No need to store the received mask. It is either STATX_BASIC_STATS or STATX_BASIC_STATS & ~STATX_SIZE. If STATX_SIZE is requested, the cache is bypassed anyway, so the cached mask is unnecessary to decide whether to do a real getattr. This is a change. Previously a getattr would want size and use the cached size. All of the in-kernel callers that wanted size did not want a cached size. Now a getattr cannot use the cached size if it wants size at all. Signed-off-by: Martin Brandenburg <martin@xxxxxxxxxxxx> --- fs/orangefs/file.c | 12 ++++++------ fs/orangefs/inode.c | 11 ++++++----- fs/orangefs/orangefs-kernel.h | 7 ++++--- fs/orangefs/orangefs-utils.c | 31 ++++++++++--------------------- 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 5a66d521d9df..e1b9880e2b5f 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -418,8 +418,8 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite /* Make sure generic_write_checks sees an up to date inode size. */ if (file->f_flags & O_APPEND) { - rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1, - STATX_SIZE); + rc = orangefs_inode_getattr(file->f_mapping->host, + ORANGEFS_GETATTR_SIZE); if (rc == -ESTALE) rc = -EIO; if (rc) { @@ -526,8 +526,8 @@ static int orangefs_fault(struct vm_fault *vmf) { struct file *file = vmf->vma->vm_file; int rc; - rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1, - STATX_SIZE); + rc = orangefs_inode_getattr(file->f_mapping->host, + ORANGEFS_GETATTR_SIZE); if (rc == -ESTALE) rc = -EIO; if (rc) { @@ -652,8 +652,8 @@ static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin) * NOTE: We are only interested in file size here, * so we set mask accordingly. */ - ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1, - STATX_SIZE); + ret = orangefs_inode_getattr(file->f_mapping->host, + ORANGEFS_GETATTR_SIZE); if (ret == -ESTALE) ret = -EIO; if (ret) { diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 109bdd101e04..6222f029f93a 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -161,7 +161,7 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) 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); + ret = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_SIZE); if (ret == -ESTALE) ret = -EIO; if (ret) { @@ -255,7 +255,8 @@ 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); + ret = orangefs_inode_getattr(inode, + request_mask & STATX_SIZE ? ORANGEFS_GETATTR_SIZE : 0); if (ret == 0) { generic_fillattr(inode, stat); @@ -282,7 +283,7 @@ int orangefs_permission(struct inode *inode, int mask) 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); + ret = orangefs_inode_getattr(inode, 0); if (ret < 0) return ret; @@ -398,7 +399,7 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref if (!inode || !(inode->i_state & I_NEW)) return inode; - error = orangefs_inode_getattr(inode, 1, 1, STATX_ALL); + error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW); if (error) { iget_failed(inode); return ERR_PTR(error); @@ -443,7 +444,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, orangefs_set_inode(inode, ref); inode->i_ino = hash; /* needed for stat etc */ - error = orangefs_inode_getattr(inode, 1, 1, STATX_ALL); + error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW); if (error) goto out_iput; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 7e2ad1590d1e..03a2a042132f 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -194,7 +194,6 @@ struct orangefs_inode_s { sector_t last_failed_block_index_read; unsigned long getattr_time; - u32 getattr_mask; DECLARE_HASHTABLE(xattr_cache, 4); }; @@ -398,8 +397,10 @@ int orangefs_inode_setxattr(struct inode *inode, size_t size, int flags); -int orangefs_inode_getattr(struct inode *inode, int new, int bypass, - u32 request_mask); +#define ORANGEFS_GETATTR_NEW 1 +#define ORANGEFS_GETATTR_SIZE 2 + +int orangefs_inode_getattr(struct inode *, int); int orangefs_inode_check_changed(struct inode *inode); diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index f8cbbdd7dd7f..ab1be285f89d 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * (C) 2001 Clemson University and The University of Chicago + * Copyright 2018 Omnibond Systems, L.L.C. * * See COPYING in top-level directory. */ @@ -268,8 +269,7 @@ static int orangefs_inode_is_stale(struct inode *inode, return 0; } -int orangefs_inode_getattr(struct inode *inode, int new, int bypass, - u32 request_mask) +int orangefs_inode_getattr(struct inode *inode, int flags) { struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); struct orangefs_kernel_op_s *new_op; @@ -279,16 +279,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 (!new && !bypass) { - /* - * Must have all the attributes in the mask and be within cache - * time. - */ - if ((request_mask & orangefs_inode->getattr_mask) == - request_mask && - time_before(jiffies, orangefs_inode->getattr_time)) - return 0; - } + /* Must have all the attributes in the mask and be within cache time. */ + if (!flags && time_before(jiffies, orangefs_inode->getattr_time)) + return 0; new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); if (!new_op) @@ -298,7 +291,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass, * Size is the hardest attribute to get. The incremental cost of any * other attribute is essentially zero. */ - if (request_mask & STATX_SIZE || new) + if (flags) new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT; else new_op->upcall.req.getattr.mask = @@ -308,7 +301,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass, if (ret != 0) goto out; - if (!new) { + if (!(flags & ORANGEFS_GETATTR_NEW)) { ret = orangefs_inode_is_stale(inode, &new_op->downcall.resp.getattr.attributes, new_op->downcall.resp.getattr.link_target); @@ -324,7 +317,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass, case S_IFREG: inode->i_flags = orangefs_inode_flags(&new_op-> downcall.resp.getattr.attributes); - if (request_mask & STATX_SIZE || new) { + if (flags) { inode_size = (loff_t)new_op-> downcall.resp.getattr.attributes.size; rounded_up_size = @@ -340,7 +333,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass, } break; case S_IFDIR: - if (request_mask & STATX_SIZE || new) { + if (flags) { inode->i_size = PAGE_SIZE; orangefs_inode->blksize = i_blocksize(inode); spin_lock(&inode->i_lock); @@ -350,7 +343,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass, set_nlink(inode, 1); break; case S_IFLNK: - if (new) { + if (flags & ORANGEFS_GETATTR_NEW) { inode->i_size = (loff_t)strlen(new_op-> downcall.resp.getattr.link_target); orangefs_inode->blksize = i_blocksize(inode); @@ -392,10 +385,6 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass, orangefs_inode->getattr_time = jiffies + orangefs_getattr_timeout_msecs*HZ/1000; - if (request_mask & STATX_SIZE || new) - orangefs_inode->getattr_mask = STATX_BASIC_STATS; - else - orangefs_inode->getattr_mask = STATX_BASIC_STATS & ~STATX_SIZE; ret = 0; out: op_release(new_op); -- 2.16.2