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