diff options
author | Luis Henriques <lhenriques@suse.com> | 2019-03-21 11:20:10 +0100 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-05-07 19:22:36 +0200 |
commit | 0c44a8e0fc55f56a70f72e67d7cc5b9341dae7d1 (patch) | |
tree | 22ff1d529ddff80eb05f19809f37ceda342b900c /fs/ceph/mds_client.h | |
parent | ceph: factor out ceph_lookup_inode() (diff) | |
download | linux-0c44a8e0fc55f56a70f72e67d7cc5b9341dae7d1.tar.xz linux-0c44a8e0fc55f56a70f72e67d7cc5b9341dae7d1.zip |
ceph: quota: fix quota subdir mounts
The CephFS kernel client does not enforce quotas set in a directory that
isn't visible from the mount point. For example, given the path
'/dir1/dir2', if quotas are set in 'dir1' and the filesystem is mounted with
mount -t ceph <server>:<port>:/dir1/ /mnt
then the client won't be able to access 'dir1' inode, even if 'dir2' belongs
to a quota realm that points to it.
This patch fixes this issue by simply doing an MDS LOOKUPINO operation for
unknown inodes. Any inode reference obtained this way will be added to a
list in ceph_mds_client, and will only be released when the filesystem is
umounted.
Link: https://tracker.ceph.com/issues/38482
Reported-by: Hendrik Peyerl <hpeyerl@plusline.net>
Signed-off-by: Luis Henriques <lhenriques@suse.com>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/mds_client.h')
-rw-r--r-- | fs/ceph/mds_client.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 50385a481fdb..3f0029aa8a39 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -326,6 +326,18 @@ struct ceph_snapid_map { }; /* + * node for list of quotarealm inodes that are not visible from the filesystem + * mountpoint, but required to handle, e.g. quotas. + */ +struct ceph_quotarealm_inode { + struct rb_node node; + u64 ino; + unsigned long timeout; /* last time a lookup failed for this inode */ + struct mutex mutex; + struct inode *inode; +}; + +/* * mds client state */ struct ceph_mds_client { @@ -344,6 +356,12 @@ struct ceph_mds_client { int stopping; /* true if shutting down */ atomic64_t quotarealms_count; /* # realms with quota */ + /* + * We keep a list of inodes we don't see in the mountpoint but that we + * need to track quota realms. + */ + struct rb_root quotarealms_inodes; + struct mutex quotarealms_inodes_mutex; /* * snap_rwsem will cover cap linkage into snaprealms, and |