aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-02-11 00:01:19 -0500
committerSage Weil <sage@inktank.com>2014-02-17 15:37:05 -0500
commitfbc0b970ddfab4b35dad27ebaae712af680bdc7e (patch)
tree2120c4d11018e7090fc76158453f11d7a0939d3f /fs/ceph
parent0ec1d15ec6ed513ab2cc86c67d94761d71228a32 (diff)
ceph: properly handle XATTR_CREATE and XATTR_REPLACE
return -EEXIST if XATTR_CREATE is set and xattr alread exists. return -ENODATA if XATTR_REPLACE is set but xattr does not exist. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/xattr.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 898b6565ad3e..28f9793b9167 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -319,8 +319,7 @@ static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
319static int __set_xattr(struct ceph_inode_info *ci, 319static int __set_xattr(struct ceph_inode_info *ci,
320 const char *name, int name_len, 320 const char *name, int name_len,
321 const char *val, int val_len, 321 const char *val, int val_len,
322 int dirty, 322 int flags, int update_xattr,
323 int should_free_name, int should_free_val,
324 struct ceph_inode_xattr **newxattr) 323 struct ceph_inode_xattr **newxattr)
325{ 324{
326 struct rb_node **p; 325 struct rb_node **p;
@@ -349,12 +348,25 @@ static int __set_xattr(struct ceph_inode_info *ci,
349 xattr = NULL; 348 xattr = NULL;
350 } 349 }
351 350
351 if (update_xattr) {
352 int err = 0;
353 if (xattr && (flags & XATTR_CREATE))
354 err = -EEXIST;
355 else if (!xattr && (flags & XATTR_REPLACE))
356 err = -ENODATA;
357 if (err) {
358 kfree(name);
359 kfree(val);
360 return err;
361 }
362 }
363
352 if (!xattr) { 364 if (!xattr) {
353 new = 1; 365 new = 1;
354 xattr = *newxattr; 366 xattr = *newxattr;
355 xattr->name = name; 367 xattr->name = name;
356 xattr->name_len = name_len; 368 xattr->name_len = name_len;
357 xattr->should_free_name = should_free_name; 369 xattr->should_free_name = update_xattr;
358 370
359 ci->i_xattrs.count++; 371 ci->i_xattrs.count++;
360 dout("__set_xattr count=%d\n", ci->i_xattrs.count); 372 dout("__set_xattr count=%d\n", ci->i_xattrs.count);
@@ -364,7 +376,7 @@ static int __set_xattr(struct ceph_inode_info *ci,
364 if (xattr->should_free_val) 376 if (xattr->should_free_val)
365 kfree((void *)xattr->val); 377 kfree((void *)xattr->val);
366 378
367 if (should_free_name) { 379 if (update_xattr) {
368 kfree((void *)name); 380 kfree((void *)name);
369 name = xattr->name; 381 name = xattr->name;
370 } 382 }
@@ -379,8 +391,8 @@ static int __set_xattr(struct ceph_inode_info *ci,
379 xattr->val = ""; 391 xattr->val = "";
380 392
381 xattr->val_len = val_len; 393 xattr->val_len = val_len;
382 xattr->dirty = dirty; 394 xattr->dirty = update_xattr;
383 xattr->should_free_val = (val && should_free_val); 395 xattr->should_free_val = (val && update_xattr);
384 396
385 if (new) { 397 if (new) {
386 rb_link_node(&xattr->node, parent, p); 398 rb_link_node(&xattr->node, parent, p);
@@ -588,7 +600,7 @@ start:
588 p += len; 600 p += len;
589 601
590 err = __set_xattr(ci, name, namelen, val, len, 602 err = __set_xattr(ci, name, namelen, val, len,
591 0, 0, 0, &xattrs[numattr]); 603 0, 0, &xattrs[numattr]);
592 604
593 if (err < 0) 605 if (err < 0)
594 goto bad; 606 goto bad;
@@ -892,7 +904,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
892 struct ceph_inode_info *ci = ceph_inode(inode); 904 struct ceph_inode_info *ci = ceph_inode(inode);
893 int issued; 905 int issued;
894 int err; 906 int err;
895 int dirty; 907 int dirty = 0;
896 int name_len = strlen(name); 908 int name_len = strlen(name);
897 int val_len = size; 909 int val_len = size;
898 char *newname = NULL; 910 char *newname = NULL;
@@ -954,11 +966,13 @@ retry:
954 } 966 }
955 967
956 err = __set_xattr(ci, newname, name_len, newval, 968 err = __set_xattr(ci, newname, name_len, newval,
957 val_len, 1, 1, 1, &xattr); 969 val_len, flags, 1, &xattr);
958 970
959 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 971 if (!err) {
960 ci->i_xattrs.dirty = true; 972 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
961 inode->i_ctime = CURRENT_TIME; 973 ci->i_xattrs.dirty = true;
974 inode->i_ctime = CURRENT_TIME;
975 }
962 976
963 spin_unlock(&ci->i_ceph_lock); 977 spin_unlock(&ci->i_ceph_lock);
964 if (dirty) 978 if (dirty)