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