aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2018-04-07 21:54:39 -0400
committerIlya Dryomov <idryomov@gmail.com>2018-04-23 11:35:19 -0400
commitf1919826896c82b6af9c46f69e02f2bc04df4be7 (patch)
tree341881dd9dbe110e1b2795b8597fc3c3010f7ad8
parent6d08b06e67cd117f6992c46611dfb4ce267cd71e (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.c28
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
229static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci) 229static 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
234static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val, 242static 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 }
1113out: 1135out:
1114 ceph_free_cap_flush(prealloc_cf); 1136 ceph_free_cap_flush(prealloc_cf);