Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbc0b970 authored by Yan, Zheng's avatar Yan, Zheng Committed by Sage Weil
Browse files

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: default avatarYan, Zheng <zheng.z.yan@intel.com>
parent 0ec1d15e
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -319,8 +319,7 @@ static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
static int __set_xattr(struct ceph_inode_info *ci,
			   const char *name, int name_len,
			   const char *val, int val_len,
			   int dirty,
			   int should_free_name, int should_free_val,
			   int flags, int update_xattr,
			   struct ceph_inode_xattr **newxattr)
{
	struct rb_node **p;
@@ -349,12 +348,25 @@ static int __set_xattr(struct ceph_inode_info *ci,
		xattr = NULL;
	}

	if (update_xattr) {
		int err = 0;
		if (xattr && (flags & XATTR_CREATE))
			err = -EEXIST;
		else if (!xattr && (flags & XATTR_REPLACE))
			err = -ENODATA;
		if (err) {
			kfree(name);
			kfree(val);
			return err;
		}
	}

	if (!xattr) {
		new = 1;
		xattr = *newxattr;
		xattr->name = name;
		xattr->name_len = name_len;
		xattr->should_free_name = should_free_name;
		xattr->should_free_name = update_xattr;

		ci->i_xattrs.count++;
		dout("__set_xattr count=%d\n", ci->i_xattrs.count);
@@ -364,7 +376,7 @@ static int __set_xattr(struct ceph_inode_info *ci,
		if (xattr->should_free_val)
			kfree((void *)xattr->val);

		if (should_free_name) {
		if (update_xattr) {
			kfree((void *)name);
			name = xattr->name;
		}
@@ -379,8 +391,8 @@ static int __set_xattr(struct ceph_inode_info *ci,
		xattr->val = "";

	xattr->val_len = val_len;
	xattr->dirty = dirty;
	xattr->should_free_val = (val && should_free_val);
	xattr->dirty = update_xattr;
	xattr->should_free_val = (val && update_xattr);

	if (new) {
		rb_link_node(&xattr->node, parent, p);
@@ -588,7 +600,7 @@ start:
			p += len;

			err = __set_xattr(ci, name, namelen, val, len,
					  0, 0, 0, &xattrs[numattr]);
					  0, 0, &xattrs[numattr]);

			if (err < 0)
				goto bad;
@@ -892,7 +904,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
	struct ceph_inode_info *ci = ceph_inode(inode);
	int issued;
	int err;
	int dirty;
	int dirty = 0;
	int name_len = strlen(name);
	int val_len = size;
	char *newname = NULL;
@@ -954,11 +966,13 @@ retry:
	}

	err = __set_xattr(ci, newname, name_len, newval,
			  val_len, 1, 1, 1, &xattr);
			  val_len, flags, 1, &xattr);

	if (!err) {
		dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
		ci->i_xattrs.dirty = true;
		inode->i_ctime = CURRENT_TIME;
	}

	spin_unlock(&ci->i_ceph_lock);
	if (dirty)