orangefs: simplify orangefs_inode_getattr interface

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@omnibond.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
This commit is contained in:
Martin Brandenburg 2018-02-07 18:44:50 +00:00 committed by Mike Marshall
parent 66d5477d70
commit 8b60785c1d
4 changed files with 28 additions and 38 deletions

View File

@ -420,8 +420,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. */ /* Make sure generic_write_checks sees an up to date inode size. */
if (file->f_flags & O_APPEND) { if (file->f_flags & O_APPEND) {
rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1, rc = orangefs_inode_getattr(file->f_mapping->host,
STATX_SIZE); ORANGEFS_GETATTR_SIZE);
if (rc == -ESTALE) if (rc == -ESTALE)
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
@ -528,14 +528,13 @@ static vm_fault_t orangefs_fault(struct vm_fault *vmf)
{ {
struct file *file = vmf->vma->vm_file; struct file *file = vmf->vma->vm_file;
int ret; int ret;
ret = orangefs_inode_getattr(file->f_mapping->host,
ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1, ORANGEFS_GETATTR_SIZE);
STATX_SIZE);
if (ret == -ESTALE) if (ret == -ESTALE)
ret = -EIO; ret = -EIO;
if (ret) { if (ret) {
gossip_err("%s: orangefs_inode_getattr failed, ret:%d:.\n", gossip_err("%s: orangefs_inode_getattr failed, "
__func__, ret); "ret:%d:.\n", __func__, ret);
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
} }
return filemap_fault(vmf); return filemap_fault(vmf);
@ -656,8 +655,8 @@ static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin)
* NOTE: We are only interested in file size here, * NOTE: We are only interested in file size here,
* so we set mask accordingly. * so we set mask accordingly.
*/ */
ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1, ret = orangefs_inode_getattr(file->f_mapping->host,
STATX_SIZE); ORANGEFS_GETATTR_SIZE);
if (ret == -ESTALE) if (ret == -ESTALE)
ret = -EIO; ret = -EIO;
if (ret) { if (ret) {

View File

@ -162,7 +162,7 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
iattr->ia_size); iattr->ia_size);
/* Ensure that we have a up to date size, so we know if it changed. */ /* 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) if (ret == -ESTALE)
ret = -EIO; ret = -EIO;
if (ret) { if (ret) {
@ -256,7 +256,8 @@ int orangefs_getattr(const struct path *path, struct kstat *stat,
"orangefs_getattr: called on %pd\n", "orangefs_getattr: called on %pd\n",
path->dentry); 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) { if (ret == 0) {
generic_fillattr(inode, stat); generic_fillattr(inode, stat);
@ -284,7 +285,7 @@ int orangefs_permission(struct inode *inode, int mask)
gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__); gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__);
/* Make sure the permission (and other common attrs) are up to date. */ /* 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) if (ret < 0)
return ret; return ret;
@ -410,7 +411,7 @@ struct inode *orangefs_iget(struct super_block *sb,
if (!(inode->i_state & I_NEW)) if (!(inode->i_state & I_NEW))
return inode; return inode;
error = orangefs_inode_getattr(inode, 1, 1, STATX_ALL); error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW);
if (error) { if (error) {
iget_failed(inode); iget_failed(inode);
return ERR_PTR(error); return ERR_PTR(error);
@ -455,7 +456,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
orangefs_set_inode(inode, ref); orangefs_set_inode(inode, ref);
inode->i_ino = hash; /* needed for stat etc */ 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) if (error)
goto out_iput; goto out_iput;

View File

