orangefs: implement statx
Fortunately OrangeFS has had a getattr request mask for a long time. The server basically has two difficulty levels for attributes. Fetching any attribute except size requires communicating with the metadata server for that handle. Since all the attributes are right there, it makes sense to return them all. Fetching the size requires communicating with every I/O server (that the file is distributed across). Therefore if asked for anything except size, get everything except size, and if asked for size, get everything. Signed-off-by: Martin Brandenburg <martin@omnibond.com> Signed-off-by: Mike Marshall <hubcap@omnibond.com>
This commit is contained in:

committed by
Mike Marshall

parent
7b796ae370
commit
68a24a6cc4
@@ -251,7 +251,8 @@ static int orangefs_inode_is_stale(struct inode *inode, int new,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int orangefs_inode_getattr(struct inode *inode, int new, int bypass)
|
||||
int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
|
||||
u32 request_mask)
|
||||
{
|
||||
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
|
||||
struct orangefs_kernel_op_s *new_op;
|
||||
@@ -262,7 +263,13 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass)
|
||||
get_khandle_from_ino(inode));
|
||||
|
||||
if (!new && !bypass) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
@@ -270,7 +277,15 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass)
|
||||
if (!new_op)
|
||||
return -ENOMEM;
|
||||
new_op->upcall.req.getattr.refn = orangefs_inode->refn;
|
||||
new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
|
||||
/*
|
||||
* Size is the hardest attribute to get. The incremental cost of any
|
||||
* other attribute is essentially zero.
|
||||
*/
|
||||
if (request_mask & STATX_SIZE || new)
|
||||
new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
|
||||
else
|
||||
new_op->upcall.req.getattr.mask =
|
||||
ORANGEFS_ATTR_SYS_ALL_NOHINT & ~ORANGEFS_ATTR_SYS_SIZE;
|
||||
|
||||
ret = service_operation(new_op, __func__,
|
||||
get_interruptible_flag(inode));
|
||||
@@ -291,25 +306,29 @@ 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);
|
||||
inode_size = (loff_t)new_op->
|
||||
downcall.resp.getattr.attributes.size;
|
||||
rounded_up_size =
|
||||
(inode_size + (4096 - (inode_size % 4096)));
|
||||
inode->i_size = inode_size;
|
||||
orangefs_inode->blksize =
|
||||
new_op->downcall.resp.getattr.attributes.blksize;
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_bytes = inode_size;
|
||||
inode->i_blocks =
|
||||
(unsigned long)(rounded_up_size / 512);
|
||||
spin_unlock(&inode->i_lock);
|
||||
if (request_mask & STATX_SIZE || new) {
|
||||
inode_size = (loff_t)new_op->
|
||||
downcall.resp.getattr.attributes.size;
|
||||
rounded_up_size =
|
||||
(inode_size + (4096 - (inode_size % 4096)));
|
||||
inode->i_size = inode_size;
|
||||
orangefs_inode->blksize =
|
||||
new_op->downcall.resp.getattr.attributes.blksize;
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_bytes = inode_size;
|
||||
inode->i_blocks =
|
||||
(unsigned long)(rounded_up_size / 512);
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
break;
|
||||
case S_IFDIR:
|
||||
inode->i_size = PAGE_SIZE;
|
||||
orangefs_inode->blksize = i_blocksize(inode);
|
||||
spin_lock(&inode->i_lock);
|
||||
inode_set_bytes(inode, inode->i_size);
|
||||
spin_unlock(&inode->i_lock);
|
||||
if (request_mask & STATX_SIZE || new) {
|
||||
inode->i_size = PAGE_SIZE;
|
||||
orangefs_inode->blksize = i_blocksize(inode);
|
||||
spin_lock(&inode->i_lock);
|
||||
inode_set_bytes(inode, inode->i_size);
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
set_nlink(inode, 1);
|
||||
break;
|
||||
case S_IFLNK:
|
||||
@@ -349,6 +368,10 @@ 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);
|
||||
|
Reference in New Issue
Block a user