1 /* 2 * Copyright (C) 2007 Red Hat. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public 14 * License along with this program; if not, write to the 15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 * Boston, MA 021110-1307, USA. 17 */ 18 19 #include <linux/init.h> 20 #include <linux/fs.h> 21 #include <linux/slab.h> 22 #include <linux/rwsem.h> 23 #include <linux/xattr.h> 24 #include "ctree.h" 25 #include "btrfs_inode.h" 26 #include "transaction.h" 27 #include "xattr.h" 28 #include "disk-io.h" 29 30 static struct xattr_handler *btrfs_xattr_handler_map[] = { 31 [BTRFS_XATTR_INDEX_USER] = &btrfs_xattr_user_handler, 32 #ifdef CONFIG_FS_POSIX_ACL 33 [BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS] = &btrfs_xattr_acl_access_handler, 34 [BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &btrfs_xattr_acl_default_handler, 35 #endif 36 [BTRFS_XATTR_INDEX_TRUSTED] = &btrfs_xattr_trusted_handler, 37 [BTRFS_XATTR_INDEX_SECURITY] = &btrfs_xattr_security_handler, 38 [BTRFS_XATTR_INDEX_SYSTEM] = &btrfs_xattr_system_handler, 39 }; 40 41 struct xattr_handler *btrfs_xattr_handlers[] = { 42 &btrfs_xattr_user_handler, 43 #ifdef CONFIG_FS_POSIX_ACL 44 &btrfs_xattr_acl_access_handler, 45 &btrfs_xattr_acl_default_handler, 46 #endif 47 &btrfs_xattr_trusted_handler, 48 &btrfs_xattr_security_handler, 49 &btrfs_xattr_system_handler, 50 NULL, 51 }; 52 53 /* 54 * @param name - the xattr name 55 * @return - the xattr_handler for the xattr, NULL if its not found 56 * 57 * use this with listxattr where we don't already know the type of xattr we 58 * have 59 */ 60 static struct xattr_handler *find_btrfs_xattr_handler(struct extent_buffer *l, 61 unsigned long name_ptr, 62 u16 name_len) 63 { 64 struct xattr_handler *handler = NULL; 65 int i = 0; 66 67 for (handler = btrfs_xattr_handlers[i]; handler != NULL; i++, 68 handler = btrfs_xattr_handlers[i]) { 69 u16 prefix_len = strlen(handler->prefix); 70 71 if (name_len < prefix_len) 72 continue; 73 74 if (memcmp_extent_buffer(l, handler->prefix, name_ptr, 75 prefix_len) == 0) 76 break; 77 } 78 79 return handler; 80 } 81 82 /* 83 * @param name_index - the index for the xattr handler 84 * @return the xattr_handler if we found it, NULL otherwise 85 * 86 * use this if we know the type of the xattr already 87 */ 88 static struct xattr_handler *btrfs_xattr_handler(int name_index) 89 { 90 struct xattr_handler *handler = NULL; 91 92 if (name_index >= 0 && 93 name_index < ARRAY_SIZE(btrfs_xattr_handler_map)) 94 handler = btrfs_xattr_handler_map[name_index]; 95 96 return handler; 97 } 98 99 static inline char *get_name(const char *name, int name_index) 100 { 101 char *ret = NULL; 102 struct xattr_handler *handler = btrfs_xattr_handler(name_index); 103 int prefix_len; 104 105 if (!handler) 106 return ret; 107 108 prefix_len = strlen(handler->prefix); 109 110 ret = kmalloc(strlen(name) + prefix_len + 1, GFP_KERNEL); 111 if (!ret) 112 return ret; 113 114 memcpy(ret, handler->prefix, prefix_len); 115 memcpy(ret+prefix_len, name, strlen(name)); 116 ret[prefix_len + strlen(name)] = '\0'; 117 118 return ret; 119 } 120 121 size_t btrfs_xattr_generic_list(struct inode *inode, char *list, 122 size_t list_size, const char *name, 123 size_t name_len) 124 { 125 if (list && (name_len+1) <= list_size) { 126 memcpy(list, name, name_len); 127 list[name_len] = '\0'; 128 } else 129 return -ERANGE; 130 131 return name_len+1; 132 } 133 134 ssize_t btrfs_xattr_get(struct inode *inode, int name_index, 135 const char *attr_name, void *buffer, size_t size) 136 { 137 struct btrfs_dir_item *di; 138 struct btrfs_root *root = BTRFS_I(inode)->root; 139 struct btrfs_path *path; 140 struct extent_buffer *leaf; 141 struct xattr_handler *handler = btrfs_xattr_handler(name_index); 142 int ret = 0; 143 unsigned long data_ptr; 144 char *name; 145 146 if (!handler) 147 return -EOPNOTSUPP; 148 name = get_name(attr_name, name_index); 149 if (!name) 150 return -ENOMEM; 151 152 path = btrfs_alloc_path(); 153 if (!path) { 154 kfree(name); 155 return -ENOMEM; 156 } 157 158 /* lookup the xattr by name */ 159 di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, 160 strlen(name), 0); 161 if (!di || IS_ERR(di)) { 162 ret = -ENODATA; 163 goto out; 164 } 165 166 leaf = path->nodes[0]; 167 /* if size is 0, that means we want the size of the attr */ 168 if (!size) { 169 ret = btrfs_dir_data_len(leaf, di); 170 goto out; 171 } 172 173 /* now get the data out of our dir_item */ 174 if (btrfs_dir_data_len(leaf, di) > size) { 175 ret = -ERANGE; 176 goto out; 177 } 178 data_ptr = (unsigned long)((char *)(di + 1) + 179 btrfs_dir_name_len(leaf, di)); 180 read_extent_buffer(leaf, buffer, data_ptr, 181 btrfs_dir_data_len(leaf, di)); 182 ret = btrfs_dir_data_len(leaf, di); 183 184 out: 185 kfree(name); 186 btrfs_free_path(path); 187 return ret; 188 } 189 190 int btrfs_xattr_set(struct inode *inode, int name_index, 191 const char *attr_name, const void *value, size_t size, 192 int flags) 193 { 194 struct btrfs_dir_item *di; 195 struct btrfs_root *root = BTRFS_I(inode)->root; 196 struct btrfs_trans_handle *trans; 197 struct btrfs_path *path; 198 struct xattr_handler *handler = btrfs_xattr_handler(name_index); 199 char *name; 200 int ret = 0, mod = 0; 201 if (!handler) 202 return -EOPNOTSUPP; 203 name = get_name(attr_name, name_index); 204 if (!name) 205 return -ENOMEM; 206 207 path = btrfs_alloc_path(); 208 if (!path) { 209 kfree(name); 210 return -ENOMEM; 211 } 212 213 trans = btrfs_start_transaction(root, 1); 214 btrfs_set_trans_block_group(trans, inode); 215 216 /* first lets see if we already have this xattr */ 217 di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name, 218 strlen(name), -1); 219 if (IS_ERR(di)) { 220 ret = PTR_ERR(di); 221 goto out; 222 } 223 224 /* ok we already have this xattr, lets remove it */ 225 if (di) { 226 /* if we want create only exit */ 227 if (flags & XATTR_CREATE) { 228 ret = -EEXIST; 229 goto out; 230 } 231 232 ret = btrfs_delete_one_dir_name(trans, root, path, di); 233 if (ret) 234 goto out; 235 btrfs_release_path(root, path); 236 237 /* if we don't have a value then we are removing the xattr */ 238 if (!value) { 239 mod = 1; 240 goto out; 241 } 242 } else { 243 btrfs_release_path(root, path); 244 245 if (flags & XATTR_REPLACE) { 246 /* we couldn't find the attr to replace */ 247 ret = -ENODATA; 248 goto out; 249 } 250 } 251 252 /* ok we have to create a completely new xattr */ 253 ret = btrfs_insert_xattr_item(trans, root, name, strlen(name), 254 value, size, inode->i_ino); 255 if (ret) 256 goto out; 257 mod = 1; 258 259 out: 260 if (mod) { 261 inode->i_ctime = CURRENT_TIME; 262 ret = btrfs_update_inode(trans, root, inode); 263 } 264 265 btrfs_end_transaction(trans, root); 266 kfree(name); 267 btrfs_free_path(path); 268 269 return ret; 270 } 271 272 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) 273 { 274 struct btrfs_key key, found_key; 275 struct inode *inode = dentry->d_inode; 276 struct btrfs_root *root = BTRFS_I(inode)->root; 277 struct btrfs_path *path; 278 struct btrfs_item *item; 279 struct extent_buffer *leaf; 280 struct btrfs_dir_item *di; 281 struct xattr_handler *handler; 282 int ret = 0, slot, advance; 283 size_t total_size = 0, size_left = size, written; 284 unsigned long name_ptr; 285 char *name; 286 u32 nritems; 287 288 /* 289 * ok we want all objects associated with this id. 290 * NOTE: we set key.offset = 0; because we want to start with the 291 * first xattr that we find and walk forward 292 */ 293 key.objectid = inode->i_ino; 294 btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); 295 key.offset = 0; 296 297 path = btrfs_alloc_path(); 298 if (!path) 299 return -ENOMEM; 300 path->reada = 2; 301 302 /* search for our xattrs */ 303 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 304 if (ret < 0) 305 goto err; 306 ret = 0; 307 advance = 0; 308 while (1) { 309 leaf = path->nodes[0]; 310 nritems = btrfs_header_nritems(leaf); 311 slot = path->slots[0]; 312 313 /* this is where we start walking through the path */ 314 if (advance || slot >= nritems) { 315 /* 316 * if we've reached the last slot in this leaf we need 317 * to go to the next leaf and reset everything 318 */ 319 if (slot >= nritems-1) { 320 ret = btrfs_next_leaf(root, path); 321 if (ret) 322 break; 323 leaf = path->nodes[0]; 324 nritems = btrfs_header_nritems(leaf); 325 slot = path->slots[0]; 326 } else { 327 /* 328 * just walking through the slots on this leaf 329 */ 330 slot++; 331 path->slots[0]++; 332 } 333 } 334 advance = 1; 335 336 item = btrfs_item_nr(leaf, slot); 337 btrfs_item_key_to_cpu(leaf, &found_key, slot); 338 339 /* check to make sure this item is what we want */ 340 if (found_key.objectid != key.objectid) 341 break; 342 if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY) 343 break; 344 345 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 346 347 total_size += btrfs_dir_name_len(leaf, di)+1; 348 349 /* we are just looking for how big our buffer needs to be */ 350 if (!size) 351 continue; 352 353 /* find our handler for this xattr */ 354 name_ptr = (unsigned long)(di + 1); 355 handler = find_btrfs_xattr_handler(leaf, name_ptr, 356 btrfs_dir_name_len(leaf, di)); 357 if (!handler) { 358 printk(KERN_ERR "btrfs: unsupported xattr found\n"); 359 continue; 360 } 361 362 name = kmalloc(btrfs_dir_name_len(leaf, di), GFP_KERNEL); 363 read_extent_buffer(leaf, name, name_ptr, 364 btrfs_dir_name_len(leaf, di)); 365 366 /* call the list function associated with this xattr */ 367 written = handler->list(inode, buffer, size_left, name, 368 btrfs_dir_name_len(leaf, di)); 369 kfree(name); 370 371 if (written < 0) { 372 ret = -ERANGE; 373 break; 374 } 375 376 size_left -= written; 377 buffer += written; 378 } 379 ret = total_size; 380 381 err: 382 btrfs_free_path(path); 383 384 return ret; 385 } 386 387 /* 388 * Handler functions 389 */ 390 #define BTRFS_XATTR_SETGET_FUNCS(name, index) \ 391 static int btrfs_xattr_##name##_get(struct inode *inode, \ 392 const char *name, void *value, \ 393 size_t size) \ 394 { \ 395 if (*name == '\0') \ 396 return -EINVAL; \ 397 return btrfs_xattr_get(inode, index, name, value, size); \ 398 } \ 399 static int btrfs_xattr_##name##_set(struct inode *inode, \ 400 const char *name, const void *value,\ 401 size_t size, int flags) \ 402 { \ 403 if (*name == '\0') \ 404 return -EINVAL; \ 405 return btrfs_xattr_set(inode, index, name, value, size, flags); \ 406 } 407 408 BTRFS_XATTR_SETGET_FUNCS(security, BTRFS_XATTR_INDEX_SECURITY); 409 BTRFS_XATTR_SETGET_FUNCS(system, BTRFS_XATTR_INDEX_SYSTEM); 410 BTRFS_XATTR_SETGET_FUNCS(user, BTRFS_XATTR_INDEX_USER); 411 BTRFS_XATTR_SETGET_FUNCS(trusted, BTRFS_XATTR_INDEX_TRUSTED); 412 413 struct xattr_handler btrfs_xattr_security_handler = { 414 .prefix = XATTR_SECURITY_PREFIX, 415 .list = btrfs_xattr_generic_list, 416 .get = btrfs_xattr_security_get, 417 .set = btrfs_xattr_security_set, 418 }; 419 420 struct xattr_handler btrfs_xattr_system_handler = { 421 .prefix = XATTR_SYSTEM_PREFIX, 422 .list = btrfs_xattr_generic_list, 423 .get = btrfs_xattr_system_get, 424 .set = btrfs_xattr_system_set, 425 }; 426 427 struct xattr_handler btrfs_xattr_user_handler = { 428 .prefix = XATTR_USER_PREFIX, 429 .list = btrfs_xattr_generic_list, 430 .get = btrfs_xattr_user_get, 431 .set = btrfs_xattr_user_set, 432 }; 433 434 struct xattr_handler btrfs_xattr_trusted_handler = { 435 .prefix = XATTR_TRUSTED_PREFIX, 436 .list = btrfs_xattr_generic_list, 437 .get = btrfs_xattr_trusted_get, 438 .set = btrfs_xattr_trusted_set, 439 }; 440