1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6 #include "xfs_platform.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_mount.h"
13 #include "xfs_defer.h"
14 #include "xfs_da_format.h"
15 #include "xfs_da_btree.h"
16 #include "xfs_attr_sf.h"
17 #include "xfs_inode.h"
18 #include "xfs_trans.h"
19 #include "xfs_bmap.h"
20 #include "xfs_bmap_btree.h"
21 #include "xfs_attr.h"
22 #include "xfs_attr_leaf.h"
23 #include "xfs_attr_remote.h"
24 #include "xfs_quota.h"
25 #include "xfs_trans_space.h"
26 #include "xfs_trace.h"
27 #include "xfs_attr_item.h"
28 #include "xfs_xattr.h"
29 #include "xfs_parent.h"
30
31 struct kmem_cache *xfs_attr_intent_cache;
32
33 /*
34 * xfs_attr.c
35 *
36 * Provide the external interfaces to manage attribute lists.
37 */
38
39 /*========================================================================
40 * Function prototypes for the kernel.
41 *========================================================================*/
42
43 /*
44 * Internal routines when attribute list fits inside the inode.
45 */
46 STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
47
48 /*
49 * Internal routines when attribute list is one block.
50 */
51 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
52 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
53
54 /*
55 * Internal routines when attribute list is more than one block.
56 */
57 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
58 STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
59 static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
60 STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
61 STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
62 STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
63 struct xfs_da_state *state);
64
65 int
xfs_inode_hasattr(struct xfs_inode * ip)66 xfs_inode_hasattr(
67 struct xfs_inode *ip)
68 {
69 if (!xfs_inode_has_attr_fork(ip))
70 return 0;
71 if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
72 ip->i_af.if_nextents == 0)
73 return 0;
74 return 1;
75 }
76
77 /*
78 * Returns true if the there is exactly only block in the attr fork, in which
79 * case the attribute fork consists of a single leaf block entry.
80 */
81 bool
xfs_attr_is_leaf(struct xfs_inode * ip)82 xfs_attr_is_leaf(
83 struct xfs_inode *ip)
84 {
85 struct xfs_ifork *ifp = &ip->i_af;
86 struct xfs_iext_cursor icur;
87 struct xfs_bmbt_irec imap;
88
89 ASSERT(!xfs_need_iread_extents(ifp));
90
91 if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
92 return false;
93
94 xfs_iext_first(ifp, &icur);
95 xfs_iext_get_extent(ifp, &icur, &imap);
96 return imap.br_startoff == 0 && imap.br_blockcount == 1;
97 }
98
99 /*
100 * XXX (dchinner): name path state saving and refilling is an optimisation to
101 * avoid needing to look up name entries after rolling transactions removing
102 * remote xattr blocks between the name entry lookup and name entry removal.
103 * This optimisation got sidelined when combining the set and remove state
104 * machines, but the code has been left in place because it is worthwhile to
105 * restore the optimisation once the combined state machine paths have settled.
106 *
107 * This comment is a public service announcement to remind Future Dave that he
108 * still needs to restore this code to working order.
109 */
110 #if 0
111 /*
112 * Fill in the disk block numbers in the state structure for the buffers
113 * that are attached to the state structure.
114 * This is done so that we can quickly reattach ourselves to those buffers
115 * after some set of transaction commits have released these buffers.
116 */
117 static int
118 xfs_attr_fillstate(xfs_da_state_t *state)
119 {
120 xfs_da_state_path_t *path;
121 xfs_da_state_blk_t *blk;
122 int level;
123
124 trace_xfs_attr_fillstate(state->args);
125
126 /*
127 * Roll down the "path" in the state structure, storing the on-disk
128 * block number for those buffers in the "path".
129 */
130 path = &state->path;
131 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
132 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
133 if (blk->bp) {
134 blk->disk_blkno = xfs_buf_daddr(blk->bp);
135 blk->bp = NULL;
136 } else {
137 blk->disk_blkno = 0;
138 }
139 }
140
141 /*
142 * Roll down the "altpath" in the state structure, storing the on-disk
143 * block number for those buffers in the "altpath".
144 */
145 path = &state->altpath;
146 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
147 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
148 if (blk->bp) {
149 blk->disk_blkno = xfs_buf_daddr(blk->bp);
150 blk->bp = NULL;
151 } else {
152 blk->disk_blkno = 0;
153 }
154 }
155
156 return 0;
157 }
158
159 /*
160 * Reattach the buffers to the state structure based on the disk block
161 * numbers stored in the state structure.
162 * This is done after some set of transaction commits have released those
163 * buffers from our grip.
164 */
165 static int
166 xfs_attr_refillstate(xfs_da_state_t *state)
167 {
168 xfs_da_state_path_t *path;
169 xfs_da_state_blk_t *blk;
170 int level, error;
171
172 trace_xfs_attr_refillstate(state->args);
173
174 /*
175 * Roll down the "path" in the state structure, storing the on-disk
176 * block number for those buffers in the "path".
177 */
178 path = &state->path;
179 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
180 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
181 if (blk->disk_blkno) {
182 error = xfs_da3_node_read_mapped(state->args->trans,
183 state->args->dp, blk->disk_blkno,
184 &blk->bp, XFS_ATTR_FORK);
185 if (error)
186 return error;
187 } else {
188 blk->bp = NULL;
189 }
190 }
191
192 /*
193 * Roll down the "altpath" in the state structure, storing the on-disk
194 * block number for those buffers in the "altpath".
195 */
196 path = &state->altpath;
197 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
198 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
199 if (blk->disk_blkno) {
200 error = xfs_da3_node_read_mapped(state->args->trans,
201 state->args->dp, blk->disk_blkno,
202 &blk->bp, XFS_ATTR_FORK);
203 if (error)
204 return error;
205 } else {
206 blk->bp = NULL;
207 }
208 }
209
210 return 0;
211 }
212 #else
xfs_attr_fillstate(xfs_da_state_t * state)213 static int xfs_attr_fillstate(xfs_da_state_t *state) { return 0; }
214 #endif
215
216 /*========================================================================
217 * Overall external interface routines.
218 *========================================================================*/
219
220 /*
221 * Retrieve an extended attribute and its value. Must have ilock.
222 * Returns 0 on successful retrieval, otherwise an error.
223 */
224 int
xfs_attr_get_ilocked(struct xfs_da_args * args)225 xfs_attr_get_ilocked(
226 struct xfs_da_args *args)
227 {
228 int error;
229
230 xfs_assert_ilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
231
232 if (!xfs_inode_hasattr(args->dp))
233 return -ENOATTR;
234
235 /*
236 * The incore attr fork iext tree must be loaded for xfs_attr_is_leaf
237 * to work correctly.
238 */
239 error = xfs_iread_extents(args->trans, args->dp, XFS_ATTR_FORK);
240 if (error)
241 return error;
242
243 if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
244 return xfs_attr_shortform_getvalue(args);
245 if (xfs_attr_is_leaf(args->dp))
246 return xfs_attr_leaf_get(args);
247 return xfs_attr_node_get(args);
248 }
249
250 /*
251 * Retrieve an extended attribute by name, and its value if requested.
252 *
253 * If args->valuelen is zero, then the caller does not want the value, just an
254 * indication whether the attribute exists and the size of the value if it
255 * exists. The size is returned in args.valuelen.
256 *
257 * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
258 * for the value after existence of the attribute has been determined. The
259 * caller always has to free args->value if it is set, no matter if this
260 * function was successful or not.
261 *
262 * If the attribute is found, but exceeds the size limit set by the caller in
263 * args->valuelen, return -ERANGE with the size of the attribute that was found
264 * in args->valuelen.
265 */
266 int
xfs_attr_get(struct xfs_da_args * args)267 xfs_attr_get(
268 struct xfs_da_args *args)
269 {
270 uint lock_mode;
271 int error;
272
273 XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
274
275 if (xfs_is_shutdown(args->dp->i_mount))
276 return -EIO;
277
278 if (!args->owner)
279 args->owner = args->dp->i_ino;
280 args->geo = args->dp->i_mount->m_attr_geo;
281 args->whichfork = XFS_ATTR_FORK;
282 xfs_attr_sethash(args);
283
284 /* Entirely possible to look up a name which doesn't exist */
285 args->op_flags = XFS_DA_OP_OKNOENT;
286
287 lock_mode = xfs_ilock_attr_map_shared(args->dp);
288 error = xfs_attr_get_ilocked(args);
289 xfs_iunlock(args->dp, lock_mode);
290
291 return error;
292 }
293
294 /*
295 * Calculate how many blocks we need for the new attribute,
296 */
297 int
xfs_attr_calc_size(struct xfs_da_args * args,int * local)298 xfs_attr_calc_size(
299 struct xfs_da_args *args,
300 int *local)
301 {
302 struct xfs_mount *mp = args->dp->i_mount;
303 int size;
304 int nblks;
305
306 /*
307 * Determine space new attribute will use, and if it would be
308 * "local" or "remote" (note: local != inline).
309 */
310 size = xfs_attr_leaf_newentsize(args, local);
311 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
312 if (*local) {
313 if (size > (args->geo->blksize / 2)) {
314 /* Double split possible */
315 nblks *= 2;
316 }
317 } else {
318 /*
319 * Out of line attribute, cannot double split, but
320 * make room for the attribute value itself.
321 */
322 uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
323 nblks += dblocks;
324 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
325 }
326
327 return nblks;
328 }
329
330 /* Initialize transaction reservation for an xattr set/replace/upsert */
331 inline struct xfs_trans_res
xfs_attr_set_resv(const struct xfs_da_args * args)332 xfs_attr_set_resv(
333 const struct xfs_da_args *args)
334 {
335 struct xfs_mount *mp = args->dp->i_mount;
336 struct xfs_trans_res ret = {
337 .tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
338 M_RES(mp)->tr_attrsetrt.tr_logres * args->total,
339 .tr_logcount = XFS_ATTRSET_LOG_COUNT,
340 .tr_logflags = XFS_TRANS_PERM_LOG_RES,
341 };
342
343 return ret;
344 }
345
346 /*
347 * Add an attr to a shortform fork. If there is no space,
348 * xfs_attr_shortform_addname() will convert to leaf format and return -ENOSPC.
349 * to use.
350 */
351 STATIC int
xfs_attr_try_sf_addname(struct xfs_da_args * args)352 xfs_attr_try_sf_addname(
353 struct xfs_da_args *args)
354 {
355 int error;
356
357 /*
358 * Build initial attribute list (if required).
359 */
360 if (args->dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
361 xfs_attr_shortform_create(args);
362
363 error = xfs_attr_shortform_addname(args);
364 if (error == -ENOSPC)
365 return error;
366
367 /*
368 * Commit the shortform mods, and we're done.
369 * NOTE: this is also the error path (EEXIST, etc).
370 */
371 if (!error)
372 xfs_trans_ichgtime(args->trans, args->dp, XFS_ICHGTIME_CHG);
373
374 if (xfs_has_wsync(args->dp->i_mount))
375 xfs_trans_set_sync(args->trans);
376
377 return error;
378 }
379
380 static int
xfs_attr_sf_addname(struct xfs_attr_intent * attr)381 xfs_attr_sf_addname(
382 struct xfs_attr_intent *attr)
383 {
384 struct xfs_da_args *args = attr->xattri_da_args;
385 int error = 0;
386
387 error = xfs_attr_try_sf_addname(args);
388 if (error != -ENOSPC) {
389 ASSERT(!error || error == -EEXIST);
390 attr->xattri_dela_state = XFS_DAS_DONE;
391 goto out;
392 }
393
394 /*
395 * It won't fit in the shortform, transform to a leaf block. GROT:
396 * another possible req'mt for a double-split btree op.
397 */
398 error = xfs_attr_shortform_to_leaf(args);
399 if (error)
400 return error;
401
402 attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
403 out:
404 trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
405 return error;
406 }
407
408 /* Compute the hash value for a user/root/secure extended attribute */
409 xfs_dahash_t
xfs_attr_hashname(const uint8_t * name,int namelen)410 xfs_attr_hashname(
411 const uint8_t *name,
412 int namelen)
413 {
414 return xfs_da_hashname(name, namelen);
415 }
416
417 /* Compute the hash value for any extended attribute from any namespace. */
418 xfs_dahash_t
xfs_attr_hashval(struct xfs_mount * mp,unsigned int attr_flags,const uint8_t * name,int namelen,const void * value,int valuelen)419 xfs_attr_hashval(
420 struct xfs_mount *mp,
421 unsigned int attr_flags,
422 const uint8_t *name,
423 int namelen,
424 const void *value,
425 int valuelen)
426 {
427 ASSERT(xfs_attr_check_namespace(attr_flags));
428
429 if (attr_flags & XFS_ATTR_PARENT)
430 return xfs_parent_hashattr(mp, name, namelen, value, valuelen);
431
432 return xfs_attr_hashname(name, namelen);
433 }
434
435 /* Save the current remote block info and clear the current pointers. */
436 static void
xfs_attr_save_rmt_blk(struct xfs_da_args * args)437 xfs_attr_save_rmt_blk(
438 struct xfs_da_args *args)
439 {
440 args->blkno2 = args->blkno;
441 args->index2 = args->index;
442 args->rmtblkno2 = args->rmtblkno;
443 args->rmtblkcnt2 = args->rmtblkcnt;
444 args->rmtvaluelen2 = args->rmtvaluelen;
445 args->rmtblkno = 0;
446 args->rmtblkcnt = 0;
447 args->rmtvaluelen = 0;
448 }
449
450 /* Set stored info about a remote block */
451 static void
xfs_attr_restore_rmt_blk(struct xfs_da_args * args)452 xfs_attr_restore_rmt_blk(
453 struct xfs_da_args *args)
454 {
455 args->blkno = args->blkno2;
456 args->index = args->index2;
457 args->rmtblkno = args->rmtblkno2;
458 args->rmtblkcnt = args->rmtblkcnt2;
459 args->rmtvaluelen = args->rmtvaluelen2;
460 }
461
462 /*
463 * PPTR_REPLACE operations require the caller to set the old and new names and
464 * values explicitly. Update the canonical fields to the new name and value
465 * here now that the removal phase has finished.
466 */
467 static void
xfs_attr_update_pptr_replace_args(struct xfs_da_args * args)468 xfs_attr_update_pptr_replace_args(
469 struct xfs_da_args *args)
470 {
471 ASSERT(args->new_namelen > 0);
472 args->name = args->new_name;
473 args->namelen = args->new_namelen;
474 args->value = args->new_value;
475 args->valuelen = args->new_valuelen;
476 xfs_attr_sethash(args);
477 }
478
479 /*
480 * Handle the state change on completion of a multi-state attr operation.
481 *
482 * If the XFS_DA_OP_REPLACE flag is set, this means the operation was the first
483 * modification in a attr replace operation and we still have to do the second
484 * state, indicated by @replace_state.
485 *
486 * We consume the XFS_DA_OP_REPLACE flag so that when we are called again on
487 * completion of the second half of the attr replace operation we correctly
488 * signal that it is done.
489 */
490 static enum xfs_delattr_state
xfs_attr_complete_op(struct xfs_attr_intent * attr,enum xfs_delattr_state replace_state)491 xfs_attr_complete_op(
492 struct xfs_attr_intent *attr,
493 enum xfs_delattr_state replace_state)
494 {
495 struct xfs_da_args *args = attr->xattri_da_args;
496
497 if (!(args->op_flags & XFS_DA_OP_REPLACE))
498 replace_state = XFS_DAS_DONE;
499 else if (xfs_attr_intent_op(attr) == XFS_ATTRI_OP_FLAGS_PPTR_REPLACE)
500 xfs_attr_update_pptr_replace_args(args);
501
502 args->op_flags &= ~XFS_DA_OP_REPLACE;
503 args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
504 return replace_state;
505 }
506
507 /*
508 * Try to add an attribute to an inode in leaf form.
509 */
510 static int
xfs_attr_leaf_addname(struct xfs_attr_intent * attr)511 xfs_attr_leaf_addname(
512 struct xfs_attr_intent *attr)
513 {
514 struct xfs_da_args *args = attr->xattri_da_args;
515 struct xfs_buf *bp;
516 int error;
517
518 ASSERT(xfs_attr_is_leaf(args->dp));
519
520 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
521 if (error)
522 return error;
523
524 /*
525 * Look up the xattr name to set the insertion point for the new xattr.
526 */
527 error = xfs_attr3_leaf_lookup_int(bp, args);
528 switch (error) {
529 case -ENOATTR:
530 if (args->op_flags & XFS_DA_OP_REPLACE)
531 goto out_brelse;
532 break;
533 case -EEXIST:
534 if (!(args->op_flags & XFS_DA_OP_REPLACE))
535 goto out_brelse;
536
537 trace_xfs_attr_leaf_replace(args);
538 /*
539 * Save the existing remote attr state so that the current
540 * values reflect the state of the new attribute we are about to
541 * add, not the attribute we just found and will remove later.
542 */
543 xfs_attr_save_rmt_blk(args);
544 break;
545 case 0:
546 break;
547 default:
548 goto out_brelse;
549 }
550
551 /*
552 * We need to commit and roll if we need to allocate remote xattr blocks
553 * or perform more xattr manipulations. Otherwise there is nothing more
554 * to do and we can return success.
555 */
556 if (!xfs_attr3_leaf_add(bp, args)) {
557 error = xfs_attr3_leaf_to_node(args);
558 if (error)
559 return error;
560
561 attr->xattri_dela_state = XFS_DAS_NODE_ADD;
562 } else if (args->rmtblkno) {
563 attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
564 } else {
565 attr->xattri_dela_state =
566 xfs_attr_complete_op(attr, XFS_DAS_LEAF_REPLACE);
567 }
568
569 trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
570 return 0;
571
572 out_brelse:
573 xfs_trans_brelse(args->trans, bp);
574 return error;
575 }
576
577 /*
578 * Add an entry to a node format attr tree.
579 *
580 * Note that we might still have a leaf here - xfs_attr_is_leaf() cannot tell
581 * the difference between leaf + remote attr blocks and a node format tree,
582 * so we may still end up having to convert from leaf to node format here.
583 */
584 static int
xfs_attr_node_addname(struct xfs_attr_intent * attr)585 xfs_attr_node_addname(
586 struct xfs_attr_intent *attr)
587 {
588 struct xfs_da_args *args = attr->xattri_da_args;
589 int error;
590
591 error = xfs_attr_node_addname_find_attr(attr);
592 if (error)
593 return error;
594
595 error = xfs_attr_node_try_addname(attr);
596 if (error == 1) {
597 error = xfs_attr3_leaf_to_node(args);
598 if (error)
599 return error;
600 /*
601 * No state change, we really are in node form now
602 * but we need the transaction rolled to continue.
603 */
604 goto out;
605 }
606 if (error)
607 return error;
608
609 if (args->rmtblkno)
610 attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
611 else
612 attr->xattri_dela_state = xfs_attr_complete_op(attr,
613 XFS_DAS_NODE_REPLACE);
614 out:
615 trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
616 return error;
617 }
618
619 static int
xfs_attr_rmtval_alloc(struct xfs_attr_intent * attr)620 xfs_attr_rmtval_alloc(
621 struct xfs_attr_intent *attr)
622 {
623 struct xfs_da_args *args = attr->xattri_da_args;
624 int error = 0;
625
626 /*
627 * If there was an out-of-line value, allocate the blocks we
628 * identified for its storage and copy the value. This is done
629 * after we create the attribute so that we don't overflow the
630 * maximum size of a transaction and/or hit a deadlock.
631 */
632 if (attr->xattri_blkcnt > 0) {
633 error = xfs_attr_rmtval_set_blk(attr);
634 if (error)
635 return error;
636 /* Roll the transaction only if there is more to allocate. */
637 if (attr->xattri_blkcnt > 0)
638 goto out;
639 }
640
641 error = xfs_attr_rmtval_set_value(args);
642 if (error)
643 return error;
644
645 attr->xattri_dela_state = xfs_attr_complete_op(attr,
646 ++attr->xattri_dela_state);
647 /*
648 * If we are not doing a rename, we've finished the operation but still
649 * have to clear the incomplete flag protecting the new attr from
650 * exposing partially initialised state if we crash during creation.
651 */
652 if (attr->xattri_dela_state == XFS_DAS_DONE)
653 error = xfs_attr3_leaf_clearflag(args);
654 out:
655 trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
656 return error;
657 }
658
659 /*
660 * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
661 * for later deletion of the entry.
662 */
663 static int
xfs_attr_leaf_mark_incomplete(struct xfs_da_args * args,struct xfs_da_state * state)664 xfs_attr_leaf_mark_incomplete(
665 struct xfs_da_args *args,
666 struct xfs_da_state *state)
667 {
668 int error;
669
670 /*
671 * Fill in disk block numbers in the state structure
672 * so that we can get the buffers back after we commit
673 * several transactions in the following calls.
674 */
675 error = xfs_attr_fillstate(state);
676 if (error)
677 return error;
678
679 /*
680 * Mark the attribute as INCOMPLETE
681 */
682 return xfs_attr3_leaf_setflag(args);
683 }
684
685 /* Ensure the da state of an xattr deferred work item is ready to go. */
686 static inline void
xfs_attr_item_init_da_state(struct xfs_attr_intent * attr)687 xfs_attr_item_init_da_state(
688 struct xfs_attr_intent *attr)
689 {
690 struct xfs_da_args *args = attr->xattri_da_args;
691
692 if (!attr->xattri_da_state)
693 attr->xattri_da_state = xfs_da_state_alloc(args);
694 else
695 xfs_da_state_reset(attr->xattri_da_state, args);
696 }
697
698 /*
699 * Initial setup for xfs_attr_node_removename. Make sure the attr is there and
700 * the blocks are valid. Attr keys with remote blocks will be marked
701 * incomplete.
702 */
703 static
xfs_attr_node_removename_setup(struct xfs_attr_intent * attr)704 int xfs_attr_node_removename_setup(
705 struct xfs_attr_intent *attr)
706 {
707 struct xfs_da_args *args = attr->xattri_da_args;
708 struct xfs_da_state *state;
709 int error;
710
711 xfs_attr_item_init_da_state(attr);
712 error = xfs_attr_node_lookup(args, attr->xattri_da_state);
713 if (error != -EEXIST)
714 goto out;
715 error = 0;
716
717 state = attr->xattri_da_state;
718 ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
719 ASSERT(state->path.blk[state->path.active - 1].magic ==
720 XFS_ATTR_LEAF_MAGIC);
721
722 error = xfs_attr_leaf_mark_incomplete(args, state);
723 if (error)
724 goto out;
725 if (args->rmtblkno > 0)
726 error = xfs_attr_rmtval_invalidate(args);
727 out:
728 if (error) {
729 xfs_da_state_free(attr->xattri_da_state);
730 attr->xattri_da_state = NULL;
731 }
732
733 return error;
734 }
735
736 /*
737 * Remove the original attr we have just replaced. This is dependent on the
738 * original lookup and insert placing the old attr in args->blkno/args->index
739 * and the new attr in args->blkno2/args->index2.
740 */
741 static int
xfs_attr_leaf_remove_attr(struct xfs_attr_intent * attr)742 xfs_attr_leaf_remove_attr(
743 struct xfs_attr_intent *attr)
744 {
745 struct xfs_da_args *args = attr->xattri_da_args;
746 struct xfs_inode *dp = args->dp;
747 struct xfs_buf *bp = NULL;
748 int forkoff;
749 int error;
750
751 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
752 args->blkno, &bp);
753 if (error)
754 return error;
755
756 xfs_attr3_leaf_remove(bp, args);
757
758 forkoff = xfs_attr_shortform_allfit(bp, dp);
759 if (forkoff)
760 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
761 /* bp is gone due to xfs_da_shrink_inode */
762
763 return error;
764 }
765
766 /*
767 * Shrink an attribute from leaf to shortform. Used by the node format remove
768 * path when the node format collapses to a single block and so we have to check
769 * if it can be collapsed further.
770 */
771 static int
xfs_attr_leaf_shrink(struct xfs_da_args * args)772 xfs_attr_leaf_shrink(
773 struct xfs_da_args *args)
774 {
775 struct xfs_inode *dp = args->dp;
776 struct xfs_buf *bp;
777 int forkoff;
778 int error;
779
780 if (!xfs_attr_is_leaf(dp))
781 return 0;
782
783 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
784 if (error)
785 return error;
786
787 forkoff = xfs_attr_shortform_allfit(bp, dp);
788 if (forkoff) {
789 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
790 /* bp is gone due to xfs_da_shrink_inode */
791 } else {
792 xfs_trans_brelse(args->trans, bp);
793 }
794
795 return error;
796 }
797
798 /*
799 * Run the attribute operation specified in @attr.
800 *
801 * This routine is meant to function as a delayed operation and will set the
802 * state to XFS_DAS_DONE when the operation is complete. Calling functions will
803 * need to handle this, and recall the function until either an error or
804 * XFS_DAS_DONE is detected.
805 */
806 int
xfs_attr_set_iter(struct xfs_attr_intent * attr)807 xfs_attr_set_iter(
808 struct xfs_attr_intent *attr)
809 {
810 struct xfs_da_args *args = attr->xattri_da_args;
811 int error = 0;
812
813 /* State machine switch */
814 next_state:
815 switch (attr->xattri_dela_state) {
816 case XFS_DAS_UNINIT:
817 ASSERT(0);
818 return -EFSCORRUPTED;
819 case XFS_DAS_SF_ADD:
820 return xfs_attr_sf_addname(attr);
821 case XFS_DAS_LEAF_ADD:
822 return xfs_attr_leaf_addname(attr);
823 case XFS_DAS_NODE_ADD:
824 return xfs_attr_node_addname(attr);
825
826 case XFS_DAS_SF_REMOVE:
827 error = xfs_attr_sf_removename(args);
828 attr->xattri_dela_state = xfs_attr_complete_op(attr,
829 xfs_attr_init_add_state(args));
830 break;
831 case XFS_DAS_LEAF_REMOVE:
832 error = xfs_attr_leaf_removename(args);
833 attr->xattri_dela_state = xfs_attr_complete_op(attr,
834 xfs_attr_init_add_state(args));
835 break;
836 case XFS_DAS_NODE_REMOVE:
837 error = xfs_attr_node_removename_setup(attr);
838 if (error == -ENOATTR &&
839 (args->op_flags & XFS_DA_OP_RECOVERY)) {
840 attr->xattri_dela_state = xfs_attr_complete_op(attr,
841 xfs_attr_init_add_state(args));
842 error = 0;
843 break;
844 }
845 if (error)
846 return error;
847 attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
848 if (args->rmtblkno == 0)
849 attr->xattri_dela_state++;
850 break;
851
852 case XFS_DAS_LEAF_SET_RMT:
853 case XFS_DAS_NODE_SET_RMT:
854 error = xfs_attr_rmtval_find_space(attr);
855 if (error)
856 return error;
857 attr->xattri_dela_state++;
858 fallthrough;
859
860 case XFS_DAS_LEAF_ALLOC_RMT:
861 case XFS_DAS_NODE_ALLOC_RMT:
862 error = xfs_attr_rmtval_alloc(attr);
863 if (error)
864 return error;
865 if (attr->xattri_dela_state == XFS_DAS_DONE)
866 break;
867 goto next_state;
868
869 case XFS_DAS_LEAF_REPLACE:
870 case XFS_DAS_NODE_REPLACE:
871 /*
872 * We must "flip" the incomplete flags on the "new" and "old"
873 * attribute/value pairs so that one disappears and one appears
874 * atomically.
875 */
876 error = xfs_attr3_leaf_flipflags(args);
877 if (error)
878 return error;
879 /*
880 * We must commit the flag value change now to make it atomic
881 * and then we can start the next trans in series at REMOVE_OLD.
882 */
883 attr->xattri_dela_state++;
884 break;
885
886 case XFS_DAS_LEAF_REMOVE_OLD:
887 case XFS_DAS_NODE_REMOVE_OLD:
888 /*
889 * If we have a remote attr, start the process of removing it
890 * by invalidating any cached buffers.
891 *
892 * If we don't have a remote attr, we skip the remote block
893 * removal state altogether with a second state increment.
894 */
895 xfs_attr_restore_rmt_blk(args);
896 if (args->rmtblkno) {
897 error = xfs_attr_rmtval_invalidate(args);
898 if (error)
899 return error;
900 } else {
901 attr->xattri_dela_state++;
902 }
903
904 attr->xattri_dela_state++;
905 goto next_state;
906
907 case XFS_DAS_LEAF_REMOVE_RMT:
908 case XFS_DAS_NODE_REMOVE_RMT:
909 error = xfs_attr_rmtval_remove(attr);
910 if (error == -EAGAIN) {
911 error = 0;
912 break;
913 }
914 if (error)
915 return error;
916
917 /*
918 * We've finished removing the remote attr blocks, so commit the
919 * transaction and move on to removing the attr name from the
920 * leaf/node block. Removing the attr might require a full
921 * transaction reservation for btree block freeing, so we
922 * can't do that in the same transaction where we removed the
923 * remote attr blocks.
924 */
925 attr->xattri_dela_state++;
926 break;
927
928 case XFS_DAS_LEAF_REMOVE_ATTR:
929 error = xfs_attr_leaf_remove_attr(attr);
930 attr->xattri_dela_state = xfs_attr_complete_op(attr,
931 xfs_attr_init_add_state(args));
932 break;
933
934 case XFS_DAS_NODE_REMOVE_ATTR:
935 error = xfs_attr_node_remove_attr(attr);
936 if (!error)
937 error = xfs_attr_leaf_shrink(args);
938 attr->xattri_dela_state = xfs_attr_complete_op(attr,
939 xfs_attr_init_add_state(args));
940 break;
941 default:
942 ASSERT(0);
943 break;
944 }
945
946 trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
947 return error;
948 }
949
950
951 /*
952 * Return EEXIST if attr is found, or ENOATTR if not
953 */
954 static int
xfs_attr_lookup(struct xfs_da_args * args)955 xfs_attr_lookup(
956 struct xfs_da_args *args)
957 {
958 struct xfs_inode *dp = args->dp;
959 struct xfs_buf *bp = NULL;
960 struct xfs_da_state *state;
961 int error;
962
963 if (!xfs_inode_hasattr(dp))
964 return -ENOATTR;
965
966 if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL) {
967 if (xfs_attr_sf_findname(args))
968 return -EEXIST;
969 return -ENOATTR;
970 }
971
972 /* Prerequisite for xfs_attr_is_leaf */
973 error = xfs_iread_extents(args->trans, args->dp, XFS_ATTR_FORK);
974 if (error)
975 return error;
976
977 if (xfs_attr_is_leaf(dp)) {
978 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
979 0, &bp);
980 if (error)
981 return error;
982 error = xfs_attr3_leaf_lookup_int(bp, args);
983 xfs_trans_brelse(args->trans, bp);
984 return error;
985 }
986
987 state = xfs_da_state_alloc(args);
988 error = xfs_attr_node_lookup(args, state);
989 xfs_da_state_free(state);
990 return error;
991 }
992
993 int
xfs_attr_add_fork(struct xfs_inode * ip,int size,int rsvd)994 xfs_attr_add_fork(
995 struct xfs_inode *ip, /* incore inode pointer */
996 int size, /* space new attribute needs */
997 int rsvd) /* xact may use reserved blks */
998 {
999 struct xfs_mount *mp = ip->i_mount;
1000 struct xfs_trans *tp; /* transaction pointer */
1001 unsigned int blks; /* space reservation */
1002 int error; /* error return value */
1003
1004 if (!xfs_is_metadir_inode(ip))
1005 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1006
1007 blks = XFS_ADDAFORK_SPACE_RES(mp);
1008
1009 error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
1010 rsvd, &tp);
1011 if (error)
1012 return error;
1013
1014 if (xfs_inode_has_attr_fork(ip))
1015 goto trans_cancel;
1016
1017 error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
1018 if (error)
1019 goto trans_cancel;
1020
1021 error = xfs_trans_commit(tp);
1022 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1023 return error;
1024
1025 trans_cancel:
1026 xfs_trans_cancel(tp);
1027 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1028 return error;
1029 }
1030
1031 /*
1032 * Decide if it is theoretically possible to try to bypass the attr intent
1033 * mechanism for better performance. Other constraints (e.g. available space
1034 * in the existing structure) are not considered here.
1035 */
1036 static inline bool
xfs_attr_can_shortcut(const struct xfs_inode * ip)1037 xfs_attr_can_shortcut(
1038 const struct xfs_inode *ip)
1039 {
1040 return xfs_inode_has_attr_fork(ip) && xfs_attr_is_shortform(ip);
1041 }
1042
1043 /* Try to set an attr in one transaction or fall back to attr intents. */
1044 int
xfs_attr_setname(struct xfs_da_args * args,int rmt_blks)1045 xfs_attr_setname(
1046 struct xfs_da_args *args,
1047 int rmt_blks)
1048 {
1049 int error;
1050
1051 if (!rmt_blks && xfs_attr_can_shortcut(args->dp)) {
1052 args->op_flags |= XFS_DA_OP_ADDNAME;
1053
1054 error = xfs_attr_try_sf_addname(args);
1055 if (error != -ENOSPC)
1056 return error;
1057 }
1058
1059 xfs_attr_defer_add(args, XFS_ATTR_DEFER_SET);
1060 return 0;
1061 }
1062
1063 /* Try to remove an attr in one transaction or fall back to attr intents. */
1064 int
xfs_attr_removename(struct xfs_da_args * args)1065 xfs_attr_removename(
1066 struct xfs_da_args *args)
1067 {
1068 if (xfs_attr_can_shortcut(args->dp))
1069 return xfs_attr_sf_removename(args);
1070
1071 xfs_attr_defer_add(args, XFS_ATTR_DEFER_REMOVE);
1072 return 0;
1073 }
1074
1075 /* Try to replace an attr in one transaction or fall back to attr intents. */
1076 int
xfs_attr_replacename(struct xfs_da_args * args,int rmt_blks)1077 xfs_attr_replacename(
1078 struct xfs_da_args *args,
1079 int rmt_blks)
1080 {
1081 int error;
1082
1083 if (rmt_blks || !xfs_attr_can_shortcut(args->dp)) {
1084 xfs_attr_defer_add(args, XFS_ATTR_DEFER_REPLACE);
1085 return 0;
1086 }
1087
1088 error = xfs_attr_shortform_replace(args);
1089 if (error != -ENOSPC)
1090 return error;
1091
1092 args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
1093
1094 error = xfs_attr_sf_removename(args);
1095 if (error)
1096 return error;
1097
1098 if (args->attr_filter & XFS_ATTR_PARENT) {
1099 /*
1100 * Move the new name/value to the regular name/value slots and
1101 * zero out the new name/value slots because we don't need to
1102 * log them for a PPTR_SET operation.
1103 */
1104 xfs_attr_update_pptr_replace_args(args);
1105 args->new_name = NULL;
1106 args->new_namelen = 0;
1107 args->new_value = NULL;
1108 args->new_valuelen = 0;
1109 }
1110 args->op_flags &= ~XFS_DA_OP_REPLACE;
1111
1112 error = xfs_attr_try_sf_addname(args);
1113 if (error != -ENOSPC)
1114 return error;
1115
1116 xfs_attr_defer_add(args, XFS_ATTR_DEFER_SET);
1117 return 0;
1118 }
1119
1120 /*
1121 * Make a change to the xattr structure.
1122 *
1123 * The caller must have initialized @args, attached dquots, and must not hold
1124 * any ILOCKs. Reserved data blocks may be used if @rsvd is set.
1125 *
1126 * Returns -EEXIST for XFS_ATTRUPDATE_CREATE if the name already exists.
1127 * Returns -ENOATTR for XFS_ATTRUPDATE_REMOVE if the name does not exist.
1128 * Returns 0 on success, or a negative errno if something else went wrong.
1129 */
1130 int
xfs_attr_set(struct xfs_da_args * args,enum xfs_attr_update op,bool rsvd)1131 xfs_attr_set(
1132 struct xfs_da_args *args,
1133 enum xfs_attr_update op,
1134 bool rsvd)
1135 {
1136 struct xfs_inode *dp = args->dp;
1137 struct xfs_mount *mp = dp->i_mount;
1138 struct xfs_trans_res tres;
1139 int error, local;
1140 int rmt_blks = 0;
1141 unsigned int total = 0;
1142
1143 ASSERT(!args->trans);
1144
1145 switch (op) {
1146 case XFS_ATTRUPDATE_UPSERT:
1147 case XFS_ATTRUPDATE_CREATE:
1148 case XFS_ATTRUPDATE_REPLACE:
1149 XFS_STATS_INC(mp, xs_attr_set);
1150 args->total = xfs_attr_calc_size(args, &local);
1151
1152 /*
1153 * If the inode doesn't have an attribute fork, add one.
1154 * (inode must not be locked when we call this routine)
1155 */
1156 if (xfs_inode_has_attr_fork(dp) == 0) {
1157 int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1158 xfs_attr_sf_entsize_byname(args->namelen,
1159 args->valuelen);
1160
1161 error = xfs_attr_add_fork(dp, sf_size, rsvd);
1162 if (error)
1163 return error;
1164 }
1165
1166 if (!local)
1167 rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1168
1169 tres = xfs_attr_set_resv(args);
1170 total = args->total;
1171 break;
1172 case XFS_ATTRUPDATE_REMOVE:
1173 XFS_STATS_INC(mp, xs_attr_remove);
1174 rmt_blks = xfs_attr3_max_rmt_blocks(mp);
1175 tres = M_RES(mp)->tr_attrrm;
1176 total = XFS_ATTRRM_SPACE_RES(mp);
1177 break;
1178 }
1179
1180 /*
1181 * Root fork attributes can use reserved data blocks for this
1182 * operation if necessary
1183 */
1184 error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1185 if (error)
1186 return error;
1187
1188 if (op != XFS_ATTRUPDATE_REMOVE || xfs_inode_hasattr(dp)) {
1189 error = xfs_iext_count_extend(args->trans, dp, XFS_ATTR_FORK,
1190 XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1191 if (error)
1192 goto out_trans_cancel;
1193 }
1194
1195 error = xfs_attr_lookup(args);
1196 switch (error) {
1197 case -EEXIST:
1198 if (op == XFS_ATTRUPDATE_REMOVE) {
1199 /* if no value, we are performing a remove operation */
1200 error = xfs_attr_removename(args);
1201 if (error)
1202 goto out_trans_cancel;
1203 break;
1204 }
1205
1206 /* Pure create fails if the attr already exists */
1207 if (op == XFS_ATTRUPDATE_CREATE)
1208 goto out_trans_cancel;
1209
1210 error = xfs_attr_replacename(args, rmt_blks);
1211 if (error)
1212 goto out_trans_cancel;
1213 break;
1214 case -ENOATTR:
1215 /* Can't remove what isn't there. */
1216 if (op == XFS_ATTRUPDATE_REMOVE)
1217 goto out_trans_cancel;
1218
1219 /* Pure replace fails if no existing attr to replace. */
1220 if (op == XFS_ATTRUPDATE_REPLACE)
1221 goto out_trans_cancel;
1222
1223 error = xfs_attr_setname(args, rmt_blks);
1224 if (error)
1225 goto out_trans_cancel;
1226 break;
1227 default:
1228 goto out_trans_cancel;
1229 }
1230
1231 /*
1232 * If this is a synchronous mount, make sure that the
1233 * transaction goes to disk before returning to the user.
1234 */
1235 if (xfs_has_wsync(mp))
1236 xfs_trans_set_sync(args->trans);
1237
1238 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1239
1240 /*
1241 * Commit the last in the sequence of transactions.
1242 */
1243 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1244 error = xfs_trans_commit(args->trans);
1245 out_unlock:
1246 xfs_iunlock(dp, XFS_ILOCK_EXCL);
1247 args->trans = NULL;
1248 return error;
1249
1250 out_trans_cancel:
1251 if (args->trans)
1252 xfs_trans_cancel(args->trans);
1253 goto out_unlock;
1254 }
1255
1256 /*========================================================================
1257 * External routines when attribute list is inside the inode
1258 *========================================================================*/
1259
xfs_attr_sf_totsize(struct xfs_inode * dp)1260 int xfs_attr_sf_totsize(struct xfs_inode *dp)
1261 {
1262 struct xfs_attr_sf_hdr *sf = dp->i_af.if_data;
1263
1264 return be16_to_cpu(sf->totsize);
1265 }
1266
1267 /*
1268 * Add a name to the shortform attribute list structure
1269 * This is the external routine.
1270 */
1271 static int
xfs_attr_shortform_addname(struct xfs_da_args * args)1272 xfs_attr_shortform_addname(
1273 struct xfs_da_args *args)
1274 {
1275 int newsize, forkoff;
1276
1277 trace_xfs_attr_sf_addname(args);
1278
1279 if (xfs_attr_sf_findname(args)) {
1280 int error;
1281
1282 ASSERT(args->op_flags & XFS_DA_OP_REPLACE);
1283
1284 error = xfs_attr_sf_removename(args);
1285 if (error)
1286 return error;
1287
1288 /*
1289 * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1290 * so that the new attr doesn't fit in shortform format, the
1291 * leaf format add routine won't trip over the attr not being
1292 * around.
1293 */
1294 args->op_flags &= ~XFS_DA_OP_REPLACE;
1295 } else {
1296 ASSERT(!(args->op_flags & XFS_DA_OP_REPLACE));
1297 }
1298
1299 if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1300 args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1301 return -ENOSPC;
1302
1303 newsize = xfs_attr_sf_totsize(args->dp);
1304 newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
1305
1306 forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
1307 if (!forkoff)
1308 return -ENOSPC;
1309
1310 xfs_attr_shortform_add(args, forkoff);
1311 return 0;
1312 }
1313
1314
1315 /*========================================================================
1316 * External routines when attribute list is one block
1317 *========================================================================*/
1318
1319 /*
1320 * Remove a name from the leaf attribute list structure
1321 *
1322 * This leaf block cannot have a "remote" value, we only call this routine
1323 * if bmap_one_block() says there is only one block (ie: no remote blks).
1324 */
1325 STATIC int
xfs_attr_leaf_removename(struct xfs_da_args * args)1326 xfs_attr_leaf_removename(
1327 struct xfs_da_args *args)
1328 {
1329 struct xfs_inode *dp = args->dp;
1330 int error, forkoff;
1331 struct xfs_buf *bp;
1332
1333 trace_xfs_attr_leaf_removename(args);
1334
1335 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
1336 if (error)
1337 return error;
1338 error = xfs_attr3_leaf_lookup_int(bp, args);
1339 if (error != -EEXIST) {
1340 xfs_trans_brelse(args->trans, bp);
1341 if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
1342 return 0;
1343 return error;
1344 }
1345
1346 xfs_attr3_leaf_remove(bp, args);
1347
1348 /*
1349 * If the result is small enough, shrink it all into the inode.
1350 */
1351 forkoff = xfs_attr_shortform_allfit(bp, dp);
1352 if (forkoff)
1353 return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1354 /* bp is gone due to xfs_da_shrink_inode */
1355
1356 return 0;
1357 }
1358
1359 /*
1360 * Look up a name in a leaf attribute list structure.
1361 *
1362 * This leaf block cannot have a "remote" value, we only call this routine
1363 * if bmap_one_block() says there is only one block (ie: no remote blks).
1364 *
1365 * Returns 0 on successful retrieval, otherwise an error.
1366 */
1367 STATIC int
xfs_attr_leaf_get(struct xfs_da_args * args)1368 xfs_attr_leaf_get(
1369 struct xfs_da_args *args)
1370 {
1371 struct xfs_buf *bp;
1372 int error;
1373
1374 trace_xfs_attr_leaf_get(args);
1375
1376 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
1377 if (error)
1378 return error;
1379 error = xfs_attr3_leaf_lookup_int(bp, args);
1380 if (error == -EEXIST)
1381 error = xfs_attr3_leaf_getvalue(bp, args);
1382 xfs_trans_brelse(args->trans, bp);
1383 return error;
1384 }
1385
1386 /* Return EEXIST if attr is found, or ENOATTR if not. */
1387 STATIC int
xfs_attr_node_lookup(struct xfs_da_args * args,struct xfs_da_state * state)1388 xfs_attr_node_lookup(
1389 struct xfs_da_args *args,
1390 struct xfs_da_state *state)
1391 {
1392 int retval, error;
1393
1394 /*
1395 * Search to see if name exists, and get back a pointer to it.
1396 */
1397 error = xfs_da3_node_lookup_int(state, &retval);
1398 if (error)
1399 return error;
1400
1401 return retval;
1402 }
1403
1404 /*========================================================================
1405 * External routines when attribute list size > geo->blksize
1406 *========================================================================*/
1407
1408 STATIC int
xfs_attr_node_addname_find_attr(struct xfs_attr_intent * attr)1409 xfs_attr_node_addname_find_attr(
1410 struct xfs_attr_intent *attr)
1411 {
1412 struct xfs_da_args *args = attr->xattri_da_args;
1413 int error;
1414
1415 /*
1416 * Search to see if name already exists, and get back a pointer
1417 * to where it should go.
1418 */
1419 xfs_attr_item_init_da_state(attr);
1420 error = xfs_attr_node_lookup(args, attr->xattri_da_state);
1421 switch (error) {
1422 case -ENOATTR:
1423 if (args->op_flags & XFS_DA_OP_REPLACE)
1424 goto error;
1425 break;
1426 case -EEXIST:
1427 if (!(args->op_flags & XFS_DA_OP_REPLACE))
1428 goto error;
1429
1430
1431 trace_xfs_attr_node_replace(args);
1432 /*
1433 * Save the existing remote attr state so that the current
1434 * values reflect the state of the new attribute we are about to
1435 * add, not the attribute we just found and will remove later.
1436 */
1437 xfs_attr_save_rmt_blk(args);
1438 break;
1439 case 0:
1440 break;
1441 default:
1442 goto error;
1443 }
1444
1445 return 0;
1446 error:
1447 if (attr->xattri_da_state) {
1448 xfs_da_state_free(attr->xattri_da_state);
1449 attr->xattri_da_state = NULL;
1450 }
1451 return error;
1452 }
1453
1454 /*
1455 * Add a name to a Btree-format attribute list.
1456 *
1457 * This will involve walking down the Btree, and may involve splitting leaf
1458 * nodes and even splitting intermediate nodes up to and including the root
1459 * node (a special case of an intermediate node).
1460 *
1461 * If the tree was still in single leaf format and needs to converted to
1462 * real node format return 1 and let the caller handle that.
1463 */
1464 static int
xfs_attr_node_try_addname(struct xfs_attr_intent * attr)1465 xfs_attr_node_try_addname(
1466 struct xfs_attr_intent *attr)
1467 {
1468 struct xfs_da_state *state = attr->xattri_da_state;
1469 struct xfs_da_state_blk *blk;
1470 int error = 0;
1471
1472 trace_xfs_attr_node_addname(state->args);
1473
1474 blk = &state->path.blk[state->path.active-1];
1475 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1476
1477 if (!xfs_attr3_leaf_add(blk->bp, state->args)) {
1478 if (state->path.active == 1) {
1479 /*
1480 * Its really a single leaf node, but it had
1481 * out-of-line values so it looked like it *might*
1482 * have been a b-tree. Let the caller deal with this.
1483 */
1484 error = 1;
1485 goto out;
1486 }
1487
1488 /*
1489 * Split as many Btree elements as required.
1490 * This code tracks the new and old attr's location
1491 * in the index/blkno/rmtblkno/rmtblkcnt fields and
1492 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1493 */
1494 error = xfs_da3_split(state);
1495 if (error)
1496 goto out;
1497 } else {
1498 /*
1499 * Addition succeeded, update Btree hashvals.
1500 */
1501 xfs_da3_fixhashpath(state, &state->path);
1502 }
1503
1504 out:
1505 xfs_da_state_free(state);
1506 attr->xattri_da_state = NULL;
1507 return error;
1508 }
1509
1510 static int
xfs_attr_node_removename(struct xfs_da_args * args,struct xfs_da_state * state)1511 xfs_attr_node_removename(
1512 struct xfs_da_args *args,
1513 struct xfs_da_state *state)
1514 {
1515 struct xfs_da_state_blk *blk;
1516 int retval;
1517
1518 /*
1519 * Remove the name and update the hashvals in the tree.
1520 */
1521 blk = &state->path.blk[state->path.active-1];
1522 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1523 retval = xfs_attr3_leaf_remove(blk->bp, args);
1524 xfs_da3_fixhashpath(state, &state->path);
1525
1526 return retval;
1527 }
1528
1529 static int
xfs_attr_node_remove_attr(struct xfs_attr_intent * attr)1530 xfs_attr_node_remove_attr(
1531 struct xfs_attr_intent *attr)
1532 {
1533 struct xfs_da_args *args = attr->xattri_da_args;
1534 struct xfs_da_state *state = xfs_da_state_alloc(args);
1535 int retval = 0;
1536 int error = 0;
1537
1538 /*
1539 * The attr we are removing has already been marked incomplete, so
1540 * we need to set the filter appropriately to re-find the "old"
1541 * attribute entry after any split ops.
1542 */
1543 args->attr_filter |= XFS_ATTR_INCOMPLETE;
1544 error = xfs_da3_node_lookup_int(state, &retval);
1545 if (error)
1546 goto out;
1547
1548 error = xfs_attr_node_removename(args, state);
1549
1550 /*
1551 * Check to see if the tree needs to be collapsed.
1552 */
1553 if (retval && (state->path.active > 1)) {
1554 error = xfs_da3_join(state);
1555 if (error)
1556 goto out;
1557 }
1558 retval = error = 0;
1559
1560 out:
1561 xfs_da_state_free(state);
1562 if (error)
1563 return error;
1564 return retval;
1565 }
1566
1567 /*
1568 * Retrieve the attribute data from a node attribute list.
1569 *
1570 * This routine gets called for any attribute fork that has more than one
1571 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1572 * "remote" values taking up more blocks.
1573 *
1574 * Returns 0 on successful retrieval, otherwise an error.
1575 */
1576 STATIC int
xfs_attr_node_get(struct xfs_da_args * args)1577 xfs_attr_node_get(
1578 struct xfs_da_args *args)
1579 {
1580 struct xfs_da_state *state;
1581 struct xfs_da_state_blk *blk;
1582 int i;
1583 int error;
1584
1585 trace_xfs_attr_node_get(args);
1586
1587 /*
1588 * Search to see if name exists, and get back a pointer to it.
1589 */
1590 state = xfs_da_state_alloc(args);
1591 error = xfs_attr_node_lookup(args, state);
1592 if (error != -EEXIST)
1593 goto out_release;
1594
1595 /*
1596 * Get the value, local or "remote"
1597 */
1598 blk = &state->path.blk[state->path.active - 1];
1599 error = xfs_attr3_leaf_getvalue(blk->bp, args);
1600
1601 /*
1602 * If not in a transaction, we have to release all the buffers.
1603 */
1604 out_release:
1605 for (i = 0; i < state->path.active; i++) {
1606 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1607 state->path.blk[i].bp = NULL;
1608 }
1609
1610 xfs_da_state_free(state);
1611 return error;
1612 }
1613
1614 /* Enforce that there is at most one namespace bit per attr. */
xfs_attr_check_namespace(unsigned int attr_flags)1615 inline bool xfs_attr_check_namespace(unsigned int attr_flags)
1616 {
1617 return hweight32(attr_flags & XFS_ATTR_NSP_ONDISK_MASK) < 2;
1618 }
1619
1620 /* Returns true if the attribute entry name is valid. */
1621 bool
xfs_attr_namecheck(unsigned int attr_flags,const void * name,size_t length)1622 xfs_attr_namecheck(
1623 unsigned int attr_flags,
1624 const void *name,
1625 size_t length)
1626 {
1627 /* Only one namespace bit allowed. */
1628 if (!xfs_attr_check_namespace(attr_flags))
1629 return false;
1630
1631 /*
1632 * MAXNAMELEN includes the trailing null, but (name/length) leave it
1633 * out, so use >= for the length check.
1634 */
1635 if (length >= MAXNAMELEN)
1636 return false;
1637
1638 /* Parent pointers have their own validation. */
1639 if (attr_flags & XFS_ATTR_PARENT)
1640 return xfs_parent_namecheck(attr_flags, name, length);
1641
1642 /* There shouldn't be any nulls here */
1643 return !memchr(name, 0, length);
1644 }
1645
1646 int __init
xfs_attr_intent_init_cache(void)1647 xfs_attr_intent_init_cache(void)
1648 {
1649 xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
1650 sizeof(struct xfs_attr_intent),
1651 0, 0, NULL);
1652
1653 return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
1654 }
1655
1656 void
xfs_attr_intent_destroy_cache(void)1657 xfs_attr_intent_destroy_cache(void)
1658 {
1659 kmem_cache_destroy(xfs_attr_intent_cache);
1660 xfs_attr_intent_cache = NULL;
1661 }
1662