ceph: properly handle granular statx requests
cephfs can benefit from statx. We can have the client just request caps sufficient for the needed attributes and leave off the rest. Also, recognize when AT_STATX_DONT_SYNC is set, and just scrape the inode without doing any call in that case. Force a call to the MDS in the event that AT_STATX_FORCE_SYNC is set. Link: http://tracker.ceph.com/issues/39258 Signed-off-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Reviewed-by: David Howells <dhowells@redhat.com> Reviewed-by: Sage Weil <sage@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
ffb61c55b2
commit
428bb68ad9
|
@ -2269,19 +2269,46 @@ int ceph_permission(struct inode *inode, int mask)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* Craft a mask of needed caps given a set of requested statx attrs. */
|
||||
static int statx_to_caps(u32 want)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
if (want & (STATX_MODE|STATX_UID|STATX_GID|STATX_CTIME))
|
||||
mask |= CEPH_CAP_AUTH_SHARED;
|
||||
|
||||
if (want & (STATX_NLINK|STATX_CTIME))
|
||||
mask |= CEPH_CAP_LINK_SHARED;
|
||||
|
||||
if (want & (STATX_ATIME|STATX_MTIME|STATX_CTIME|STATX_SIZE|
|
||||
STATX_BLOCKS))
|
||||
mask |= CEPH_CAP_FILE_SHARED;
|
||||
|
||||
if (want & (STATX_CTIME))
|
||||
mask |= CEPH_CAP_XATTR_SHARED;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get all attributes. Hopefully somedata we'll have a statlite()
|
||||
* and can limit the fields we require to be accurate.
|
||||
* Get all the attributes. If we have sufficient caps for the requested attrs,
|
||||
* then we can avoid talking to the MDS at all.
|
||||
*/
|
||||
int ceph_getattr(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int flags)
|
||||
{
|
||||
struct inode *inode = d_inode(path->dentry);
|
||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
/* Skip the getattr altogether if we're asked not to sync */
|
||||
if (!(flags & AT_STATX_DONT_SYNC)) {
|
||||
err = ceph_do_getattr(inode, statx_to_caps(request_mask),
|
||||
flags & AT_STATX_FORCE_SYNC);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL, false);
|
||||
if (!err) {
|
||||
generic_fillattr(inode, stat);
|
||||
stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino);
|
||||
if (ceph_snap(inode) == CEPH_NOSNAP)
|
||||
|
@ -2306,6 +2333,8 @@ int ceph_getattr(const struct path *path, struct kstat *stat,
|
|||
/* '.' + '..' + subdirs */
|
||||
stat->nlink = 1 + 1 + ci->i_subdirs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mask off any higher bits (e.g. btime) until we have support */
|
||||
stat->result_mask = request_mask & STATX_BASIC_STATS;
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue