xattr_acl.c revision e68888bcb60ccba4dc21df9f2d8cd7325b64dce7
1#include <linux/capability.h> 2#include <linux/fs.h> 3#include <linux/posix_acl.h> 4#include <linux/reiserfs_fs.h> 5#include <linux/errno.h> 6#include <linux/pagemap.h> 7#include <linux/xattr.h> 8#include <linux/posix_acl_xattr.h> 9#include <linux/reiserfs_xattr.h> 10#include <linux/reiserfs_acl.h> 11#include <asm/uaccess.h> 12 13static int reiserfs_set_acl(struct reiserfs_transaction_handle *th, 14 struct inode *inode, int type, 15 struct posix_acl *acl); 16 17static int 18xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) 19{ 20 struct posix_acl *acl; 21 int error, error2; 22 struct reiserfs_transaction_handle th; 23 size_t jcreate_blocks; 24 if (!reiserfs_posixacl(inode->i_sb)) 25 return -EOPNOTSUPP; 26 if (!is_owner_or_cap(inode)) 27 return -EPERM; 28 29 if (value) { 30 acl = posix_acl_from_xattr(value, size); 31 if (IS_ERR(acl)) { 32 return PTR_ERR(acl); 33 } else if (acl) { 34 error = posix_acl_valid(acl); 35 if (error) 36 goto release_and_out; 37 } 38 } else 39 acl = NULL; 40 41 /* Pessimism: We can't assume that anything from the xattr root up 42 * has been created. */ 43 44 jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) + 45 reiserfs_xattr_nblocks(inode, size) * 2; 46 47 reiserfs_write_lock(inode->i_sb); 48 error = journal_begin(&th, inode->i_sb, jcreate_blocks); 49 if (error == 0) { 50 error = reiserfs_set_acl(&th, inode, type, acl); 51 error2 = journal_end(&th, inode->i_sb, jcreate_blocks); 52 if (error2) 53 error = error2; 54 } 55 reiserfs_write_unlock(inode->i_sb); 56 57 release_and_out: 58 posix_acl_release(acl); 59 return error; 60} 61 62static int 63xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) 64{ 65 struct posix_acl *acl; 66 int error; 67 68 if (!reiserfs_posixacl(inode->i_sb)) 69 return -EOPNOTSUPP; 70 71 acl = reiserfs_get_acl(inode, type); 72 if (IS_ERR(acl)) 73 return PTR_ERR(acl); 74 if (acl == NULL) 75 return -ENODATA; 76 error = posix_acl_to_xattr(acl, buffer, size); 77 posix_acl_release(acl); 78 79 return error; 80} 81 82/* 83 * Convert from filesystem to in-memory representation. 84 */ 85static struct posix_acl *posix_acl_from_disk(const void *value, size_t size) 86{ 87 const char *end = (char *)value + size; 88 int n, count; 89 struct posix_acl *acl; 90 91 if (!value) 92 return NULL; 93 if (size < sizeof(reiserfs_acl_header)) 94 return ERR_PTR(-EINVAL); 95 if (((reiserfs_acl_header *) value)->a_version != 96 cpu_to_le32(REISERFS_ACL_VERSION)) 97 return ERR_PTR(-EINVAL); 98 value = (char *)value + sizeof(reiserfs_acl_header); 99 count = reiserfs_acl_count(size); 100 if (count < 0) 101 return ERR_PTR(-EINVAL); 102 if (count == 0) 103 return NULL; 104 acl = posix_acl_alloc(count, GFP_NOFS); 105 if (!acl) 106 return ERR_PTR(-ENOMEM); 107 for (n = 0; n < count; n++) { 108 reiserfs_acl_entry *entry = (reiserfs_acl_entry *) value; 109 if ((char *)value + sizeof(reiserfs_acl_entry_short) > end) 110 goto fail; 111 acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag); 112 acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm); 113 switch (acl->a_entries[n].e_tag) { 114 case ACL_USER_OBJ: 115 case ACL_GROUP_OBJ: 116 case ACL_MASK: 117 case ACL_OTHER: 118 value = (char *)value + 119 sizeof(reiserfs_acl_entry_short); 120 acl->a_entries[n].e_id = ACL_UNDEFINED_ID; 121 break; 122 123 case ACL_USER: 124 case ACL_GROUP: 125 value = (char *)value + sizeof(reiserfs_acl_entry); 126 if ((char *)value > end) 127 goto fail; 128 acl->a_entries[n].e_id = le32_to_cpu(entry->e_id); 129 break; 130 131 default: 132 goto fail; 133 } 134 } 135 if (value != end) 136 goto fail; 137 return acl; 138 139 fail: 140 posix_acl_release(acl); 141 return ERR_PTR(-EINVAL); 142} 143 144/* 145 * Convert from in-memory to filesystem representation. 146 */ 147static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) 148{ 149 reiserfs_acl_header *ext_acl; 150 char *e; 151 int n; 152 153 *size = reiserfs_acl_size(acl->a_count); 154 ext_acl = kmalloc(sizeof(reiserfs_acl_header) + 155 acl->a_count * 156 sizeof(reiserfs_acl_entry), 157 GFP_NOFS); 158 if (!ext_acl) 159 return ERR_PTR(-ENOMEM); 160 ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION); 161 e = (char *)ext_acl + sizeof(reiserfs_acl_header); 162 for (n = 0; n < acl->a_count; n++) { 163 reiserfs_acl_entry *entry = (reiserfs_acl_entry *) e; 164 entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); 165 entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); 166 switch (acl->a_entries[n].e_tag) { 167 case ACL_USER: 168 case ACL_GROUP: 169 entry->e_id = cpu_to_le32(acl->a_entries[n].e_id); 170 e += sizeof(reiserfs_acl_entry); 171 break; 172 173 case ACL_USER_OBJ: 174 case ACL_GROUP_OBJ: 175 case ACL_MASK: 176 case ACL_OTHER: 177 e += sizeof(reiserfs_acl_entry_short); 178 break; 179 180 default: 181 goto fail; 182 } 183 } 184 return (char *)ext_acl; 185 186 fail: 187 kfree(ext_acl); 188 return ERR_PTR(-EINVAL); 189} 190 191static inline void iset_acl(struct inode *inode, struct posix_acl **i_acl, 192 struct posix_acl *acl) 193{ 194 spin_lock(&inode->i_lock); 195 if (*i_acl != ERR_PTR(-ENODATA)) 196 posix_acl_release(*i_acl); 197 *i_acl = acl ? posix_acl_dup(acl) : ERR_PTR(-ENODATA); 198 spin_unlock(&inode->i_lock); 199} 200 201static inline struct posix_acl *iget_acl(struct inode *inode, 202 struct posix_acl **i_acl) 203{ 204 struct posix_acl *acl = ERR_PTR(-ENODATA); 205 206 spin_lock(&inode->i_lock); 207 if (*i_acl != ERR_PTR(-ENODATA)) 208 acl = posix_acl_dup(*i_acl); 209 spin_unlock(&inode->i_lock); 210 211 return acl; 212} 213 214/* 215 * Inode operation get_posix_acl(). 216 * 217 * inode->i_mutex: down 218 * BKL held [before 2.5.x] 219 */ 220struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) 221{ 222 char *name, *value; 223 struct posix_acl *acl, **p_acl; 224 int size; 225 int retval; 226 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 227 228 switch (type) { 229 case ACL_TYPE_ACCESS: 230 name = POSIX_ACL_XATTR_ACCESS; 231 p_acl = &reiserfs_i->i_acl_access; 232 break; 233 case ACL_TYPE_DEFAULT: 234 name = POSIX_ACL_XATTR_DEFAULT; 235 p_acl = &reiserfs_i->i_acl_default; 236 break; 237 default: 238 return ERR_PTR(-EINVAL); 239 } 240 241 acl = iget_acl(inode, p_acl); 242 if (acl && !IS_ERR(acl)) 243 return acl; 244 else if (PTR_ERR(acl) == -ENODATA) 245 return NULL; 246 247 size = reiserfs_xattr_get(inode, name, NULL, 0); 248 if (size < 0) { 249 if (size == -ENODATA || size == -ENOSYS) { 250 *p_acl = ERR_PTR(-ENODATA); 251 return NULL; 252 } 253 return ERR_PTR(size); 254 } 255 256 value = kmalloc(size, GFP_NOFS); 257 if (!value) 258 return ERR_PTR(-ENOMEM); 259 260 retval = reiserfs_xattr_get(inode, name, value, size); 261 if (retval == -ENODATA || retval == -ENOSYS) { 262 /* This shouldn't actually happen as it should have 263 been caught above.. but just in case */ 264 acl = NULL; 265 *p_acl = ERR_PTR(-ENODATA); 266 } else if (retval < 0) { 267 acl = ERR_PTR(retval); 268 } else { 269 acl = posix_acl_from_disk(value, retval); 270 if (!IS_ERR(acl)) 271 iset_acl(inode, p_acl, acl); 272 } 273 274 kfree(value); 275 return acl; 276} 277 278/* 279 * Inode operation set_posix_acl(). 280 * 281 * inode->i_mutex: down 282 * BKL held [before 2.5.x] 283 */ 284static int 285reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, 286 int type, struct posix_acl *acl) 287{ 288 char *name; 289 void *value = NULL; 290 struct posix_acl **p_acl; 291 size_t size = 0; 292 int error; 293 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 294 295 if (S_ISLNK(inode->i_mode)) 296 return -EOPNOTSUPP; 297 298 switch (type) { 299 case ACL_TYPE_ACCESS: 300 name = POSIX_ACL_XATTR_ACCESS; 301 p_acl = &reiserfs_i->i_acl_access; 302 if (acl) { 303 mode_t mode = inode->i_mode; 304 error = posix_acl_equiv_mode(acl, &mode); 305 if (error < 0) 306 return error; 307 else { 308 inode->i_mode = mode; 309 if (error == 0) 310 acl = NULL; 311 } 312 } 313 break; 314 case ACL_TYPE_DEFAULT: 315 name = POSIX_ACL_XATTR_DEFAULT; 316 p_acl = &reiserfs_i->i_acl_default; 317 if (!S_ISDIR(inode->i_mode)) 318 return acl ? -EACCES : 0; 319 break; 320 default: 321 return -EINVAL; 322 } 323 324 if (acl) { 325 value = posix_acl_to_disk(acl, &size); 326 if (IS_ERR(value)) 327 return (int)PTR_ERR(value); 328 } 329 330 error = reiserfs_xattr_set_handle(th, inode, name, value, size, 0); 331 332 /* 333 * Ensure that the inode gets dirtied if we're only using 334 * the mode bits and an old ACL didn't exist. We don't need 335 * to check if the inode is hashed here since we won't get 336 * called by reiserfs_inherit_default_acl(). 337 */ 338 if (error == -ENODATA) { 339 error = 0; 340 if (type == ACL_TYPE_ACCESS) { 341 inode->i_ctime = CURRENT_TIME_SEC; 342 mark_inode_dirty(inode); 343 } 344 } 345 346 kfree(value); 347 348 if (!error) 349 iset_acl(inode, p_acl, acl); 350 351 return error; 352} 353 354/* dir->i_mutex: locked, 355 * inode is new and not released into the wild yet */ 356int 357reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, 358 struct inode *dir, struct dentry *dentry, 359 struct inode *inode) 360{ 361 struct posix_acl *acl; 362 int err = 0; 363 364 /* ACLs only get applied to files and directories */ 365 if (S_ISLNK(inode->i_mode)) 366 return 0; 367 368 /* ACLs can only be used on "new" objects, so if it's an old object 369 * there is nothing to inherit from */ 370 if (get_inode_sd_version(dir) == STAT_DATA_V1) 371 goto apply_umask; 372 373 /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This 374 * would be useless since permissions are ignored, and a pain because 375 * it introduces locking cycles */ 376 if (IS_PRIVATE(dir)) { 377 inode->i_flags |= S_PRIVATE; 378 goto apply_umask; 379 } 380 381 acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT); 382 if (IS_ERR(acl)) { 383 if (PTR_ERR(acl) == -ENODATA) 384 goto apply_umask; 385 return PTR_ERR(acl); 386 } 387 388 if (acl) { 389 struct posix_acl *acl_copy; 390 mode_t mode = inode->i_mode; 391 int need_acl; 392 393 /* Copy the default ACL to the default ACL of a new directory */ 394 if (S_ISDIR(inode->i_mode)) { 395 err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, 396 acl); 397 if (err) 398 goto cleanup; 399 } 400 401 /* Now we reconcile the new ACL and the mode, 402 potentially modifying both */ 403 acl_copy = posix_acl_clone(acl, GFP_NOFS); 404 if (!acl_copy) { 405 err = -ENOMEM; 406 goto cleanup; 407 } 408 409 need_acl = posix_acl_create_masq(acl_copy, &mode); 410 if (need_acl >= 0) { 411 if (mode != inode->i_mode) { 412 inode->i_mode = mode; 413 } 414 415 /* If we need an ACL.. */ 416 if (need_acl > 0) { 417 err = reiserfs_set_acl(th, inode, 418 ACL_TYPE_ACCESS, 419 acl_copy); 420 if (err) 421 goto cleanup_copy; 422 } 423 } 424 cleanup_copy: 425 posix_acl_release(acl_copy); 426 cleanup: 427 posix_acl_release(acl); 428 } else { 429 apply_umask: 430 /* no ACL, apply umask */ 431 inode->i_mode &= ~current_umask(); 432 } 433 434 return err; 435} 436 437/* This is used to cache the default acl before a new object is created. 438 * The biggest reason for this is to get an idea of how many blocks will 439 * actually be required for the create operation if we must inherit an ACL. 440 * An ACL write can add up to 3 object creations and an additional file write 441 * so we'd prefer not to reserve that many blocks in the journal if we can. 442 * It also has the advantage of not loading the ACL with a transaction open, 443 * this may seem silly, but if the owner of the directory is doing the 444 * creation, the ACL may not be loaded since the permissions wouldn't require 445 * it. 446 * We return the number of blocks required for the transaction. 447 */ 448int reiserfs_cache_default_acl(struct inode *inode) 449{ 450 struct posix_acl *acl; 451 int nblocks = 0; 452 453 if (IS_PRIVATE(inode)) 454 return 0; 455 456 acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); 457 458 if (acl && !IS_ERR(acl)) { 459 int size = reiserfs_acl_size(acl->a_count); 460 461 /* Other xattrs can be created during inode creation. We don't 462 * want to claim too many blocks, so we check to see if we 463 * we need to create the tree to the xattrs, and then we 464 * just want two files. */ 465 nblocks = reiserfs_xattr_jcreate_nblocks(inode); 466 nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); 467 468 REISERFS_I(inode)->i_flags |= i_has_xattr_dir; 469 470 /* We need to account for writes + bitmaps for two files */ 471 nblocks += reiserfs_xattr_nblocks(inode, size) * 4; 472 posix_acl_release(acl); 473 } 474 475 return nblocks; 476} 477 478int reiserfs_acl_chmod(struct inode *inode) 479{ 480 struct posix_acl *acl, *clone; 481 int error; 482 483 if (S_ISLNK(inode->i_mode)) 484 return -EOPNOTSUPP; 485 486 if (get_inode_sd_version(inode) == STAT_DATA_V1 || 487 !reiserfs_posixacl(inode->i_sb)) { 488 return 0; 489 } 490 491 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); 492 if (!acl) 493 return 0; 494 if (IS_ERR(acl)) 495 return PTR_ERR(acl); 496 clone = posix_acl_clone(acl, GFP_NOFS); 497 posix_acl_release(acl); 498 if (!clone) 499 return -ENOMEM; 500 error = posix_acl_chmod_masq(clone, inode->i_mode); 501 if (!error) { 502 struct reiserfs_transaction_handle th; 503 size_t size = reiserfs_xattr_nblocks(inode, 504 reiserfs_acl_size(clone->a_count)); 505 reiserfs_write_lock(inode->i_sb); 506 error = journal_begin(&th, inode->i_sb, size * 2); 507 if (!error) { 508 int error2; 509 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, 510 clone); 511 error2 = journal_end(&th, inode->i_sb, size * 2); 512 if (error2) 513 error = error2; 514 } 515 reiserfs_write_unlock(inode->i_sb); 516 } 517 posix_acl_release(clone); 518 return error; 519} 520 521static int 522posix_acl_access_get(struct inode *inode, const char *name, 523 void *buffer, size_t size) 524{ 525 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) 526 return -EINVAL; 527 return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); 528} 529 530static int 531posix_acl_access_set(struct inode *inode, const char *name, 532 const void *value, size_t size, int flags) 533{ 534 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) 535 return -EINVAL; 536 return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); 537} 538 539static size_t posix_acl_access_list(struct inode *inode, char *list, 540 size_t list_size, const char *name, 541 size_t name_len) 542{ 543 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); 544 if (!reiserfs_posixacl(inode->i_sb)) 545 return 0; 546 if (list && size <= list_size) 547 memcpy(list, POSIX_ACL_XATTR_ACCESS, size); 548 return size; 549} 550 551struct xattr_handler reiserfs_posix_acl_access_handler = { 552 .prefix = POSIX_ACL_XATTR_ACCESS, 553 .get = posix_acl_access_get, 554 .set = posix_acl_access_set, 555 .list = posix_acl_access_list, 556}; 557 558static int 559posix_acl_default_get(struct inode *inode, const char *name, 560 void *buffer, size_t size) 561{ 562 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) 563 return -EINVAL; 564 return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); 565} 566 567static int 568posix_acl_default_set(struct inode *inode, const char *name, 569 const void *value, size_t size, int flags) 570{ 571 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) 572 return -EINVAL; 573 return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); 574} 575 576static size_t posix_acl_default_list(struct inode *inode, char *list, 577 size_t list_size, const char *name, 578 size_t name_len) 579{ 580 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); 581 if (!reiserfs_posixacl(inode->i_sb)) 582 return 0; 583 if (list && size <= list_size) 584 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); 585 return size; 586} 587 588struct xattr_handler reiserfs_posix_acl_default_handler = { 589 .prefix = POSIX_ACL_XATTR_DEFAULT, 590 .get = posix_acl_default_get, 591 .set = posix_acl_default_set, 592 .list = posix_acl_default_list, 593}; 594