1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #ifndef __XFS_ATTR_H__ 7 #define __XFS_ATTR_H__ 8 9 struct xfs_inode; 10 struct xfs_da_args; 11 struct xfs_attr_list_context; 12 13 /* 14 * Large attribute lists are structured around Btrees where all the data 15 * elements are in the leaf nodes. Attribute names are hashed into an int, 16 * then that int is used as the index into the Btree. Since the hashval 17 * of an attribute name may not be unique, we may have duplicate keys. 18 * The internal links in the Btree are logical block offsets into the file. 19 * 20 * Small attribute lists use a different format and are packed as tightly 21 * as possible so as to fit into the literal area of the inode. 22 */ 23 24 /* 25 * The maximum size (into the kernel or returned from the kernel) of an 26 * attribute value or the buffer used for an attr_list() call. Larger 27 * sizes will result in an ERANGE return code. 28 */ 29 #define ATTR_MAX_VALUELEN (64*1024) /* max length of a value */ 30 31 /* 32 * Kernel-internal version of the attrlist cursor. 33 */ 34 struct xfs_attrlist_cursor_kern { 35 __u32 hashval; /* hash value of next entry to add */ 36 __u32 blkno; /* block containing entry (suggestion) */ 37 __u32 offset; /* offset in list of equal-hashvals */ 38 __u16 pad1; /* padding to match user-level */ 39 __u8 pad2; /* padding to match user-level */ 40 __u8 initted; /* T/F: cursor has been initialized */ 41 }; 42 43 44 /*======================================================================== 45 * Structure used to pass context around among the routines. 46 *========================================================================*/ 47 48 49 /* void; state communicated via *context */ 50 typedef void (*put_listent_func_t)(struct xfs_attr_list_context *context, 51 int flags, unsigned char *name, int namelen, void *value, 52 int valuelen); 53 54 struct xfs_attr_list_context { 55 struct xfs_trans *tp; 56 struct xfs_inode *dp; /* inode */ 57 struct xfs_attrlist_cursor_kern cursor; /* position in list */ 58 /* output buffer */ 59 void *buffer __counted_by_ptr(bufsize); 60 61 /* 62 * Abort attribute list iteration if non-zero. Can be used to pass 63 * error values to the xfs_attr_list caller. 64 */ 65 int seen_enough; 66 bool allow_incomplete; 67 68 ssize_t count; /* num used entries */ 69 int dupcnt; /* count dup hashvals seen */ 70 int bufsize; /* total buffer size */ 71 int firstu; /* first used byte in buffer */ 72 unsigned int attr_filter; /* XFS_ATTR_{ROOT,SECURE} */ 73 int resynch; /* T/F: resynch with cursor */ 74 put_listent_func_t put_listent; /* list output fmt function */ 75 int index; /* index into output buffer */ 76 }; 77 78 79 /* 80 * ======================================================================== 81 * Structure used to pass context around among the delayed routines. 82 * ======================================================================== 83 */ 84 85 /* 86 * Below is a state machine diagram for attr remove operations. The XFS_DAS_* 87 * states indicate places where the function would return -EAGAIN, and then 88 * immediately resume from after being called by the calling function. States 89 * marked as a "subroutine state" indicate that they belong to a subroutine, and 90 * so the calling function needs to pass them back to that subroutine to allow 91 * it to finish where it left off. But they otherwise do not have a role in the 92 * calling function other than just passing through. 93 * 94 * xfs_attr_remove_iter() 95 * │ 96 * v 97 * have attr to remove? ──n──> done 98 * │ 99 * y 100 * │ 101 * v 102 * are we short form? ──y──> xfs_attr_shortform_remove ──> done 103 * │ 104 * n 105 * │ 106 * V 107 * are we leaf form? ──y──> xfs_attr_leaf_removename ──> done 108 * │ 109 * n 110 * │ 111 * V 112 * ┌── need to setup state? 113 * │ │ 114 * n y 115 * │ │ 116 * │ v 117 * │ find attr and get state 118 * │ attr has remote blks? ──n─┐ 119 * │ │ v 120 * │ │ find and invalidate 121 * │ y the remote blocks. 122 * │ │ mark attr incomplete 123 * │ ├────────────────┘ 124 * └──────────┤ 125 * │ 126 * v 127 * Have remote blks to remove? ───y─────┐ 128 * │ ^ remove the blks 129 * │ │ │ 130 * │ │ v 131 * │ XFS_DAS_RMTBLK <─n── done? 132 * │ re-enter with │ 133 * │ one less blk to y 134 * │ remove │ 135 * │ V 136 * │ refill the state 137 * n │ 138 * │ v 139 * │ XFS_DAS_RM_NAME 140 * │ │ 141 * ├─────────────────────────┘ 142 * │ 143 * v 144 * remove leaf and 145 * update hash with 146 * xfs_attr_node_remove_cleanup 147 * │ 148 * v 149 * need to 150 * shrink tree? ─n─┐ 151 * │ │ 152 * y │ 153 * │ │ 154 * v │ 155 * join leaf │ 156 * │ │ 157 * v │ 158 * XFS_DAS_RM_SHRINK │ 159 * │ │ 160 * v │ 161 * do the shrink │ 162 * │ │ 163 * v │ 164 * free state <──┘ 165 * │ 166 * v 167 * done 168 * 169 * 170 * Below is a state machine diagram for attr set operations. 171 * 172 * It seems the challenge with understanding this system comes from trying to 173 * absorb the state machine all at once, when really one should only be looking 174 * at it with in the context of a single function. Once a state sensitive 175 * function is called, the idea is that it "takes ownership" of the 176 * state machine. It isn't concerned with the states that may have belonged to 177 * it's calling parent. Only the states relevant to itself or any other 178 * subroutines there in. Once a calling function hands off the state machine to 179 * a subroutine, it needs to respect the simple rule that it doesn't "own" the 180 * state machine anymore, and it's the responsibility of that calling function 181 * to propagate the -EAGAIN back up the call stack. Upon reentry, it is 182 * committed to re-calling that subroutine until it returns something other than 183 * -EAGAIN. Once that subroutine signals completion (by returning anything other 184 * than -EAGAIN), the calling function can resume using the state machine. 185 * 186 * xfs_attr_set_iter() 187 * │ 188 * v 189 * ┌─y─ has an attr fork? 190 * │ | 191 * │ n 192 * │ | 193 * │ V 194 * │ add a fork 195 * │ │ 196 * └──────────┤ 197 * │ 198 * V 199 * ┌─── is shortform? 200 * │ │ 201 * │ y 202 * │ │ 203 * │ V 204 * │ xfs_attr_set_fmt 205 * │ | 206 * │ V 207 * │ xfs_attr_try_sf_addname 208 * │ │ 209 * │ V 210 * │ had enough ──y──> done 211 * │ space? 212 * n │ 213 * │ n 214 * │ │ 215 * │ V 216 * │ transform to leaf 217 * │ │ 218 * │ V 219 * │ hold the leaf buffer 220 * │ │ 221 * │ V 222 * │ return -EAGAIN 223 * │ Re-enter in 224 * │ leaf form 225 * │ 226 * └─> release leaf buffer 227 * if needed 228 * │ 229 * V 230 * ┌───n── fork has 231 * │ only 1 blk? 232 * │ │ 233 * │ y 234 * │ │ 235 * │ v 236 * │ xfs_attr_leaf_try_add() 237 * │ │ 238 * │ v 239 * │ had enough ──────────────y─────────────┐ 240 * │ space? │ 241 * │ │ │ 242 * │ n │ 243 * │ │ │ 244 * │ v │ 245 * │ return -EAGAIN │ 246 * │ re-enter in │ 247 * │ node form │ 248 * │ │ │ 249 * └──────────┤ │ 250 * │ │ 251 * V │ 252 * xfs_attr_node_addname_find_attr │ 253 * determines if this │ 254 * is create or rename │ 255 * find space to store attr │ 256 * │ │ 257 * v │ 258 * xfs_attr_node_addname │ 259 * │ │ 260 * v │ 261 * fits in a node leaf? ────n─────┐ │ 262 * │ ^ v │ 263 * │ │ single leaf node? │ 264 * │ │ │ │ │ 265 * y │ y n │ 266 * │ │ │ │ │ 267 * v │ v v │ 268 * update │ grow the leaf split if │ 269 * hashvals └── return -EAGAIN needed │ 270 * │ retry leaf add │ │ 271 * │ on reentry │ │ 272 * ├────────────────────────────┘ │ 273 * │ │ 274 * v │ 275 * need to alloc │ 276 * ┌─y── or flip flag? │ 277 * │ │ │ 278 * │ n │ 279 * │ │ │ 280 * │ v │ 281 * │ done │ 282 * │ │ 283 * │ │ 284 * │ XFS_DAS_FOUND_LBLK <────────────────┘ 285 * │ │ 286 * │ V 287 * │ xfs_attr_leaf_addname() 288 * │ │ 289 * │ v 290 * │ ┌──first time through? 291 * │ │ │ 292 * │ │ y 293 * │ │ │ 294 * │ n v 295 * │ │ if we have rmt blks 296 * │ │ find space for them 297 * │ │ │ 298 * │ └──────────┤ 299 * │ │ 300 * │ v 301 * │ still have 302 * │ ┌─n─ blks to alloc? <──┐ 303 * │ │ │ │ 304 * │ │ y │ 305 * │ │ │ │ 306 * │ │ v │ 307 * │ │ alloc one blk │ 308 * │ │ return -EAGAIN ──┘ 309 * │ │ re-enter with one 310 * │ │ less blk to alloc 311 * │ │ 312 * │ │ 313 * │ └───> set the rmt 314 * │ value 315 * │ │ 316 * │ v 317 * │ was this 318 * │ a rename? ──n─┐ 319 * │ │ │ 320 * │ y │ 321 * │ │ │ 322 * │ v │ 323 * │ flip incomplete │ 324 * │ flag │ 325 * │ │ │ 326 * │ v │ 327 * │ XFS_DAS_FLIP_LFLAG │ 328 * │ │ │ 329 * │ v │ 330 * │ need to remove │ 331 * │ old bks? ──n──┤ 332 * │ │ │ 333 * │ y │ 334 * │ │ │ 335 * │ V │ 336 * │ remove │ 337 * │ ┌───> old blks │ 338 * │ │ │ │ 339 * │ XFS_DAS_RM_LBLK │ │ 340 * │ ^ │ │ 341 * │ │ v │ 342 * │ └──y── more to │ 343 * │ remove? │ 344 * │ │ │ 345 * │ n │ 346 * │ │ │ 347 * │ v │ 348 * │ XFS_DAS_RD_LEAF │ 349 * │ │ │ 350 * │ v │ 351 * │ remove leaf │ 352 * │ │ │ 353 * │ v │ 354 * │ shrink to sf │ 355 * │ if needed │ 356 * │ │ │ 357 * │ v │ 358 * │ done <──────┘ 359 * │ 360 * └──────> XFS_DAS_FOUND_NBLK 361 * │ 362 * v 363 * ┌─────n── need to 364 * │ alloc blks? 365 * │ │ 366 * │ y 367 * │ │ 368 * │ v 369 * │ find space 370 * │ │ 371 * │ v 372 * │ ┌─>XFS_DAS_ALLOC_NODE 373 * │ │ │ 374 * │ │ v 375 * │ │ alloc blk 376 * │ │ │ 377 * │ │ v 378 * │ └──y── need to alloc 379 * │ more blocks? 380 * │ │ 381 * │ n 382 * │ │ 383 * │ v 384 * │ set the rmt value 385 * │ │ 386 * │ v 387 * │ was this 388 * └────────> a rename? ──n─┐ 389 * │ │ 390 * y │ 391 * │ │ 392 * v │ 393 * flip incomplete │ 394 * flag │ 395 * │ │ 396 * v │ 397 * XFS_DAS_FLIP_NFLAG │ 398 * │ │ 399 * v │ 400 * need to │ 401 * remove blks? ─n──┤ 402 * │ │ 403 * y │ 404 * │ │ 405 * v │ 406 * remove │ 407 * ┌────────> old blks │ 408 * │ │ │ 409 * XFS_DAS_RM_NBLK │ │ 410 * ^ │ │ 411 * │ v │ 412 * └──────y── more to │ 413 * remove │ 414 * │ │ 415 * n │ 416 * │ │ 417 * v │ 418 * XFS_DAS_CLR_FLAG │ 419 * │ │ 420 * v │ 421 * clear flags │ 422 * │ │ 423 * ├──────────┘ 424 * │ 425 * v 426 * done 427 */ 428 429 /* 430 * Enum values for xfs_attr_intent.xattri_da_state 431 * 432 * These values are used by delayed attribute operations to keep track of where 433 * they were before they returned -EAGAIN. A return code of -EAGAIN signals the 434 * calling function to roll the transaction, and then call the subroutine to 435 * finish the operation. The enum is then used by the subroutine to jump back 436 * to where it was and resume executing where it left off. 437 */ 438 enum xfs_delattr_state { 439 XFS_DAS_UNINIT = 0, /* No state has been set yet */ 440 441 /* 442 * Initial sequence states. The replace setup code relies on the 443 * ADD and REMOVE states for a specific format to be sequential so 444 * that we can transform the initial operation to be performed 445 * according to the xfs_has_larp() state easily. 446 */ 447 XFS_DAS_SF_ADD, /* Initial sf add state */ 448 XFS_DAS_SF_REMOVE, /* Initial sf replace/remove state */ 449 450 XFS_DAS_LEAF_ADD, /* Initial leaf add state */ 451 XFS_DAS_LEAF_REMOVE, /* Initial leaf replace/remove state */ 452 453 XFS_DAS_NODE_ADD, /* Initial node add state */ 454 XFS_DAS_NODE_REMOVE, /* Initial node replace/remove state */ 455 456 /* Leaf state set/replace/remove sequence */ 457 XFS_DAS_LEAF_SET_RMT, /* set a remote xattr from a leaf */ 458 XFS_DAS_LEAF_ALLOC_RMT, /* We are allocating remote blocks */ 459 XFS_DAS_LEAF_REPLACE, /* Perform replace ops on a leaf */ 460 XFS_DAS_LEAF_REMOVE_OLD, /* Start removing old attr from leaf */ 461 XFS_DAS_LEAF_REMOVE_RMT, /* A rename is removing remote blocks */ 462 XFS_DAS_LEAF_REMOVE_ATTR, /* Remove the old attr from a leaf */ 463 464 /* Node state sequence, must match leaf state above */ 465 XFS_DAS_NODE_SET_RMT, /* set a remote xattr from a node */ 466 XFS_DAS_NODE_ALLOC_RMT, /* We are allocating remote blocks */ 467 XFS_DAS_NODE_REPLACE, /* Perform replace ops on a node */ 468 XFS_DAS_NODE_REMOVE_OLD, /* Start removing old attr from node */ 469 XFS_DAS_NODE_REMOVE_RMT, /* A rename is removing remote blocks */ 470 XFS_DAS_NODE_REMOVE_ATTR, /* Remove the old attr from a node */ 471 472 XFS_DAS_DONE, /* finished operation */ 473 }; 474 475 #define XFS_DAS_STRINGS \ 476 { XFS_DAS_UNINIT, "XFS_DAS_UNINIT" }, \ 477 { XFS_DAS_SF_ADD, "XFS_DAS_SF_ADD" }, \ 478 { XFS_DAS_SF_REMOVE, "XFS_DAS_SF_REMOVE" }, \ 479 { XFS_DAS_LEAF_ADD, "XFS_DAS_LEAF_ADD" }, \ 480 { XFS_DAS_LEAF_REMOVE, "XFS_DAS_LEAF_REMOVE" }, \ 481 { XFS_DAS_NODE_ADD, "XFS_DAS_NODE_ADD" }, \ 482 { XFS_DAS_NODE_REMOVE, "XFS_DAS_NODE_REMOVE" }, \ 483 { XFS_DAS_LEAF_SET_RMT, "XFS_DAS_LEAF_SET_RMT" }, \ 484 { XFS_DAS_LEAF_ALLOC_RMT, "XFS_DAS_LEAF_ALLOC_RMT" }, \ 485 { XFS_DAS_LEAF_REPLACE, "XFS_DAS_LEAF_REPLACE" }, \ 486 { XFS_DAS_LEAF_REMOVE_OLD, "XFS_DAS_LEAF_REMOVE_OLD" }, \ 487 { XFS_DAS_LEAF_REMOVE_RMT, "XFS_DAS_LEAF_REMOVE_RMT" }, \ 488 { XFS_DAS_LEAF_REMOVE_ATTR, "XFS_DAS_LEAF_REMOVE_ATTR" }, \ 489 { XFS_DAS_NODE_SET_RMT, "XFS_DAS_NODE_SET_RMT" }, \ 490 { XFS_DAS_NODE_ALLOC_RMT, "XFS_DAS_NODE_ALLOC_RMT" }, \ 491 { XFS_DAS_NODE_REPLACE, "XFS_DAS_NODE_REPLACE" }, \ 492 { XFS_DAS_NODE_REMOVE_OLD, "XFS_DAS_NODE_REMOVE_OLD" }, \ 493 { XFS_DAS_NODE_REMOVE_RMT, "XFS_DAS_NODE_REMOVE_RMT" }, \ 494 { XFS_DAS_NODE_REMOVE_ATTR, "XFS_DAS_NODE_REMOVE_ATTR" }, \ 495 { XFS_DAS_DONE, "XFS_DAS_DONE" } 496 497 struct xfs_attri_log_nameval; 498 499 /* 500 * Context used for keeping track of delayed attribute operations 501 */ 502 struct xfs_attr_intent { 503 /* 504 * used to log this item to an intent containing a list of attrs to 505 * commit later 506 */ 507 struct list_head xattri_list; 508 509 /* Used in xfs_attr_node_removename to roll through removing blocks */ 510 struct xfs_da_state *xattri_da_state; 511 512 struct xfs_da_args *xattri_da_args; 513 514 /* 515 * Shared buffer containing the attr name, new name, and value so that 516 * the logging code can share large memory buffers between log items. 517 */ 518 struct xfs_attri_log_nameval *xattri_nameval; 519 520 /* Used to keep track of current state of delayed operation */ 521 enum xfs_delattr_state xattri_dela_state; 522 523 /* 524 * Attr operation being performed - XFS_ATTRI_OP_FLAGS_* 525 */ 526 unsigned int xattri_op_flags; 527 528 /* Used in xfs_attr_rmtval_set_blk to roll through allocating blocks */ 529 xfs_dablk_t xattri_lblkno; 530 int xattri_blkcnt; 531 struct xfs_bmbt_irec xattri_map; 532 }; 533 534 static inline unsigned int 535 xfs_attr_intent_op(const struct xfs_attr_intent *attr) 536 { 537 return attr->xattri_op_flags & XFS_ATTRI_OP_FLAGS_TYPE_MASK; 538 } 539 540 /*======================================================================== 541 * Function prototypes for the kernel. 542 *========================================================================*/ 543 544 /* 545 * Overall external interface routines. 546 */ 547 int xfs_attr_inactive(struct xfs_inode *dp); 548 int xfs_attr_list_ilocked(struct xfs_attr_list_context *); 549 int xfs_attr_list(struct xfs_attr_list_context *); 550 int xfs_inode_hasattr(struct xfs_inode *ip); 551 bool xfs_attr_is_leaf(struct xfs_inode *ip); 552 int xfs_attr_get_ilocked(struct xfs_da_args *args); 553 int xfs_attr_get(struct xfs_da_args *args); 554 555 enum xfs_attr_update { 556 XFS_ATTRUPDATE_REMOVE, /* remove attr */ 557 XFS_ATTRUPDATE_UPSERT, /* set value, replace any existing attr */ 558 XFS_ATTRUPDATE_CREATE, /* set value, fail if attr already exists */ 559 XFS_ATTRUPDATE_REPLACE, /* set value, fail if attr does not exist */ 560 }; 561 562 int xfs_attr_set(struct xfs_da_args *args, enum xfs_attr_update op, bool rsvd); 563 int xfs_attr_set_iter(struct xfs_attr_intent *attr); 564 int xfs_attr_remove_iter(struct xfs_attr_intent *attr); 565 bool xfs_attr_check_namespace(unsigned int attr_flags); 566 bool xfs_attr_namecheck(unsigned int attr_flags, const void *name, 567 size_t length); 568 int xfs_attr_calc_size(struct xfs_da_args *args, int *local); 569 struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args); 570 571 /* 572 * Check to see if the attr should be upgraded from non-existent or shortform to 573 * single-leaf-block attribute list. 574 */ 575 static inline bool 576 xfs_attr_is_shortform( 577 const struct xfs_inode *ip) 578 { 579 return ip->i_af.if_format == XFS_DINODE_FMT_LOCAL || 580 (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS && 581 ip->i_af.if_nextents == 0); 582 } 583 584 static inline enum xfs_delattr_state 585 xfs_attr_init_add_state(struct xfs_da_args *args) 586 { 587 /* 588 * When called from the completion of a attr remove to determine the 589 * next state, the attribute fork may be null. This can occur only occur 590 * on a pure remove, but we grab the next state before we check if a 591 * replace operation is being performed. If we are called from any other 592 * context, i_af is guaranteed to exist. Hence if the attr fork is 593 * null, we were called from a pure remove operation and so we are done. 594 */ 595 if (!xfs_inode_has_attr_fork(args->dp)) 596 return XFS_DAS_DONE; 597 598 args->op_flags |= XFS_DA_OP_ADDNAME; 599 if (xfs_attr_is_shortform(args->dp)) 600 return XFS_DAS_SF_ADD; 601 if (xfs_attr_is_leaf(args->dp)) 602 return XFS_DAS_LEAF_ADD; 603 return XFS_DAS_NODE_ADD; 604 } 605 606 static inline enum xfs_delattr_state 607 xfs_attr_init_remove_state(struct xfs_da_args *args) 608 { 609 if (xfs_attr_is_shortform(args->dp)) 610 return XFS_DAS_SF_REMOVE; 611 if (xfs_attr_is_leaf(args->dp)) 612 return XFS_DAS_LEAF_REMOVE; 613 return XFS_DAS_NODE_REMOVE; 614 } 615 616 /* 617 * If we are logging the attributes, then we have to start with removal of the 618 * old attribute so that there is always consistent state that we can recover 619 * from if the system goes down part way through. We always log the new attr 620 * value, so even when we remove the attr first we still have the information in 621 * the log to finish the replace operation atomically. 622 */ 623 static inline enum xfs_delattr_state 624 xfs_attr_init_replace_state(struct xfs_da_args *args) 625 { 626 args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE; 627 if (args->op_flags & XFS_DA_OP_LOGGED) 628 return xfs_attr_init_remove_state(args); 629 return xfs_attr_init_add_state(args); 630 } 631 632 xfs_dahash_t xfs_attr_hashname(const uint8_t *name, int namelen); 633 634 xfs_dahash_t xfs_attr_hashval(struct xfs_mount *mp, unsigned int attr_flags, 635 const uint8_t *name, int namelen, const void *value, 636 int valuelen); 637 638 /* Set the hash value for any extended attribute from any namespace. */ 639 static inline void xfs_attr_sethash(struct xfs_da_args *args) 640 { 641 args->hashval = xfs_attr_hashval(args->dp->i_mount, args->attr_filter, 642 args->name, args->namelen, 643 args->value, args->valuelen); 644 } 645 646 extern struct kmem_cache *xfs_attr_intent_cache; 647 int __init xfs_attr_intent_init_cache(void); 648 void xfs_attr_intent_destroy_cache(void); 649 650 int xfs_attr_sf_totsize(struct xfs_inode *dp); 651 int xfs_attr_add_fork(struct xfs_inode *ip, int size, int rsvd); 652 653 int xfs_attr_setname(struct xfs_da_args *args, int rmt_blks); 654 int xfs_attr_removename(struct xfs_da_args *args); 655 int xfs_attr_replacename(struct xfs_da_args *args, int rmt_blks); 656 657 #endif /* __XFS_ATTR_H__ */ 658