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