diff options
author | Martin Brandenburg <martin@omnibond.com> | 2018-02-13 20:13:46 +0000 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2019-05-03 14:32:38 -0400 |
commit | afd9fb2a31797b4c787034294a4062df0c19c37e (patch) | |
tree | 08bc9f1eaab32d5561519af8f9b1ba2d5ee846ac /fs/orangefs/namei.c | |
parent | df2d7337b570c34e051a2412f716743277ccf9c8 (diff) | |
download | lwn-afd9fb2a31797b4c787034294a4062df0c19c37e.tar.gz lwn-afd9fb2a31797b4c787034294a4062df0c19c37e.zip |
orangefs: reorganize setattr functions to track attribute changes
OrangeFS accepts a mask indicating which attributes were changed. The
kernel must not set any bits except those that were actually changed.
The kernel must set the uid/gid of the request to the actual uid/gid
responsible for the change.
Code path for notify_change initiated setattrs is
orangefs_setattr(dentry, iattr)
-> __orangefs_setattr(inode, iattr)
In kernel changes are initiated by calling __orangefs_setattr.
Code path for writeback is
orangefs_write_inode
-> orangefs_inode_setattr
attr_valid and attr_uid and attr_gid change together under i_lock.
I_DIRTY changes separately.
__orangefs_setattr
lock
if needs to be cleaned first, unlock and retry
set attr_valid
copy data in
unlock
mark_inode_dirty
orangefs_inode_setattr
lock
copy attributes out
unlock
clear getattr_time
# __writeback_single_inode clears dirty
orangefs_inode_getattr
# possible to get here with attr_valid set and not dirty
lock
if getattr_time ok or attr_valid set, unlock and return
unlock
do server operation
# another thread may getattr or setattr, so check for that
lock
if getattr_time ok or attr_valid, unlock and return
else, copy in
update getattr_time
unlock
Signed-off-by: Martin Brandenburg <martin@omnibond.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs/orangefs/namei.c')
-rw-r--r-- | fs/orangefs/namei.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 140314b76e10..1dd710e5f376 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -82,11 +82,10 @@ static int orangefs_create(struct inode *dir, __func__, dentry); - dir->i_mtime = dir->i_ctime = current_time(dir); memset(&iattr, 0, sizeof iattr); - iattr.ia_valid |= ATTR_MTIME; - orangefs_inode_setattr(dir, &iattr); - mark_inode_dirty_sync(dir); + iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME; + iattr.ia_mtime = iattr.ia_ctime = current_time(dir); + __orangefs_setattr(dir, &iattr); ret = 0; out: op_release(new_op); @@ -208,11 +207,10 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry) if (!ret) { drop_nlink(inode); - dir->i_mtime = dir->i_ctime = current_time(dir); memset(&iattr, 0, sizeof iattr); - iattr.ia_valid |= ATTR_MTIME; - orangefs_inode_setattr(dir, &iattr); - mark_inode_dirty_sync(dir); + iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME; + iattr.ia_mtime = iattr.ia_ctime = current_time(dir); + __orangefs_setattr(dir, &iattr); } return ret; } @@ -295,11 +293,10 @@ static int orangefs_symlink(struct inode *dir, get_khandle_from_ino(inode), dentry); - dir->i_mtime = dir->i_ctime = current_time(dir); memset(&iattr, 0, sizeof iattr); - iattr.ia_valid |= ATTR_MTIME; - orangefs_inode_setattr(dir, &iattr); - mark_inode_dirty_sync(dir); + iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME; + iattr.ia_mtime = iattr.ia_ctime = current_time(dir); + __orangefs_setattr(dir, &iattr); ret = 0; out: op_release(new_op); @@ -366,11 +363,10 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode * NOTE: we have no good way to keep nlink consistent for directories * across clients; keep constant at 1. */ - dir->i_mtime = dir->i_ctime = current_time(dir); memset(&iattr, 0, sizeof iattr); - iattr.ia_valid |= ATTR_MTIME; - orangefs_inode_setattr(dir, &iattr); - mark_inode_dirty_sync(dir); + iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME; + iattr.ia_mtime = iattr.ia_ctime = current_time(dir); + __orangefs_setattr(dir, &iattr); out: op_release(new_op); return ret; @@ -393,11 +389,10 @@ static int orangefs_rename(struct inode *old_dir, "orangefs_rename: called (%pd2 => %pd2) ct=%d\n", old_dentry, new_dentry, d_count(new_dentry)); - new_dir->i_mtime = new_dir->i_ctime = current_time(new_dir); memset(&iattr, 0, sizeof iattr); - iattr.ia_valid |= ATTR_MTIME; - orangefs_inode_setattr(new_dir, &iattr); - mark_inode_dirty_sync(new_dir); + iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME; + iattr.ia_mtime = iattr.ia_ctime = current_time(new_dir); + __orangefs_setattr(new_dir, &iattr); new_op = op_alloc(ORANGEFS_VFS_OP_RENAME); if (!new_op) |