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. This eliminates the benefit of the old getattr cache, though the code is not removed. Since inodes are not written back in anything resembling a timely manner, using the file system from two machines is not recommended. Signed-off-by: Martin Brandenburg <martin@xxxxxxxxxxxx> --- fs/orangefs/file.c | 3 ++ fs/orangefs/inode.c | 101 ++++++++++-------------------------------- fs/orangefs/namei.c | 9 +++- fs/orangefs/orangefs-kernel.h | 2 - fs/orangefs/orangefs-utils.c | 3 ++ fs/orangefs/super.c | 23 +++++++++- fs/orangefs/symlink.c | 1 - 7 files changed, 58 insertions(+), 84 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 0de41a3..c3f44aa 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -515,6 +515,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 3ee121a..d26b9b7 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -17,7 +17,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, @@ -28,17 +27,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); @@ -64,9 +52,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; } @@ -75,38 +60,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; if (iattr->ia_valid & ATTR_SIZE) { - ret = orangefs_setattr_size(inode, iattr); - if (ret) - goto out; + /* XXX: ATTR_CTIME_SET and ATTR_MTIME_SET */ + if (i_size_read(d_inode(dentry)) != iattr->ia_size) + iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; } - - 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; + r = simple_setattr(dentry, iattr); + if (r) + return r; + if (iattr->ia_valid & ATTR_SIZE) { + r = orangefs_setattr_size(d_inode(dentry), iattr); + if (r) + return r; + } + if (iattr->ia_valid & ATTR_MODE) { + return posix_acl_chmod(d_inode(dentry), + d_inode(dentry)->i_mode); + } + return 0; } /* @@ -115,7 +87,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 ret = -ENOENT; struct inode *inode = path->dentry->d_inode; struct orangefs_inode_s *orangefs_inode = NULL; @@ -123,38 +94,13 @@ int orangefs_getattr(const struct path *path, struct kstat *stat, "orangefs_getattr: called on %pd\n", path->dentry); - ret = orangefs_inode_getattr(inode, 0, 0, request_mask); - if (ret == 0) { - generic_fillattr(inode, stat); - - /* override block size reported to stat */ - orangefs_inode = ORANGEFS_I(inode); - stat->blksize = orangefs_inode->blksize; - - if (request_mask & STATX_SIZE) - stat->result_mask = STATX_BASIC_STATS; - else - stat->result_mask = STATX_BASIC_STATS & - ~STATX_SIZE; - } - 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__); + generic_fillattr(inode, stat); - /* 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); + /* override block size reported to stat */ + orangefs_inode = ORANGEFS_I(inode); + stat->blksize = orangefs_inode->blksize; + stat->result_mask = STATX_BASIC_STATS; + return 0; } /* ORANGEDS2 implementation of VFS inode operations for files */ @@ -164,7 +110,6 @@ const struct inode_operations orangefs_file_inode_operations = { .setattr = orangefs_setattr, .getattr = orangefs_getattr, .listxattr = orangefs_listxattr, - .permission = orangefs_permission, }; static int orangefs_init_iops(struct inode *inode) diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 020a402..9ba6291 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -446,14 +446,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; } @@ -472,5 +478,4 @@ const struct inode_operations orangefs_dir_inode_operations = { .setattr = orangefs_setattr, .getattr = orangefs_getattr, .listxattr = orangefs_listxattr, - .permission = orangefs_permission, }; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 6dfb5b6..6cbbf44 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -440,8 +440,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); - /* * defined in xattr.c */ diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 1fb90bd..43bb612 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -262,6 +262,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 4d994f8..4d59f76 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -298,11 +298,32 @@ static void orangefs_dirty_inode(struct inode *inode, int flags) SetAtimeFlag(orangefs_inode); } +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, .dirty_inode = orangefs_dirty_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 = generic_show_options, diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c index 02b1bbd..97ef329 100644 --- a/fs/orangefs/symlink.c +++ b/fs/orangefs/symlink.c @@ -13,5 +13,4 @@ const struct inode_operations orangefs_symlink_inode_operations = { .setattr = orangefs_setattr, .getattr = orangefs_getattr, .listxattr = orangefs_listxattr, - .permission = orangefs_permission, }; -- 2.1.4