diff options
| -rw-r--r-- | fs/ceph/xattr.c | 38 |
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, | |||
| 319 | static int __set_xattr(struct ceph_inode_info *ci, | 319 | static 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) |
