All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Brandenburg <martin@omnibond.com>
To: hubcap@omnibond.com, devel@lists.orangefs.org,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Martin Brandenburg <martin@omnibond.com>
Subject: [PATCH 13/18] orangefs: inodes linger in cache
Date: Tue, 12 Dec 2017 13:34:19 -0500	[thread overview]
Message-ID: <20171212183424.26406-14-martin@martinbrandenburg.com> (raw)
In-Reply-To: <20171212183424.26406-1-martin@martinbrandenburg.com>

From: Martin Brandenburg <martin@omnibond.com>

This is a big change, but it boils down to implementing write_inode,
changing generic_delete_inode to generic_drop_inode, and changing
set/getattr to set/get from the in-memory inode.

The OrangeFS client requires a real getattr prior to any directory
operations.

Signed-off-by: Martin Brandenburg <martin@omnibond.com>
---
 fs/orangefs/file.c            |  3 ++
 fs/orangefs/inode.c           | 84 ++++++++++---------------------------------
 fs/orangefs/namei.c           | 48 +++++++++++++++++++++++--
 fs/orangefs/orangefs-kernel.h |  2 --
 fs/orangefs/orangefs-utils.c  |  3 ++
 fs/orangefs/super.c           | 22 +++++++++++-
 fs/orangefs/symlink.c         |  1 -
 7 files changed, 92 insertions(+), 71 deletions(-)

diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c
index 8dfa0e8c7326..1c30e9abb8cb 100644
--- a/fs/orangefs/file.c
+++ b/fs/orangefs/file.c
@@ -464,6 +464,9 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite
 	iocb->ki_pos = pos;
 	orangefs_stats.writes++;
 
+	if (pos > i_size_read(file->f_mapping->host))
+		orangefs_i_size_write(file->f_mapping->host, pos);
+
 out:
 
 	inode_unlock(file->f_mapping->host);
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index f3a157571a6a..2c4f57c5d830 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -18,7 +18,6 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
 {
 	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
 	struct orangefs_kernel_op_s *new_op;
-	loff_t orig_size;
 	int ret = -EINVAL;
 
 	gossip_debug(GOSSIP_INODE_DEBUG,
@@ -29,17 +28,6 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
 		     orangefs_inode->refn.fs_id,
 		     iattr->ia_size);
 
-	/* Ensure that we have a up to date size, so we know if it changed. */
-	ret = orangefs_inode_getattr(inode, 0, 1, STATX_SIZE);
-	if (ret == -ESTALE)
-		ret = -EIO;
-	if (ret) {
-		gossip_err("%s: orangefs_inode_getattr failed, ret:%d:.\n",
-		    __func__, ret);
-		return ret;
-	}
-	orig_size = i_size_read(inode);
-
 	truncate_setsize(inode, iattr->ia_size);
 
 	new_op = op_alloc(ORANGEFS_VFS_OP_TRUNCATE);
@@ -65,9 +53,6 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
 	if (ret != 0)
 		return ret;
 
-	if (orig_size != i_size_read(inode))
-		iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
-
 	return ret;
 }
 
