diff options
-rw-r--r-- | fs/ceph/xattr.c | 126 |
1 files changed, 0 insertions, 126 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 8966e9d96bdb..0d66722c6a52 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -498,19 +498,6 @@ static int __remove_xattr(struct ceph_inode_info *ci, | |||
498 | return 0; | 498 | return 0; |
499 | } | 499 | } |
500 | 500 | ||
501 | static int __remove_xattr_by_name(struct ceph_inode_info *ci, | ||
502 | const char *name) | ||
503 | { | ||
504 | struct rb_node **p; | ||
505 | struct ceph_inode_xattr *xattr; | ||
506 | int err; | ||
507 | |||
508 | p = &ci->i_xattrs.index.rb_node; | ||
509 | xattr = __get_xattr(ci, name); | ||
510 | err = __remove_xattr(ci, xattr); | ||
511 | return err; | ||
512 | } | ||
513 | |||
514 | static char *__copy_xattr_names(struct ceph_inode_info *ci, | 501 | static char *__copy_xattr_names(struct ceph_inode_info *ci, |
515 | char *dest) | 502 | char *dest) |
516 | { | 503 | { |
@@ -1054,119 +1041,6 @@ out: | |||
1054 | return err; | 1041 | return err; |
1055 | } | 1042 | } |
1056 | 1043 | ||
1057 | static int ceph_send_removexattr(struct inode *inode, const char *name) | ||
1058 | { | ||
1059 | struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); | ||
1060 | struct ceph_mds_client *mdsc = fsc->mdsc; | ||
1061 | struct ceph_mds_request *req; | ||
1062 | int err; | ||
1063 | |||
1064 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, | ||
1065 | USE_AUTH_MDS); | ||
1066 | if (IS_ERR(req)) | ||
1067 | return PTR_ERR(req); | ||
1068 | req->r_path2 = kstrdup(name, GFP_NOFS); | ||
1069 | if (!req->r_path2) | ||
1070 | return -ENOMEM; | ||
1071 | |||
1072 | req->r_inode = inode; | ||
1073 | ihold(inode); | ||
1074 | req->r_num_caps = 1; | ||
1075 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; | ||
1076 | err = ceph_mdsc_do_request(mdsc, NULL, req); | ||
1077 | ceph_mdsc_put_request(req); | ||
1078 | return err; | ||
1079 | } | ||
1080 | |||
1081 | static int __ceph_removexattr(struct inode *inode, const char *name) | ||
1082 | { | ||
1083 | struct ceph_vxattr *vxattr; | ||
1084 | struct ceph_inode_info *ci = ceph_inode(inode); | ||
1085 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | ||
1086 | struct ceph_cap_flush *prealloc_cf = NULL; | ||
1087 | int issued; | ||
1088 | int err; | ||
1089 | int required_blob_size; | ||
1090 | int dirty; | ||
1091 | bool lock_snap_rwsem = false; | ||
1092 | |||
1093 | if (ceph_snap(inode) != CEPH_NOSNAP) | ||
1094 | return -EROFS; | ||
1095 | |||
1096 | vxattr = ceph_match_vxattr(inode, name); | ||
1097 | if (vxattr && vxattr->readonly) | ||
1098 | return -EOPNOTSUPP; | ||
1099 | |||
1100 | /* pass any unhandled ceph.* xattrs through to the MDS */ | ||
1101 | if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) | ||
1102 | goto do_sync_unlocked; | ||
1103 | |||
1104 | prealloc_cf = ceph_alloc_cap_flush(); | ||
1105 | if (!prealloc_cf) | ||
1106 | return -ENOMEM; | ||
1107 | |||
1108 | err = -ENOMEM; | ||
1109 | spin_lock(&ci->i_ceph_lock); | ||
1110 | retry: | ||
1111 | issued = __ceph_caps_issued(ci, NULL); | ||
1112 | if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) | ||
1113 | goto do_sync; | ||
1114 | |||
1115 | if (!lock_snap_rwsem && !ci->i_head_snapc) { | ||
1116 | lock_snap_rwsem = true; | ||
1117 | if (!down_read_trylock(&mdsc->snap_rwsem)) { | ||
1118 | spin_unlock(&ci->i_ceph_lock); | ||
1119 | down_read(&mdsc->snap_rwsem); | ||
1120 | spin_lock(&ci->i_ceph_lock); | ||
1121 | goto retry; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); | ||
1126 | |||
1127 | __build_xattrs(inode); | ||
1128 | |||
1129 | required_blob_size = __get_required_blob_size(ci, 0, 0); | ||
1130 | |||
1131 | if (!ci->i_xattrs.prealloc_blob || | ||
1132 | required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { | ||
1133 | struct ceph_buffer *blob; | ||
1134 | |||
1135 | spin_unlock(&ci->i_ceph_lock); | ||
1136 | dout(" preaallocating new blob size=%d\n", required_blob_size); | ||
1137 | blob = ceph_buffer_new(required_blob_size, GFP_NOFS); | ||
1138 | if (!blob) | ||
1139 | goto do_sync_unlocked; | ||
1140 | spin_lock(&ci->i_ceph_lock); | ||
1141 | if (ci->i_xattrs.prealloc_blob) | ||
1142 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | ||
1143 | ci->i_xattrs.prealloc_blob = blob; | ||
1144 | goto retry; | ||
1145 | } | ||
1146 | |||
1147 | err = __remove_xattr_by_name(ceph_inode(inode), name); | ||
1148 | |||
1149 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL, | ||
1150 | &prealloc_cf); | ||
1151 | ci->i_xattrs.dirty = true; | ||
1152 | inode->i_ctime = current_fs_time(inode->i_sb); | ||
1153 | spin_unlock(&ci->i_ceph_lock); | ||
1154 | if (lock_snap_rwsem) | ||
1155 | up_read(&mdsc->snap_rwsem); | ||
1156 | if (dirty) | ||
1157 | __mark_inode_dirty(inode, dirty); | ||
1158 | ceph_free_cap_flush(prealloc_cf); | ||
1159 | return err; | ||
1160 | do_sync: | ||
1161 | spin_unlock(&ci->i_ceph_lock); | ||
1162 | do_sync_unlocked: | ||
1163 | if (lock_snap_rwsem) | ||
1164 | up_read(&mdsc->snap_rwsem); | ||
1165 | ceph_free_cap_flush(prealloc_cf); | ||
1166 | err = ceph_send_removexattr(inode, name); | ||
1167 | return err; | ||
1168 | } | ||
1169 | |||
1170 | static int ceph_get_xattr_handler(const struct xattr_handler *handler, | 1044 | static int ceph_get_xattr_handler(const struct xattr_handler *handler, |
1171 | struct dentry *dentry, struct inode *inode, | 1045 | struct dentry *dentry, struct inode *inode, |
1172 | const char *name, void *value, size_t size) | 1046 | const char *name, void *value, size_t size) |