forked from luck/tmp_suning_uos_patched
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:
parent
66d5477d70
commit
8b60785c1d
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
* time.
|
|
||||||
*/
|
|
||||||
if ((request_mask & orangefs_inode->getattr_mask) ==
|
|
||||||
request_mask &&
|
|
||||||
time_before(jiffies, orangefs_inode->getattr_time))
|
|
||||||
return 0;
|
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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user