aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/xattr.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/btrfs/xattr.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r--fs/btrfs/xattr.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 88ecbb215878..5366fe452ab0 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -44,7 +44,7 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
44 return -ENOMEM; 44 return -ENOMEM;
45 45
46 /* lookup the xattr by name */ 46 /* lookup the xattr by name */
47 di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, 47 di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), name,
48 strlen(name), 0); 48 strlen(name), 0);
49 if (!di) { 49 if (!di) {
50 ret = -ENODATA; 50 ret = -ENODATA;
@@ -103,7 +103,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
103 return -ENOMEM; 103 return -ENOMEM;
104 104
105 /* first lets see if we already have this xattr */ 105 /* first lets see if we already have this xattr */
106 di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name, 106 di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name,
107 strlen(name), -1); 107 strlen(name), -1);
108 if (IS_ERR(di)) { 108 if (IS_ERR(di)) {
109 ret = PTR_ERR(di); 109 ret = PTR_ERR(di);
@@ -120,13 +120,13 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
120 120
121 ret = btrfs_delete_one_dir_name(trans, root, path, di); 121 ret = btrfs_delete_one_dir_name(trans, root, path, di);
122 BUG_ON(ret); 122 BUG_ON(ret);
123 btrfs_release_path(root, path); 123 btrfs_release_path(path);
124 124
125 /* if we don't have a value then we are removing the xattr */ 125 /* if we don't have a value then we are removing the xattr */
126 if (!value) 126 if (!value)
127 goto out; 127 goto out;
128 } else { 128 } else {
129 btrfs_release_path(root, path); 129 btrfs_release_path(path);
130 130
131 if (flags & XATTR_REPLACE) { 131 if (flags & XATTR_REPLACE) {
132 /* we couldn't find the attr to replace */ 132 /* we couldn't find the attr to replace */
@@ -136,7 +136,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
136 } 136 }
137 137
138 /* ok we have to create a completely new xattr */ 138 /* ok we have to create a completely new xattr */
139 ret = btrfs_insert_xattr_item(trans, root, path, inode->i_ino, 139 ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
140 name, name_len, value, size); 140 name, name_len, value, size);
141 BUG_ON(ret); 141 BUG_ON(ret);
142out: 142out:
@@ -158,8 +158,6 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans,
158 if (IS_ERR(trans)) 158 if (IS_ERR(trans))
159 return PTR_ERR(trans); 159 return PTR_ERR(trans);
160 160
161 btrfs_set_trans_block_group(trans, inode);
162
163 ret = do_setxattr(trans, inode, name, value, size, flags); 161 ret = do_setxattr(trans, inode, name, value, size, flags);
164 if (ret) 162 if (ret)
165 goto out; 163 goto out;
@@ -178,21 +176,19 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
178 struct inode *inode = dentry->d_inode; 176 struct inode *inode = dentry->d_inode;
179 struct btrfs_root *root = BTRFS_I(inode)->root; 177 struct btrfs_root *root = BTRFS_I(inode)->root;
180 struct btrfs_path *path; 178 struct btrfs_path *path;
181 struct btrfs_item *item;
182 struct extent_buffer *leaf; 179 struct extent_buffer *leaf;
183 struct btrfs_dir_item *di; 180 struct btrfs_dir_item *di;
184 int ret = 0, slot, advance; 181 int ret = 0, slot;
185 size_t total_size = 0, size_left = size; 182 size_t total_size = 0, size_left = size;
186 unsigned long name_ptr; 183 unsigned long name_ptr;
187 size_t name_len; 184 size_t name_len;
188 u32 nritems;
189 185
190 /* 186 /*
191 * ok we want all objects associated with this id. 187 * ok we want all objects associated with this id.
192 * NOTE: we set key.offset = 0; because we want to start with the 188 * NOTE: we set key.offset = 0; because we want to start with the
193 * first xattr that we find and walk forward 189 * first xattr that we find and walk forward
194 */ 190 */
195 key.objectid = inode->i_ino; 191 key.objectid = btrfs_ino(inode);
196 btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); 192 btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
197 key.offset = 0; 193 key.offset = 0;
198 194
@@ -205,36 +201,25 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
205 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 201 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
206 if (ret < 0) 202 if (ret < 0)
207 goto err; 203 goto err;
208 advance = 0; 204
209 while (1) { 205 while (1) {
210 leaf = path->nodes[0]; 206 leaf = path->nodes[0];
211 nritems = btrfs_header_nritems(leaf);
212 slot = path->slots[0]; 207 slot = path->slots[0];
213 208
214 /* this is where we start walking through the path */ 209 /* this is where we start walking through the path */
215 if (advance || slot >= nritems) { 210 if (slot >= btrfs_header_nritems(leaf)) {
216 /* 211 /*
217 * if we've reached the last slot in this leaf we need 212 * if we've reached the last slot in this leaf we need
218 * to go to the next leaf and reset everything 213 * to go to the next leaf and reset everything
219 */ 214 */
220 if (slot >= nritems-1) { 215 ret = btrfs_next_leaf(root, path);
221 ret = btrfs_next_leaf(root, path); 216 if (ret < 0)
222 if (ret) 217 goto err;
223 break; 218 else if (ret > 0)
224 leaf = path->nodes[0]; 219 break;
225 nritems = btrfs_header_nritems(leaf); 220 continue;
226 slot = path->slots[0];
227 } else {
228 /*
229 * just walking through the slots on this leaf
230 */
231 slot++;
232 path->slots[0]++;
233 }
234 } 221 }
235 advance = 1;
236 222
237 item = btrfs_item_nr(leaf, slot);
238 btrfs_item_key_to_cpu(leaf, &found_key, slot); 223 btrfs_item_key_to_cpu(leaf, &found_key, slot);
239 224
240 /* check to make sure this item is what we want */ 225 /* check to make sure this item is what we want */
@@ -244,13 +229,15 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
244 break; 229 break;
245 230
246 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 231 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
232 if (verify_dir_item(root, leaf, di))
233 continue;
247 234
248 name_len = btrfs_dir_name_len(leaf, di); 235 name_len = btrfs_dir_name_len(leaf, di);
249 total_size += name_len + 1; 236 total_size += name_len + 1;
250 237
251 /* we are just looking for how big our buffer needs to be */ 238 /* we are just looking for how big our buffer needs to be */
252 if (!size) 239 if (!size)
253 continue; 240 goto next;
254 241
255 if (!buffer || (name_len + 1) > size_left) { 242 if (!buffer || (name_len + 1) > size_left) {
256 ret = -ERANGE; 243 ret = -ERANGE;
@@ -263,6 +250,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
263 250
264 size_left -= name_len + 1; 251 size_left -= name_len + 1;
265 buffer += name_len + 1; 252 buffer += name_len + 1;
253next:
254 path->slots[0]++;
266 } 255 }
267 ret = total_size; 256 ret = total_size;
268 257
@@ -318,6 +307,15 @@ ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
318int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, 307int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
319 size_t size, int flags) 308 size_t size, int flags)
320{ 309{
310 struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root;
311
312 /*
313 * The permission on security.* and system.* is not checked
314 * in permission().
315 */
316 if (btrfs_root_readonly(root))
317 return -EROFS;
318
321 /* 319 /*
322 * If this is a request for a synthetic attribute in the system.* 320 * If this is a request for a synthetic attribute in the system.*
323 * namespace use the generic infrastructure to resolve a handler 321 * namespace use the generic infrastructure to resolve a handler
@@ -338,6 +336,15 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
338 336
339int btrfs_removexattr(struct dentry *dentry, const char *name) 337int btrfs_removexattr(struct dentry *dentry, const char *name)
340{ 338{
339 struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root;
340
341 /*
342 * The permission on security.* and system.* is not checked
343 * in permission().
344 */
345 if (btrfs_root_readonly(root))
346 return -EROFS;
347
341 /* 348 /*
342 * If this is a request for a synthetic attribute in the system.* 349 * If this is a request for a synthetic attribute in the system.*
343 * namespace use the generic infrastructure to resolve a handler 350 * namespace use the generic infrastructure to resolve a handler
@@ -354,7 +361,8 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
354} 361}
355 362
356int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, 363int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
357 struct inode *inode, struct inode *dir) 364 struct inode *inode, struct inode *dir,
365 const struct qstr *qstr)
358{ 366{
359 int err; 367 int err;
360 size_t len; 368 size_t len;
@@ -362,7 +370,8 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
362 char *suffix; 370 char *suffix;
363 char *name; 371 char *name;
364 372
365 err = security_inode_init_security(inode, dir, &suffix, &value, &len); 373 err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
374 &len);
366 if (err) { 375 if (err) {
367 if (err == -EOPNOTSUPP) 376 if (err == -EOPNOTSUPP)
368 return 0; 377 return 0;