@ -193,7 +193,6 @@ struct orangefs_inode_s {
sector_t last_failed_block_index_read; sector_t last_failed_block_index_read;
unsigned long getattr_time; unsigned long getattr_time;
u32 getattr_mask;
DECLARE_HASHTABLE(xattr_cache, 4); DECLARE_HASHTABLE(xattr_cache, 4);
}; };
@ -397,8 +396,10 @@ int orangefs_inode_setxattr(struct inode *inode,
size_t size, size_t size,
int flags); int flags);
int orangefs_inode_getattr(struct inode *inode, int new, int bypass, #define ORANGEFS_GETATTR_NEW 1
u32 request_mask); #define ORANGEFS_GETATTR_SIZE 2
int orangefs_inode_getattr(struct inode *, int);
int orangefs_inode_check_changed(struct inode *inode); int orangefs_inode_check_changed(struct inode *inode);

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* /*
* (C) 2001 Clemson University and The University of Chicago * (C) 2001 Clemson University and The University of Chicago
* Copyright 2018 Omnibond Systems, L.L.C.
* *
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -272,8 +273,7 @@ static int orangefs_inode_is_stale(struct inode *inode,
return 0; return 0;
} }
int orangefs_inode_getattr(struct inode *inode, int new, int bypass, int orangefs_inode_getattr(struct inode *inode, int flags)
u32 request_mask)
{ {
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
struct orangefs_kernel_op_s *new_op; struct orangefs_kernel_op_s *new_op;
@ -283,16 +283,9 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__, gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
get_khandle_from_ino(inode)); get_khandle_from_ino(inode));
if (!new && !bypass) { /* Must have all the attributes in the mask and be within cache time. */
/* if (!flags && time_before(jiffies, orangefs_inode->getattr_time))
* Must have all the attributes in the mask and be within cache return 0;
* time.
*/
if ((request_mask & orangefs_inode->getattr_mask) ==
request_mask &&
time_before(jiffies, orangefs_inode->getattr_time))
return 0;
}
new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
if (!new_op) if (!new_op)
@ -302,7 +295,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
* Size is the hardest attribute to get. The incremental cost of any * Size is the hardest attribute to get. The incremental cost of any
* other attribute is essentially zero. * other attribute is essentially zero.
*/ */
if (request_mask & STATX_SIZE || new) if (flags)
new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT; new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
else else
new_op->upcall.req.getattr.mask = new_op->upcall.req.getattr.mask =
@ -313,7 +306,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
if (ret != 0) if (ret != 0)
goto out; goto out;
if (!new) { if (!(flags & ORANGEFS_GETATTR_NEW)) {
ret = orangefs_inode_is_stale(inode, ret = orangefs_inode_is_stale(inode,
&new_op->downcall.resp.getattr.attributes, &new_op->downcall.resp.getattr.attributes,
new_op->downcall.resp.getattr.link_target); new_op->downcall.resp.getattr.link_target);
@ -329,7 +322,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
case S_IFREG: case S_IFREG:
inode->i_flags = orangefs_inode_flags(&new_op-> inode->i_flags = orangefs_inode_flags(&new_op->
downcall.resp.getattr.attributes); downcall.resp.getattr.attributes);
if (request_mask & STATX_SIZE || new) { if (flags) {
inode_size = (loff_t)new_op-> inode_size = (loff_t)new_op->
downcall.resp.getattr.attributes.size; downcall.resp.getattr.attributes.size;
inode->i_size = inode_size; inode->i_size = inode_size;
@ -343,7 +336,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
} }
break; break;
case S_IFDIR: case S_IFDIR:
if (request_mask & STATX_SIZE || new) { if (flags) {
inode->i_size = PAGE_SIZE; inode->i_size = PAGE_SIZE;
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
inode_set_bytes(inode, inode->i_size); inode_set_bytes(inode, inode->i_size);
@ -352,7 +345,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
set_nlink(inode, 1); set_nlink(inode, 1);
break; break;
case S_IFLNK: case S_IFLNK:
if (new) { if (flags & ORANGEFS_GETATTR_NEW) {
inode->i_size = (loff_t)strlen(new_op-> inode->i_size = (loff_t)strlen(new_op->
downcall.resp.getattr.link_target); downcall.resp.getattr.link_target);
ret = strscpy(orangefs_inode->link_target, ret = strscpy(orangefs_inode->link_target,
@ -393,10 +386,6 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
orangefs_inode->getattr_time = jiffies + orangefs_inode->getattr_time = jiffies +
orangefs_getattr_timeout_msecs*HZ/1000; 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; ret = 0;
out: out:
op_release(new_op); op_release(new_op);