@@ -76,38 +61,25 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
  */
 int orangefs_setattr(struct dentry *dentry, struct iattr *iattr)
 {
-	int ret = -EINVAL;
-	struct inode *inode = dentry->d_inode;
-
-	gossip_debug(GOSSIP_INODE_DEBUG,
-		     "orangefs_setattr: called on %pd\n",
-		     dentry);
-
-	ret = setattr_prepare(dentry, iattr);
-	if (ret)
-		goto out;
-
+	int r;
+	r = setattr_prepare(dentry, iattr);
+	if (r)
+		return r;
+	if (iattr->ia_valid & ATTR_SIZE)
+		if (i_size_read(d_inode(dentry)) != iattr->ia_size)
+			iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
+	setattr_copy(d_inode(dentry), iattr);
+	mark_inode_dirty(d_inode(dentry));
 	if (iattr->ia_valid & ATTR_SIZE) {
-		ret = orangefs_setattr_size(inode, iattr);
-		if (ret)
-			goto out;
+		r = orangefs_setattr_size(d_inode(dentry), iattr);
+		if (r)
+			return r;
 	}
-
-	setattr_copy(inode, iattr);
-	mark_inode_dirty(inode);
-
-	ret = orangefs_inode_setattr(inode, iattr);
-	gossip_debug(GOSSIP_INODE_DEBUG,
-		     "orangefs_setattr: inode_setattr returned %d\n",
-		     ret);
-
-	if (!ret && (iattr->ia_valid & ATTR_MODE))
-		/* change mod on a file that has ACLs */
-		ret = posix_acl_chmod(inode, inode->i_mode);
-
-out:
-	gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n", ret);
-	return ret;
+	if (iattr->ia_valid & ATTR_MODE) {
+		return posix_acl_chmod(d_inode(dentry),
+		    d_inode(dentry)->i_mode);
+	}
+	return 0;
 }
 
 /*
@@ -116,14 +88,14 @@ int orangefs_setattr(struct dentry *dentry, struct iattr *iattr)
 int orangefs_getattr(const struct path *path, struct kstat *stat,
 		     u32 request_mask, unsigned int flags)
 {
-	int ret = -ENOENT;
 	struct inode *inode = path->dentry->d_inode;
 	struct orangefs_inode_s *orangefs_inode = NULL;
+	int ret;
 
 	gossip_debug(GOSSIP_INODE_DEBUG,
 		     "orangefs_getattr: called on %pd\n",
 		     path->dentry);
-
+ 
 	ret = orangefs_inode_getattr(inode, 0, 0, request_mask);
 	if (ret == 0) {
 		generic_fillattr(inode, stat);
@@ -141,23 +113,6 @@ int orangefs_getattr(const struct path *path, struct kstat *stat,
 	return ret;
 }
 
-int orangefs_permission(struct inode *inode, int mask)
-{
-	int ret;
-
-	if (mask & MAY_NOT_BLOCK)
-		return -ECHILD;
-
-	gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__);
-
-	/* Make sure the permission (and other common attrs) are up to date. */
-	ret = orangefs_inode_getattr(inode, 0, 0, STATX_MODE);
-	if (ret < 0)
-		return ret;
-
-	return generic_permission(inode, mask);
-}
-
 int orangefs_update_time(struct inode *inode, struct timespec *time, int flags)
 {
 	struct iattr iattr;
@@ -181,7 +136,6 @@ const struct inode_operations orangefs_file_inode_operations = {
 	.setattr = orangefs_setattr,
 	.getattr = orangefs_getattr,
 	.listxattr = orangefs_listxattr,
-	.permission = orangefs_permission,
 	.update_time = orangefs_update_time,
 };
 
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c
index d3a62e52c724..37d7d8214e3e 100644
--- a/fs/orangefs/namei.c
+++ b/fs/orangefs/namei.c
@@ -31,6 +31,13 @@ static int orangefs_create(struct inode *dir,
 		     __func__,
 		     dentry);
 
+	/* Need directory updates to be on server prior to issuing op. */
+	write_inode_now(dir, 1);
+	/* Need OrangeFS client to update capability. */
+	ret = orangefs_inode_getattr(dir, 1, 1, STATX_ALL);
+	if (ret)
+		goto out;
+
 	new_op = op_alloc(ORANGEFS_VFS_OP_CREATE);
 	if (!new_op)
 		return -ENOMEM;
@@ -236,6 +243,13 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
 		     &parent->refn.khandle,
 		     parent->refn.fs_id);
 
+	/* Need directory updates to be on server prior to issuing op. */
+	write_inode_now(dir, 1);
+	/* Need OrangeFS client to update capability. */
+	ret = orangefs_inode_getattr(dir, 1, 1, STATX_ALL);
+	if (ret)
+		return ret;
+
 	new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE);
 	if (!new_op)
 		return -ENOMEM;
