diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 13:29:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 13:29:21 -0500 |
commit | 1a52bb0b686844021597d190e562ab55d1210104 (patch) | |
tree | 7edf13509869a6a7f1f488a679f15ff6c3057c54 /fs/ceph/xattr.c | |
parent | 8638094e956a47dbb9a25166705a91e9a0981d52 (diff) | |
parent | 83eb26af0db71f2dfe551405c55d982288fa6178 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
ceph: ensure prealloc_blob is in place when removing xattr
rbd: initialize snap_rwsem in rbd_add()
ceph: enable/disable dentry complete flags via mount option
vfs: export symbol d_find_any_alias()
ceph: always initialize the dentry in open_root_dentry()
libceph: remove useless return value for osd_client __send_request()
ceph: avoid iput() while holding spinlock in ceph_dir_fsync
ceph: avoid useless dget/dput in encode_fh
ceph: dereference pointer after checking for NULL
crush: fix force for non-root TAKE
ceph: remove unnecessary d_fsdata conditional checks
ceph: Use kmemdup rather than duplicating its implementation
Fix up conflicts in fs/ceph/super.c (d_alloc_root() failure handling vs
always initialize the dentry in open_root_dentry)
Diffstat (limited to 'fs/ceph/xattr.c')
-rw-r--r-- | fs/ceph/xattr.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index a5e36e4488a7..857214ae8c08 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -818,6 +818,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name) | |||
818 | struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); | 818 | struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); |
819 | int issued; | 819 | int issued; |
820 | int err; | 820 | int err; |
821 | int required_blob_size; | ||
821 | int dirty; | 822 | int dirty; |
822 | 823 | ||
823 | if (ceph_snap(inode) != CEPH_NOSNAP) | 824 | if (ceph_snap(inode) != CEPH_NOSNAP) |
@@ -833,14 +834,34 @@ int ceph_removexattr(struct dentry *dentry, const char *name) | |||
833 | return -EOPNOTSUPP; | 834 | return -EOPNOTSUPP; |
834 | } | 835 | } |
835 | 836 | ||
837 | err = -ENOMEM; | ||
836 | spin_lock(&ci->i_ceph_lock); | 838 | spin_lock(&ci->i_ceph_lock); |
837 | __build_xattrs(inode); | 839 | __build_xattrs(inode); |
840 | retry: | ||
838 | issued = __ceph_caps_issued(ci, NULL); | 841 | issued = __ceph_caps_issued(ci, NULL); |
839 | dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); | 842 | dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); |
840 | 843 | ||
841 | if (!(issued & CEPH_CAP_XATTR_EXCL)) | 844 | if (!(issued & CEPH_CAP_XATTR_EXCL)) |
842 | goto do_sync; | 845 | goto do_sync; |
843 | 846 | ||
847 | required_blob_size = __get_required_blob_size(ci, 0, 0); | ||
848 | |||
849 | if (!ci->i_xattrs.prealloc_blob || | ||
850 | required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { | ||
851 | struct ceph_buffer *blob; | ||
852 | |||
853 | spin_unlock(&ci->i_ceph_lock); | ||
854 | dout(" preaallocating new blob size=%d\n", required_blob_size); | ||
855 | blob = ceph_buffer_new(required_blob_size, GFP_NOFS); | ||
856 | if (!blob) | ||
857 | goto out; | ||
858 | spin_lock(&ci->i_ceph_lock); | ||
859 | if (ci->i_xattrs.prealloc_blob) | ||
860 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | ||
861 | ci->i_xattrs.prealloc_blob = blob; | ||
862 | goto retry; | ||
863 | } | ||
864 | |||
844 | err = __remove_xattr_by_name(ceph_inode(inode), name); | 865 | err = __remove_xattr_by_name(ceph_inode(inode), name); |
845 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); | 866 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); |
846 | ci->i_xattrs.dirty = true; | 867 | ci->i_xattrs.dirty = true; |
@@ -853,6 +874,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name) | |||
853 | do_sync: | 874 | do_sync: |
854 | spin_unlock(&ci->i_ceph_lock); | 875 | spin_unlock(&ci->i_ceph_lock); |
855 | err = ceph_send_removexattr(dentry, name); | 876 | err = ceph_send_removexattr(dentry, name); |
877 | out: | ||
856 | return err; | 878 | return err; |
857 | } | 879 | } |
858 | 880 | ||