|
@@ -912,6 +912,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
|
|
struct ceph_vxattr *vxattr;
|
|
struct ceph_vxattr *vxattr;
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
|
|
struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
|
|
|
|
+ struct ceph_cap_flush *prealloc_cf = NULL;
|
|
int issued;
|
|
int issued;
|
|
int err;
|
|
int err;
|
|
int dirty = 0;
|
|
int dirty = 0;
|
|
@@ -950,6 +951,10 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
|
|
if (!xattr)
|
|
if (!xattr)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
+ prealloc_cf = ceph_alloc_cap_flush();
|
|
|
|
+ if (!prealloc_cf)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
spin_lock(&ci->i_ceph_lock);
|
|
spin_lock(&ci->i_ceph_lock);
|
|
retry:
|
|
retry:
|
|
issued = __ceph_caps_issued(ci, NULL);
|
|
issued = __ceph_caps_issued(ci, NULL);
|
|
@@ -991,7 +996,8 @@ retry:
|
|
flags, value ? 1 : -1, &xattr);
|
|
flags, value ? 1 : -1, &xattr);
|
|
|
|
|
|
if (!err) {
|
|
if (!err) {
|
|
- dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
|
|
|
|
|
|
+ dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL,
|
|
|
|
+ &prealloc_cf);
|
|
ci->i_xattrs.dirty = true;
|
|
ci->i_xattrs.dirty = true;
|
|
inode->i_ctime = CURRENT_TIME;
|
|
inode->i_ctime = CURRENT_TIME;
|
|
}
|
|
}
|
|
@@ -1001,6 +1007,7 @@ retry:
|
|
up_read(&mdsc->snap_rwsem);
|
|
up_read(&mdsc->snap_rwsem);
|
|
if (dirty)
|
|
if (dirty)
|
|
__mark_inode_dirty(inode, dirty);
|
|
__mark_inode_dirty(inode, dirty);
|
|
|
|
+ ceph_free_cap_flush(prealloc_cf);
|
|
return err;
|
|
return err;
|
|
|
|
|
|
do_sync:
|
|
do_sync:
|
|
@@ -1010,6 +1017,7 @@ do_sync_unlocked:
|
|
up_read(&mdsc->snap_rwsem);
|
|
up_read(&mdsc->snap_rwsem);
|
|
err = ceph_sync_setxattr(dentry, name, value, size, flags);
|
|
err = ceph_sync_setxattr(dentry, name, value, size, flags);
|
|
out:
|
|
out:
|
|
|
|
+ ceph_free_cap_flush(prealloc_cf);
|
|
kfree(newname);
|
|
kfree(newname);
|
|
kfree(newval);
|
|
kfree(newval);
|
|
kfree(xattr);
|
|
kfree(xattr);
|
|
@@ -1062,6 +1070,7 @@ int __ceph_removexattr(struct dentry *dentry, const char *name)
|
|
struct ceph_vxattr *vxattr;
|
|
struct ceph_vxattr *vxattr;
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
|
|
struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
|
|
|
|
+ struct ceph_cap_flush *prealloc_cf = NULL;
|
|
int issued;
|
|
int issued;
|
|
int err;
|
|
int err;
|
|
int required_blob_size;
|
|
int required_blob_size;
|
|
@@ -1079,6 +1088,10 @@ int __ceph_removexattr(struct dentry *dentry, const char *name)
|
|
if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN))
|
|
if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN))
|
|
goto do_sync_unlocked;
|
|
goto do_sync_unlocked;
|
|
|
|
|
|
|
|
+ prealloc_cf = ceph_alloc_cap_flush();
|
|
|
|
+ if (!prealloc_cf)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
err = -ENOMEM;
|
|
err = -ENOMEM;
|
|
spin_lock(&ci->i_ceph_lock);
|
|
spin_lock(&ci->i_ceph_lock);
|
|
retry:
|
|
retry:
|
|
@@ -1120,7 +1133,8 @@ retry:
|
|
|
|
|
|
err = __remove_xattr_by_name(ceph_inode(inode), name);
|
|
err = __remove_xattr_by_name(ceph_inode(inode), name);
|
|
|
|
|
|
- dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
|
|
|
|
|
|
+ dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL,
|
|
|
|
+ &prealloc_cf);
|
|
ci->i_xattrs.dirty = true;
|
|
ci->i_xattrs.dirty = true;
|
|
inode->i_ctime = CURRENT_TIME;
|
|
inode->i_ctime = CURRENT_TIME;
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
@@ -1128,12 +1142,14 @@ retry:
|
|
up_read(&mdsc->snap_rwsem);
|
|
up_read(&mdsc->snap_rwsem);
|
|
if (dirty)
|
|
if (dirty)
|
|
__mark_inode_dirty(inode, dirty);
|
|
__mark_inode_dirty(inode, dirty);
|
|
|
|
+ ceph_free_cap_flush(prealloc_cf);
|
|
return err;
|
|
return err;
|
|
do_sync:
|
|
do_sync:
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
do_sync_unlocked:
|
|
do_sync_unlocked:
|
|
if (lock_snap_rwsem)
|
|
if (lock_snap_rwsem)
|
|
up_read(&mdsc->snap_rwsem);
|
|
up_read(&mdsc->snap_rwsem);
|
|
|
|
+ ceph_free_cap_flush(prealloc_cf);
|
|
err = ceph_send_removexattr(dentry, name);
|
|
err = ceph_send_removexattr(dentry, name);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|