@@ -286,6 +300,13 @@ static int orangefs_symlink(struct inode *dir,
 	if (strlen(symname)+1 > ORANGEFS_NAME_MAX)
 		return -ENAMETOOLONG;
 
+	/* Need directory updates to be on server prior to issuing op. */
+	write_inode_now(dir, 1);
+	/* Need OrangeFS client to update capability. */
+	ret = orangefs_inode_getattr(dir, 1, 1, STATX_ALL);
+	if (ret)
+		goto out;
+
 	new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK);
 	if (!new_op)
 		return -ENOMEM;
@@ -360,6 +381,13 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
 	struct iattr iattr;
 	int ret;
 
+	/* Need directory updates to be on server prior to issuing op. */
+	write_inode_now(dir, 1);
+	/* Need OrangeFS client to update capability. */
+	ret = orangefs_inode_getattr(dir, 1, 1, STATX_ALL);
+	if (ret)
+		goto out;
+
 	new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
 	if (!new_op)
 		return -ENOMEM;
@@ -442,6 +470,17 @@ static int orangefs_rename(struct inode *old_dir,
 
 	ORANGEFS_I(new_dentry->d_parent->d_inode)->getattr_time = jiffies - 1;
 
+	/* Need directory updates to be on server prior to issuing op. */
+	write_inode_now(old_dir, 1);
+	write_inode_now(new_dir, 1);
+	/* Need OrangeFS client to update capability. */
+	ret = orangefs_inode_getattr(old_dir, 1, 1, STATX_ALL);
+	if (ret)
+		return ret;
+	ret = orangefs_inode_getattr(new_dir, 1, 1, STATX_ALL);
+	if (ret)
+		return ret;
+
 	new_op = op_alloc(ORANGEFS_VFS_OP_RENAME);
 	if (!new_op)
 		return -EINVAL;
@@ -459,14 +498,20 @@ static int orangefs_rename(struct inode *old_dir,
 	ret = service_operation(new_op,
 				"orangefs_rename",
 				get_interruptible_flag(old_dentry->d_inode));
-
 	gossip_debug(GOSSIP_NAME_DEBUG,
 		     "orangefs_rename: got downcall status %d\n",
 		     ret);
 
+	if (ret < 0)
+		goto out;
+
 	if (new_dentry->d_inode)
 		new_dentry->d_inode->i_ctime = current_time(new_dentry->d_inode);
 
+	new_dir->i_mtime = current_time(new_dir);
+	new_dir->i_ctime = current_time(new_dir);
+
+out:
 	op_release(new_op);
 	return ret;
 }
@@ -485,6 +530,5 @@ const struct inode_operations orangefs_dir_inode_operations = {
 	.setattr = orangefs_setattr,
 	.getattr = orangefs_getattr,
 	.listxattr = orangefs_listxattr,
-	.permission = orangefs_permission,
 	.update_time = orangefs_update_time,
 };
diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h
index ba62de332e04..9c0b575a16e8 100644
--- a/fs/orangefs/orangefs-kernel.h
+++ b/fs/orangefs/orangefs-kernel.h
@@ -407,8 +407,6 @@ int orangefs_setattr(struct dentry *dentry, struct iattr *iattr);
 int orangefs_getattr(const struct path *path, struct kstat *stat,
 		     u32 request_mask, unsigned int flags);
 
-int orangefs_permission(struct inode *inode, int mask);
-
 int orangefs_update_time(struct inode *, struct timespec *, int);
 
 /*
diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c
index 2c5b7a3d7793..0953ada47cac 100644
--- a/fs/orangefs/orangefs-utils.c
+++ b/fs/orangefs/orangefs-utils.c
@@ -264,6 +264,9 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
 	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
 	    get_khandle_from_ino(inode));
 
+	if (inode->i_state & I_DIRTY)
+		return 0;
+
 	if (!new && !bypass) {
 		/*
 		 * Must have all the attributes in the mask and be within cache
diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c
index 314c4a816983..5c17709862ab 100644
--- a/fs/orangefs/super.c
+++ b/fs/orangefs/super.c
@@ -296,10 +296,30 @@ void fsid_key_table_finalize(void)
 {
 }
 
+static int orangefs_write_inode(struct inode *inode,
+    struct writeback_control *wbc)
+{
+	struct iattr iattr;
+	int r;
+	iattr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_ATIME |
+	    ATTR_ATIME_SET | ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME;
+	iattr.ia_mode = inode->i_mode;
+	iattr.ia_uid = inode->i_uid;
+	iattr.ia_gid = inode->i_gid;
+	iattr.ia_atime = inode->i_atime;
+	iattr.ia_mtime = inode->i_mtime;
+	iattr.ia_ctime = inode->i_ctime;
+	r = orangefs_inode_setattr(inode, &iattr);
+	if (r)
+		return r;
+	return r;
+}
+
 static const struct super_operations orangefs_s_ops = {
 	.alloc_inode = orangefs_alloc_inode,
 	.destroy_inode = orangefs_destroy_inode,
-	.drop_inode = generic_delete_inode,
+	.write_inode = orangefs_write_inode,
+	.drop_inode = generic_drop_inode,
 	.statfs = orangefs_statfs,
 	.remount_fs = orangefs_remount_fs,
 	.show_options = orangefs_show_options,
diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c
index db107fe91ab3..c08f81af1090 100644
--- a/fs/orangefs/symlink.c
+++ b/fs/orangefs/symlink.c
@@ -14,6 +14,5 @@ const struct inode_operations orangefs_symlink_inode_operations = {
 	.setattr = orangefs_setattr,
 	.getattr = orangefs_getattr,
 	.listxattr = orangefs_listxattr,
-	.permission = orangefs_permission,
 	.update_time = orangefs_update_time,
 };
-- 
2.15.1

  parent reply	other threads:[~2017-12-12 18:35 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-12 18:34 [PATCH 00/18] orangefs: page cache Martin Brandenburg
2017-12-12 18:34 ` [PATCH 01/18] orangefs: open code short single-use functions Martin Brandenburg
2017-12-12 18:34 ` [PATCH 02/18] orangefs: implement vm_ops->fault Martin Brandenburg
2017-12-12 18:34 ` [PATCH 03/18] orangefs: do not invalidate attributes on inode create Martin Brandenburg
2017-12-12 18:34 ` [PATCH 04/18] orangefs: do not invalidate attribute cache on setattr Martin Brandenburg
2017-12-12 18:34 ` [PATCH 05/18] orangefs: reverse sense of revalidate is-inode-stale test Martin Brandenburg
2017-12-12 18:34 ` [PATCH 06/18] orangefs: move orangefs_address_operations to file.c Martin Brandenburg
2017-12-12 18:34 ` [PATCH 07/18] orangefs: remove orangefs_readpages Martin Brandenburg
2017-12-12 18:34 ` [PATCH 08/18] orangefs: make orangefs_inode_read static Martin Brandenburg
2017-12-12 18:34 ` [PATCH 09/18] orangefs: only set a_ops for regular files Martin Brandenburg
2017-12-12 18:34 ` [PATCH 10/18] orangefs: BUG_ON if i_mode invalid Martin Brandenburg
2017-12-12 18:34 ` [PATCH 11/18] orangefs: remove mapping_nrpages macro Martin Brandenburg
2017-12-12 18:34 ` [PATCH 12/18] orangefs: set up and use backing_dev_info Martin Brandenburg
2017-12-12 18:34 ` Martin Brandenburg [this message]
2017-12-12 18:34 ` [PATCH 14/18] orangefs: implement direct_IO for the read case Martin Brandenburg
2017-12-12 18:34 ` [PATCH 15/18] orangefs: call generic_file_read_iter Martin Brandenburg
2017-12-12 18:34 ` [PATCH 16/18] orangefs: implement write through the page cache Martin Brandenburg
2017-12-12 18:34 ` [PATCH 17/18] orangefs: no more explicit setattr Martin Brandenburg
2017-12-12 18:34 ` [PATCH 18/18] orangefs: implement xattr cache Martin Brandenburg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171212183424.26406-14-martin@martinbrandenburg.com \
    --to=martin@omnibond.com \
    --cc=devel@lists.orangefs.org \
    --cc=hubcap@omnibond.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.