diff options
author | Yan, Zheng <zyan@redhat.com> | 2018-04-07 21:54:39 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-04-23 11:35:19 -0400 |
commit | f1919826896c82b6af9c46f69e02f2bc04df4be7 (patch) | |
tree | 341881dd9dbe110e1b2795b8597fc3c3010f7ad8 | |
parent | 6d08b06e67cd117f6992c46611dfb4ce267cd71e (diff) |
ceph: check if mds create snaprealm when setting quota
If mds does not, return -EOPNOTSUPP.
Link: http://tracker.ceph.com/issues/23491
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r-- | fs/ceph/xattr.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 7e72348639e4..315f7e63e7cc 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -228,7 +228,15 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, | |||
228 | 228 | ||
229 | static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci) | 229 | static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci) |
230 | { | 230 | { |
231 | return (ci->i_max_files || ci->i_max_bytes); | 231 | bool ret = false; |
232 | spin_lock(&ci->i_ceph_lock); | ||
233 | if ((ci->i_max_files || ci->i_max_bytes) && | ||
234 | ci->i_vino.snap == CEPH_NOSNAP && | ||
235 | ci->i_snap_realm && | ||
236 | ci->i_snap_realm->ino == ci->i_vino.ino) | ||
237 | ret = true; | ||
238 | spin_unlock(&ci->i_ceph_lock); | ||
239 | return ret; | ||
232 | } | 240 | } |
233 | 241 | ||
234 | static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val, | 242 | static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val, |
@@ -1008,14 +1016,19 @@ int __ceph_setxattr(struct inode *inode, const char *name, | |||
1008 | char *newval = NULL; | 1016 | char *newval = NULL; |
1009 | struct ceph_inode_xattr *xattr = NULL; | 1017 | struct ceph_inode_xattr *xattr = NULL; |
1010 | int required_blob_size; | 1018 | int required_blob_size; |
1019 | bool check_realm = false; | ||
1011 | bool lock_snap_rwsem = false; | 1020 | bool lock_snap_rwsem = false; |
1012 | 1021 | ||
1013 | if (ceph_snap(inode) != CEPH_NOSNAP) | 1022 | if (ceph_snap(inode) != CEPH_NOSNAP) |
1014 | return -EROFS; | 1023 | return -EROFS; |
1015 | 1024 | ||
1016 | vxattr = ceph_match_vxattr(inode, name); | 1025 | vxattr = ceph_match_vxattr(inode, name); |
1017 | if (vxattr && vxattr->readonly) | 1026 | if (vxattr) { |
1018 | return -EOPNOTSUPP; | 1027 | if (vxattr->readonly) |
1028 | return -EOPNOTSUPP; | ||
1029 | if (value && !strncmp(vxattr->name, "ceph.quota", 10)) | ||
1030 | check_realm = true; | ||
1031 | } | ||
1019 | 1032 | ||
1020 | /* pass any unhandled ceph.* xattrs through to the MDS */ | 1033 | /* pass any unhandled ceph.* xattrs through to the MDS */ |
1021 | if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) | 1034 | if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) |
@@ -1109,6 +1122,15 @@ do_sync_unlocked: | |||
1109 | err = -EBUSY; | 1122 | err = -EBUSY; |
1110 | } else { | 1123 | } else { |
1111 | err = ceph_sync_setxattr(inode, name, value, size, flags); | 1124 | err = ceph_sync_setxattr(inode, name, value, size, flags); |
1125 | if (err >= 0 && check_realm) { | ||
1126 | /* check if snaprealm was created for quota inode */ | ||
1127 | spin_lock(&ci->i_ceph_lock); | ||
1128 | if ((ci->i_max_files || ci->i_max_bytes) && | ||
1129 | !(ci->i_snap_realm && | ||
1130 | ci->i_snap_realm->ino == ci->i_vino.ino)) | ||
1131 | err = -EOPNOTSUPP; | ||
1132 | spin_unlock(&ci->i_ceph_lock); | ||
1133 | } | ||
1112 | } | 1134 | } |
1113 | out: | 1135 | out: |
1114 | ceph_free_cap_flush(prealloc_cf); | 1136 | ceph_free_cap_flush(prealloc_cf); |