]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/xfs_attr.c
xfs: rework xfs_bmap_free callers to use xfs_defer_ops
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_attr.c
1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #include "libxfs_priv.h"
19 #include "xfs_fs.h"
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_bit.h"
25 #include "xfs_mount.h"
26 #include "xfs_defer.h"
27 #include "xfs_da_format.h"
28 #include "xfs_da_btree.h"
29 #include "xfs_attr_sf.h"
30 #include "xfs_inode.h"
31 #include "xfs_alloc.h"
32 #include "xfs_trans.h"
33 #include "xfs_bmap.h"
34 #include "xfs_bmap_btree.h"
35 #include "xfs_attr_leaf.h"
36 #include "xfs_attr_remote.h"
37 #include "xfs_trans_space.h"
38 #include "xfs_trace.h"
39
40 /*
41 * xfs_attr.c
42 *
43 * Provide the external interfaces to manage attribute lists.
44 */
45
46 /*========================================================================
47 * Function prototypes for the kernel.
48 *========================================================================*/
49
50 /*
51 * Internal routines when attribute list fits inside the inode.
52 */
53 STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
54
55 /*
56 * Internal routines when attribute list is one block.
57 */
58 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
59 STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
60 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
61
62 /*
63 * Internal routines when attribute list is more than one block.
64 */
65 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
66 STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
67 STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
68 STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
69 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
70
71
72 STATIC int
73 xfs_attr_args_init(
74 struct xfs_da_args *args,
75 struct xfs_inode *dp,
76 const unsigned char *name,
77 int flags)
78 {
79
80 if (!name)
81 return -EINVAL;
82
83 memset(args, 0, sizeof(*args));
84 args->geo = dp->i_mount->m_attr_geo;
85 args->whichfork = XFS_ATTR_FORK;
86 args->dp = dp;
87 args->flags = flags;
88 args->name = name;
89 args->namelen = strlen((const char *)name);
90 if (args->namelen >= MAXNAMELEN)
91 return -EFAULT; /* match IRIX behaviour */
92
93 args->hashval = xfs_da_hashname(args->name, args->namelen);
94 return 0;
95 }
96
97 int
98 xfs_inode_hasattr(
99 struct xfs_inode *ip)
100 {
101 if (!XFS_IFORK_Q(ip) ||
102 (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
103 ip->i_d.di_anextents == 0))
104 return 0;
105 return 1;
106 }
107
108 /*========================================================================
109 * Overall external interface routines.
110 *========================================================================*/
111
112 int
113 xfs_attr_get(
114 struct xfs_inode *ip,
115 const unsigned char *name,
116 unsigned char *value,
117 int *valuelenp,
118 int flags)
119 {
120 struct xfs_da_args args;
121 uint lock_mode;
122 int error;
123
124 XFS_STATS_INC(ip->i_mount, xs_attr_get);
125
126 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
127 return -EIO;
128
129 if (!xfs_inode_hasattr(ip))
130 return -ENOATTR;
131
132 error = xfs_attr_args_init(&args, ip, name, flags);
133 if (error)
134 return error;
135
136 args.value = value;
137 args.valuelen = *valuelenp;
138
139 lock_mode = xfs_ilock_attr_map_shared(ip);
140 if (!xfs_inode_hasattr(ip))
141 error = -ENOATTR;
142 else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
143 error = xfs_attr_shortform_getvalue(&args);
144 else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
145 error = xfs_attr_leaf_get(&args);
146 else
147 error = xfs_attr_node_get(&args);
148 xfs_iunlock(ip, lock_mode);
149
150 *valuelenp = args.valuelen;
151 return error == -EEXIST ? 0 : error;
152 }
153
154 /*
155 * Calculate how many blocks we need for the new attribute,
156 */
157 STATIC int
158 xfs_attr_calc_size(
159 struct xfs_da_args *args,
160 int *local)
161 {
162 struct xfs_mount *mp = args->dp->i_mount;
163 int size;
164 int nblks;
165
166 /*
167 * Determine space new attribute will use, and if it would be
168 * "local" or "remote" (note: local != inline).
169 */
170 size = xfs_attr_leaf_newentsize(args, local);
171 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
172 if (*local) {
173 if (size > (args->geo->blksize / 2)) {
174 /* Double split possible */
175 nblks *= 2;
176 }
177 } else {
178 /*
179 * Out of line attribute, cannot double split, but
180 * make room for the attribute value itself.
181 */
182 uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
183 nblks += dblocks;
184 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
185 }
186
187 return nblks;
188 }
189
190 int
191 xfs_attr_set(
192 struct xfs_inode *dp,
193 const unsigned char *name,
194 unsigned char *value,
195 int valuelen,
196 int flags)
197 {
198 struct xfs_mount *mp = dp->i_mount;
199 struct xfs_da_args args;
200 struct xfs_bmap_free flist;
201 struct xfs_trans_res tres;
202 xfs_fsblock_t firstblock;
203 int rsvd = (flags & ATTR_ROOT) != 0;
204 int error, err2, local;
205
206 XFS_STATS_INC(mp, xs_attr_set);
207
208 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
209 return -EIO;
210
211 error = xfs_attr_args_init(&args, dp, name, flags);
212 if (error)
213 return error;
214
215 args.value = value;
216 args.valuelen = valuelen;
217 args.firstblock = &firstblock;
218 args.flist = &flist;
219 args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
220 args.total = xfs_attr_calc_size(&args, &local);
221
222 error = xfs_qm_dqattach(dp, 0);
223 if (error)
224 return error;
225
226 /*
227 * If the inode doesn't have an attribute fork, add one.
228 * (inode must not be locked when we call this routine)
229 */
230 if (XFS_IFORK_Q(dp) == 0) {
231 int sf_size = sizeof(xfs_attr_sf_hdr_t) +
232 XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen);
233
234 error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
235 if (error)
236 return error;
237 }
238
239 tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
240 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
241 tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
242 tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
243
244 /*
245 * Root fork attributes can use reserved data blocks for this
246 * operation if necessary
247 */
248 error = xfs_trans_alloc(mp, &tres, args.total, 0,
249 rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
250 if (error)
251 return error;
252
253 xfs_ilock(dp, XFS_ILOCK_EXCL);
254 error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
255 rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
256 XFS_QMOPT_RES_REGBLKS);
257 if (error) {
258 xfs_iunlock(dp, XFS_ILOCK_EXCL);
259 xfs_trans_cancel(args.trans);
260 return error;
261 }
262
263 xfs_trans_ijoin(args.trans, dp, 0);
264
265 /*
266 * If the attribute list is non-existent or a shortform list,
267 * upgrade it to a single-leaf-block attribute list.
268 */
269 if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL ||
270 (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
271 dp->i_d.di_anextents == 0)) {
272
273 /*
274 * Build initial attribute list (if required).
275 */
276 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
277 xfs_attr_shortform_create(&args);
278
279 /*
280 * Try to add the attr to the attribute list in
281 * the inode.
282 */
283 error = xfs_attr_shortform_addname(&args);
284 if (error != -ENOSPC) {
285 /*
286 * Commit the shortform mods, and we're done.
287 * NOTE: this is also the error path (EEXIST, etc).
288 */
289 ASSERT(args.trans != NULL);
290
291 /*
292 * If this is a synchronous mount, make sure that
293 * the transaction goes to disk before returning
294 * to the user.
295 */
296 if (mp->m_flags & XFS_MOUNT_WSYNC)
297 xfs_trans_set_sync(args.trans);
298
299 if (!error && (flags & ATTR_KERNOTIME) == 0) {
300 xfs_trans_ichgtime(args.trans, dp,
301 XFS_ICHGTIME_CHG);
302 }
303 err2 = xfs_trans_commit(args.trans);
304 xfs_iunlock(dp, XFS_ILOCK_EXCL);
305
306 return error ? error : err2;
307 }
308
309 /*
310 * It won't fit in the shortform, transform to a leaf block.
311 * GROT: another possible req'mt for a double-split btree op.
312 */
313 xfs_bmap_init(args.flist, args.firstblock);
314 error = xfs_attr_shortform_to_leaf(&args);
315 if (!error)
316 error = xfs_bmap_finish(&args.trans, args.flist, dp);
317 if (error) {
318 args.trans = NULL;
319 xfs_bmap_cancel(&flist);
320 goto out;
321 }
322
323 /*
324 * Commit the leaf transformation. We'll need another (linked)
325 * transaction to add the new attribute to the leaf.
326 */
327
328 error = xfs_trans_roll(&args.trans, dp);
329 if (error)
330 goto out;
331
332 }
333
334 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
335 error = xfs_attr_leaf_addname(&args);
336 else
337 error = xfs_attr_node_addname(&args);
338 if (error)
339 goto out;
340
341 /*
342 * If this is a synchronous mount, make sure that the
343 * transaction goes to disk before returning to the user.
344 */
345 if (mp->m_flags & XFS_MOUNT_WSYNC)
346 xfs_trans_set_sync(args.trans);
347
348 if ((flags & ATTR_KERNOTIME) == 0)
349 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
350
351 /*
352 * Commit the last in the sequence of transactions.
353 */
354 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
355 error = xfs_trans_commit(args.trans);
356 xfs_iunlock(dp, XFS_ILOCK_EXCL);
357
358 return error;
359
360 out:
361 if (args.trans)
362 xfs_trans_cancel(args.trans);
363 xfs_iunlock(dp, XFS_ILOCK_EXCL);
364 return error;
365 }
366
367 /*
368 * Generic handler routine to remove a name from an attribute list.
369 * Transitions attribute list from Btree to shortform as necessary.
370 */
371 int
372 xfs_attr_remove(
373 struct xfs_inode *dp,
374 const unsigned char *name,
375 int flags)
376 {
377 struct xfs_mount *mp = dp->i_mount;
378 struct xfs_da_args args;
379 struct xfs_bmap_free flist;
380 xfs_fsblock_t firstblock;
381 int error;
382
383 XFS_STATS_INC(mp, xs_attr_remove);
384
385 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
386 return -EIO;
387
388 if (!xfs_inode_hasattr(dp))
389 return -ENOATTR;
390
391 error = xfs_attr_args_init(&args, dp, name, flags);
392 if (error)
393 return error;
394
395 args.firstblock = &firstblock;
396 args.flist = &flist;
397
398 /*
399 * we have no control over the attribute names that userspace passes us
400 * to remove, so we have to allow the name lookup prior to attribute
401 * removal to fail.
402 */
403 args.op_flags = XFS_DA_OP_OKNOENT;
404
405 error = xfs_qm_dqattach(dp, 0);
406 if (error)
407 return error;
408
409 /*
410 * Root fork attributes can use reserved data blocks for this
411 * operation if necessary
412 */
413 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrrm,
414 XFS_ATTRRM_SPACE_RES(mp), 0,
415 (flags & ATTR_ROOT) ? XFS_TRANS_RESERVE : 0,
416 &args.trans);
417 if (error)
418 return error;
419
420 xfs_ilock(dp, XFS_ILOCK_EXCL);
421 /*
422 * No need to make quota reservations here. We expect to release some
423 * blocks not allocate in the common case.
424 */
425 xfs_trans_ijoin(args.trans, dp, 0);
426
427 if (!xfs_inode_hasattr(dp)) {
428 error = -ENOATTR;
429 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
430 ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
431 error = xfs_attr_shortform_remove(&args);
432 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
433 error = xfs_attr_leaf_removename(&args);
434 } else {
435 error = xfs_attr_node_removename(&args);
436 }
437
438 if (error)
439 goto out;
440
441 /*
442 * If this is a synchronous mount, make sure that the
443 * transaction goes to disk before returning to the user.
444 */
445 if (mp->m_flags & XFS_MOUNT_WSYNC)
446 xfs_trans_set_sync(args.trans);
447
448 if ((flags & ATTR_KERNOTIME) == 0)
449 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
450
451 /*
452 * Commit the last in the sequence of transactions.
453 */
454 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
455 error = xfs_trans_commit(args.trans);
456 xfs_iunlock(dp, XFS_ILOCK_EXCL);
457
458 return error;
459
460 out:
461 if (args.trans)
462 xfs_trans_cancel(args.trans);
463 xfs_iunlock(dp, XFS_ILOCK_EXCL);
464 return error;
465 }
466
467 /*========================================================================
468 * External routines when attribute list is inside the inode
469 *========================================================================*/
470
471 /*
472 * Add a name to the shortform attribute list structure
473 * This is the external routine.
474 */
475 STATIC int
476 xfs_attr_shortform_addname(xfs_da_args_t *args)
477 {
478 int newsize, forkoff, retval;
479
480 trace_xfs_attr_sf_addname(args);
481
482 retval = xfs_attr_shortform_lookup(args);
483 if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
484 return retval;
485 } else if (retval == -EEXIST) {
486 if (args->flags & ATTR_CREATE)
487 return retval;
488 retval = xfs_attr_shortform_remove(args);
489 ASSERT(retval == 0);
490 }
491
492 if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
493 args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
494 return -ENOSPC;
495
496 newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
497 newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
498
499 forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
500 if (!forkoff)
501 return -ENOSPC;
502
503 xfs_attr_shortform_add(args, forkoff);
504 return 0;
505 }
506
507
508 /*========================================================================
509 * External routines when attribute list is one block
510 *========================================================================*/
511
512 /*
513 * Add a name to the leaf attribute list structure
514 *
515 * This leaf block cannot have a "remote" value, we only call this routine
516 * if bmap_one_block() says there is only one block (ie: no remote blks).
517 */
518 STATIC int
519 xfs_attr_leaf_addname(xfs_da_args_t *args)
520 {
521 xfs_inode_t *dp;
522 struct xfs_buf *bp;
523 int retval, error, forkoff;
524
525 trace_xfs_attr_leaf_addname(args);
526
527 /*
528 * Read the (only) block in the attribute list in.
529 */
530 dp = args->dp;
531 args->blkno = 0;
532 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
533 if (error)
534 return error;
535
536 /*
537 * Look up the given attribute in the leaf block. Figure out if
538 * the given flags produce an error or call for an atomic rename.
539 */
540 retval = xfs_attr3_leaf_lookup_int(bp, args);
541 if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
542 xfs_trans_brelse(args->trans, bp);
543 return retval;
544 } else if (retval == -EEXIST) {
545 if (args->flags & ATTR_CREATE) { /* pure create op */
546 xfs_trans_brelse(args->trans, bp);
547 return retval;
548 }
549
550 trace_xfs_attr_leaf_replace(args);
551
552 /* save the attribute state for later removal*/
553 args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */
554 args->blkno2 = args->blkno; /* set 2nd entry info*/
555 args->index2 = args->index;
556 args->rmtblkno2 = args->rmtblkno;
557 args->rmtblkcnt2 = args->rmtblkcnt;
558 args->rmtvaluelen2 = args->rmtvaluelen;
559
560 /*
561 * clear the remote attr state now that it is saved so that the
562 * values reflect the state of the attribute we are about to
563 * add, not the attribute we just found and will remove later.
564 */
565 args->rmtblkno = 0;
566 args->rmtblkcnt = 0;
567 args->rmtvaluelen = 0;
568 }
569
570 /*
571 * Add the attribute to the leaf block, transitioning to a Btree
572 * if required.
573 */
574 retval = xfs_attr3_leaf_add(bp, args);
575 if (retval == -ENOSPC) {
576 /*
577 * Promote the attribute list to the Btree format, then
578 * Commit that transaction so that the node_addname() call
579 * can manage its own transactions.
580 */
581 xfs_bmap_init(args->flist, args->firstblock);
582 error = xfs_attr3_leaf_to_node(args);
583 if (!error)
584 error = xfs_bmap_finish(&args->trans, args->flist, dp);
585 if (error) {
586 args->trans = NULL;
587 xfs_bmap_cancel(args->flist);
588 return error;
589 }
590
591 /*
592 * Commit the current trans (including the inode) and start
593 * a new one.
594 */
595 error = xfs_trans_roll(&args->trans, dp);
596 if (error)
597 return error;
598
599 /*
600 * Fob the whole rest of the problem off on the Btree code.
601 */
602 error = xfs_attr_node_addname(args);
603 return error;
604 }
605
606 /*
607 * Commit the transaction that added the attr name so that
608 * later routines can manage their own transactions.
609 */
610 error = xfs_trans_roll(&args->trans, dp);
611 if (error)
612 return error;
613
614 /*
615 * If there was an out-of-line value, allocate the blocks we
616 * identified for its storage and copy the value. This is done
617 * after we create the attribute so that we don't overflow the
618 * maximum size of a transaction and/or hit a deadlock.
619 */
620 if (args->rmtblkno > 0) {
621 error = xfs_attr_rmtval_set(args);
622 if (error)
623 return error;
624 }
625
626 /*
627 * If this is an atomic rename operation, we must "flip" the
628 * incomplete flags on the "new" and "old" attribute/value pairs
629 * so that one disappears and one appears atomically. Then we
630 * must remove the "old" attribute/value pair.
631 */
632 if (args->op_flags & XFS_DA_OP_RENAME) {
633 /*
634 * In a separate transaction, set the incomplete flag on the
635 * "old" attr and clear the incomplete flag on the "new" attr.
636 */
637 error = xfs_attr3_leaf_flipflags(args);
638 if (error)
639 return error;
640
641 /*
642 * Dismantle the "old" attribute/value pair by removing
643 * a "remote" value (if it exists).
644 */
645 args->index = args->index2;
646 args->blkno = args->blkno2;
647 args->rmtblkno = args->rmtblkno2;
648 args->rmtblkcnt = args->rmtblkcnt2;
649 args->rmtvaluelen = args->rmtvaluelen2;
650 if (args->rmtblkno) {
651 error = xfs_attr_rmtval_remove(args);
652 if (error)
653 return error;
654 }
655
656 /*
657 * Read in the block containing the "old" attr, then
658 * remove the "old" attr from that block (neat, huh!)
659 */
660 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
661 -1, &bp);
662 if (error)
663 return error;
664
665 xfs_attr3_leaf_remove(bp, args);
666
667 /*
668 * If the result is small enough, shrink it all into the inode.
669 */
670 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
671 xfs_bmap_init(args->flist, args->firstblock);
672 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
673 /* bp is gone due to xfs_da_shrink_inode */
674 if (!error)
675 error = xfs_bmap_finish(&args->trans,
676 args->flist, dp);
677 if (error) {
678 args->trans = NULL;
679 xfs_bmap_cancel(args->flist);
680 return error;
681 }
682 }
683
684 /*
685 * Commit the remove and start the next trans in series.
686 */
687 error = xfs_trans_roll(&args->trans, dp);
688
689 } else if (args->rmtblkno > 0) {
690 /*
691 * Added a "remote" value, just clear the incomplete flag.
692 */
693 error = xfs_attr3_leaf_clearflag(args);
694 }
695 return error;
696 }
697
698 /*
699 * Remove a name from the leaf attribute list structure
700 *
701 * This leaf block cannot have a "remote" value, we only call this routine
702 * if bmap_one_block() says there is only one block (ie: no remote blks).
703 */
704 STATIC int
705 xfs_attr_leaf_removename(xfs_da_args_t *args)
706 {
707 xfs_inode_t *dp;
708 struct xfs_buf *bp;
709 int error, forkoff;
710
711 trace_xfs_attr_leaf_removename(args);
712
713 /*
714 * Remove the attribute.
715 */
716 dp = args->dp;
717 args->blkno = 0;
718 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
719 if (error)
720 return error;
721
722 error = xfs_attr3_leaf_lookup_int(bp, args);
723 if (error == -ENOATTR) {
724 xfs_trans_brelse(args->trans, bp);
725 return error;
726 }
727
728 xfs_attr3_leaf_remove(bp, args);
729
730 /*
731 * If the result is small enough, shrink it all into the inode.
732 */
733 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
734 xfs_bmap_init(args->flist, args->firstblock);
735 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
736 /* bp is gone due to xfs_da_shrink_inode */
737 if (!error)
738 error = xfs_bmap_finish(&args->trans, args->flist, dp);
739 if (error) {
740 args->trans = NULL;
741 xfs_bmap_cancel(args->flist);
742 return error;
743 }
744 }
745 return 0;
746 }
747
748 /*
749 * Look up a name in a leaf attribute list structure.
750 *
751 * This leaf block cannot have a "remote" value, we only call this routine
752 * if bmap_one_block() says there is only one block (ie: no remote blks).
753 */
754 STATIC int
755 xfs_attr_leaf_get(xfs_da_args_t *args)
756 {
757 struct xfs_buf *bp;
758 int error;
759
760 trace_xfs_attr_leaf_get(args);
761
762 args->blkno = 0;
763 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
764 if (error)
765 return error;
766
767 error = xfs_attr3_leaf_lookup_int(bp, args);
768 if (error != -EEXIST) {
769 xfs_trans_brelse(args->trans, bp);
770 return error;
771 }
772 error = xfs_attr3_leaf_getvalue(bp, args);
773 xfs_trans_brelse(args->trans, bp);
774 if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
775 error = xfs_attr_rmtval_get(args);
776 }
777 return error;
778 }
779
780 /*========================================================================
781 * External routines when attribute list size > geo->blksize
782 *========================================================================*/
783
784 /*
785 * Add a name to a Btree-format attribute list.
786 *
787 * This will involve walking down the Btree, and may involve splitting
788 * leaf nodes and even splitting intermediate nodes up to and including
789 * the root node (a special case of an intermediate node).
790 *
791 * "Remote" attribute values confuse the issue and atomic rename operations
792 * add a whole extra layer of confusion on top of that.
793 */
794 STATIC int
795 xfs_attr_node_addname(xfs_da_args_t *args)
796 {
797 xfs_da_state_t *state;
798 xfs_da_state_blk_t *blk;
799 xfs_inode_t *dp;
800 xfs_mount_t *mp;
801 int retval, error;
802
803 trace_xfs_attr_node_addname(args);
804
805 /*
806 * Fill in bucket of arguments/results/context to carry around.
807 */
808 dp = args->dp;
809 mp = dp->i_mount;
810 restart:
811 state = xfs_da_state_alloc();
812 state->args = args;
813 state->mp = mp;
814
815 /*
816 * Search to see if name already exists, and get back a pointer
817 * to where it should go.
818 */
819 error = xfs_da3_node_lookup_int(state, &retval);
820 if (error)
821 goto out;
822 blk = &state->path.blk[ state->path.active-1 ];
823 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
824 if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
825 goto out;
826 } else if (retval == -EEXIST) {
827 if (args->flags & ATTR_CREATE)
828 goto out;
829
830 trace_xfs_attr_node_replace(args);
831
832 /* save the attribute state for later removal*/
833 args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */
834 args->blkno2 = args->blkno; /* set 2nd entry info*/
835 args->index2 = args->index;
836 args->rmtblkno2 = args->rmtblkno;
837 args->rmtblkcnt2 = args->rmtblkcnt;
838 args->rmtvaluelen2 = args->rmtvaluelen;
839
840 /*
841 * clear the remote attr state now that it is saved so that the
842 * values reflect the state of the attribute we are about to
843 * add, not the attribute we just found and will remove later.
844 */
845 args->rmtblkno = 0;
846 args->rmtblkcnt = 0;
847 args->rmtvaluelen = 0;
848 }
849
850 retval = xfs_attr3_leaf_add(blk->bp, state->args);
851 if (retval == -ENOSPC) {
852 if (state->path.active == 1) {
853 /*
854 * Its really a single leaf node, but it had
855 * out-of-line values so it looked like it *might*
856 * have been a b-tree.
857 */
858 xfs_da_state_free(state);
859 state = NULL;
860 xfs_bmap_init(args->flist, args->firstblock);
861 error = xfs_attr3_leaf_to_node(args);
862 if (!error)
863 error = xfs_bmap_finish(&args->trans,
864 args->flist, dp);
865 if (error) {
866 args->trans = NULL;
867 xfs_bmap_cancel(args->flist);
868 goto out;
869 }
870
871 /*
872 * Commit the node conversion and start the next
873 * trans in the chain.
874 */
875 error = xfs_trans_roll(&args->trans, dp);
876 if (error)
877 goto out;
878
879 goto restart;
880 }
881
882 /*
883 * Split as many Btree elements as required.
884 * This code tracks the new and old attr's location
885 * in the index/blkno/rmtblkno/rmtblkcnt fields and
886 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
887 */
888 xfs_bmap_init(args->flist, args->firstblock);
889 error = xfs_da3_split(state);
890 if (!error)
891 error = xfs_bmap_finish(&args->trans, args->flist, dp);
892 if (error) {
893 args->trans = NULL;
894 xfs_bmap_cancel(args->flist);
895 goto out;
896 }
897 } else {
898 /*
899 * Addition succeeded, update Btree hashvals.
900 */
901 xfs_da3_fixhashpath(state, &state->path);
902 }
903
904 /*
905 * Kill the state structure, we're done with it and need to
906 * allow the buffers to come back later.
907 */
908 xfs_da_state_free(state);
909 state = NULL;
910
911 /*
912 * Commit the leaf addition or btree split and start the next
913 * trans in the chain.
914 */
915 error = xfs_trans_roll(&args->trans, dp);
916 if (error)
917 goto out;
918
919 /*
920 * If there was an out-of-line value, allocate the blocks we
921 * identified for its storage and copy the value. This is done
922 * after we create the attribute so that we don't overflow the
923 * maximum size of a transaction and/or hit a deadlock.
924 */
925 if (args->rmtblkno > 0) {
926 error = xfs_attr_rmtval_set(args);
927 if (error)
928 return error;
929 }
930
931 /*
932 * If this is an atomic rename operation, we must "flip" the
933 * incomplete flags on the "new" and "old" attribute/value pairs
934 * so that one disappears and one appears atomically. Then we
935 * must remove the "old" attribute/value pair.
936 */
937 if (args->op_flags & XFS_DA_OP_RENAME) {
938 /*
939 * In a separate transaction, set the incomplete flag on the
940 * "old" attr and clear the incomplete flag on the "new" attr.
941 */
942 error = xfs_attr3_leaf_flipflags(args);
943 if (error)
944 goto out;
945
946 /*
947 * Dismantle the "old" attribute/value pair by removing
948 * a "remote" value (if it exists).
949 */
950 args->index = args->index2;
951 args->blkno = args->blkno2;
952 args->rmtblkno = args->rmtblkno2;
953 args->rmtblkcnt = args->rmtblkcnt2;
954 args->rmtvaluelen = args->rmtvaluelen2;
955 if (args->rmtblkno) {
956 error = xfs_attr_rmtval_remove(args);
957 if (error)
958 return error;
959 }
960
961 /*
962 * Re-find the "old" attribute entry after any split ops.
963 * The INCOMPLETE flag means that we will find the "old"
964 * attr, not the "new" one.
965 */
966 args->flags |= XFS_ATTR_INCOMPLETE;
967 state = xfs_da_state_alloc();
968 state->args = args;
969 state->mp = mp;
970 state->inleaf = 0;
971 error = xfs_da3_node_lookup_int(state, &retval);
972 if (error)
973 goto out;
974
975 /*
976 * Remove the name and update the hashvals in the tree.
977 */
978 blk = &state->path.blk[ state->path.active-1 ];
979 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
980 error = xfs_attr3_leaf_remove(blk->bp, args);
981 xfs_da3_fixhashpath(state, &state->path);
982
983 /*
984 * Check to see if the tree needs to be collapsed.
985 */
986 if (retval && (state->path.active > 1)) {
987 xfs_bmap_init(args->flist, args->firstblock);
988 error = xfs_da3_join(state);
989 if (!error)
990 error = xfs_bmap_finish(&args->trans,
991 args->flist, dp);
992 if (error) {
993 args->trans = NULL;
994 xfs_bmap_cancel(args->flist);
995 goto out;
996 }
997 }
998
999 /*
1000 * Commit and start the next trans in the chain.
1001 */
1002 error = xfs_trans_roll(&args->trans, dp);
1003 if (error)
1004 goto out;
1005
1006 } else if (args->rmtblkno > 0) {
1007 /*
1008 * Added a "remote" value, just clear the incomplete flag.
1009 */
1010 error = xfs_attr3_leaf_clearflag(args);
1011 if (error)
1012 goto out;
1013 }
1014 retval = error = 0;
1015
1016 out:
1017 if (state)
1018 xfs_da_state_free(state);
1019 if (error)
1020 return error;
1021 return retval;
1022 }
1023
1024 /*
1025 * Remove a name from a B-tree attribute list.
1026 *
1027 * This will involve walking down the Btree, and may involve joining
1028 * leaf nodes and even joining intermediate nodes up to and including
1029 * the root node (a special case of an intermediate node).
1030 */
1031 STATIC int
1032 xfs_attr_node_removename(xfs_da_args_t *args)
1033 {
1034 xfs_da_state_t *state;
1035 xfs_da_state_blk_t *blk;
1036 xfs_inode_t *dp;
1037 struct xfs_buf *bp;
1038 int retval, error, forkoff;
1039
1040 trace_xfs_attr_node_removename(args);
1041
1042 /*
1043 * Tie a string around our finger to remind us where we are.
1044 */
1045 dp = args->dp;
1046 state = xfs_da_state_alloc();
1047 state->args = args;
1048 state->mp = dp->i_mount;
1049
1050 /*
1051 * Search to see if name exists, and get back a pointer to it.
1052 */
1053 error = xfs_da3_node_lookup_int(state, &retval);
1054 if (error || (retval != -EEXIST)) {
1055 if (error == 0)
1056 error = retval;
1057 goto out;
1058 }
1059
1060 /*
1061 * If there is an out-of-line value, de-allocate the blocks.
1062 * This is done before we remove the attribute so that we don't
1063 * overflow the maximum size of a transaction and/or hit a deadlock.
1064 */
1065 blk = &state->path.blk[ state->path.active-1 ];
1066 ASSERT(blk->bp != NULL);
1067 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1068 if (args->rmtblkno > 0) {
1069 /*
1070 * Fill in disk block numbers in the state structure
1071 * so that we can get the buffers back after we commit
1072 * several transactions in the following calls.
1073 */
1074 error = xfs_attr_fillstate(state);
1075 if (error)
1076 goto out;
1077
1078 /*
1079 * Mark the attribute as INCOMPLETE, then bunmapi() the
1080 * remote value.
1081 */
1082 error = xfs_attr3_leaf_setflag(args);
1083 if (error)
1084 goto out;
1085 error = xfs_attr_rmtval_remove(args);
1086 if (error)
1087 goto out;
1088
1089 /*
1090 * Refill the state structure with buffers, the prior calls
1091 * released our buffers.
1092 */
1093 error = xfs_attr_refillstate(state);
1094 if (error)
1095 goto out;
1096 }
1097
1098 /*
1099 * Remove the name and update the hashvals in the tree.
1100 */
1101 blk = &state->path.blk[ state->path.active-1 ];
1102 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1103 retval = xfs_attr3_leaf_remove(blk->bp, args);
1104 xfs_da3_fixhashpath(state, &state->path);
1105
1106 /*
1107 * Check to see if the tree needs to be collapsed.
1108 */
1109 if (retval && (state->path.active > 1)) {
1110 xfs_bmap_init(args->flist, args->firstblock);
1111 error = xfs_da3_join(state);
1112 if (!error)
1113 error = xfs_bmap_finish(&args->trans, args->flist, dp);
1114 if (error) {
1115 args->trans = NULL;
1116 xfs_bmap_cancel(args->flist);
1117 goto out;
1118 }
1119 /*
1120 * Commit the Btree join operation and start a new trans.
1121 */
1122 error = xfs_trans_roll(&args->trans, dp);
1123 if (error)
1124 goto out;
1125 }
1126
1127 /*
1128 * If the result is small enough, push it all into the inode.
1129 */
1130 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
1131 /*
1132 * Have to get rid of the copy of this dabuf in the state.
1133 */
1134 ASSERT(state->path.active == 1);
1135 ASSERT(state->path.blk[0].bp);
1136 state->path.blk[0].bp = NULL;
1137
1138 error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp);
1139 if (error)
1140 goto out;
1141
1142 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1143 xfs_bmap_init(args->flist, args->firstblock);
1144 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1145 /* bp is gone due to xfs_da_shrink_inode */
1146 if (!error)
1147 error = xfs_bmap_finish(&args->trans,
1148 args->flist, dp);
1149 if (error) {
1150 args->trans = NULL;
1151 xfs_bmap_cancel(args->flist);
1152 goto out;
1153 }
1154 } else
1155 xfs_trans_brelse(args->trans, bp);
1156 }
1157 error = 0;
1158
1159 out:
1160 xfs_da_state_free(state);
1161 return error;
1162 }
1163
1164 /*
1165 * Fill in the disk block numbers in the state structure for the buffers
1166 * that are attached to the state structure.
1167 * This is done so that we can quickly reattach ourselves to those buffers
1168 * after some set of transaction commits have released these buffers.
1169 */
1170 STATIC int
1171 xfs_attr_fillstate(xfs_da_state_t *state)
1172 {
1173 xfs_da_state_path_t *path;
1174 xfs_da_state_blk_t *blk;
1175 int level;
1176
1177 trace_xfs_attr_fillstate(state->args);
1178
1179 /*
1180 * Roll down the "path" in the state structure, storing the on-disk
1181 * block number for those buffers in the "path".
1182 */
1183 path = &state->path;
1184 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1185 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1186 if (blk->bp) {
1187 blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
1188 blk->bp = NULL;
1189 } else {
1190 blk->disk_blkno = 0;
1191 }
1192 }
1193
1194 /*
1195 * Roll down the "altpath" in the state structure, storing the on-disk
1196 * block number for those buffers in the "altpath".
1197 */
1198 path = &state->altpath;
1199 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1200 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1201 if (blk->bp) {
1202 blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
1203 blk->bp = NULL;
1204 } else {
1205 blk->disk_blkno = 0;
1206 }
1207 }
1208
1209 return 0;
1210 }
1211
1212 /*
1213 * Reattach the buffers to the state structure based on the disk block
1214 * numbers stored in the state structure.
1215 * This is done after some set of transaction commits have released those
1216 * buffers from our grip.
1217 */
1218 STATIC int
1219 xfs_attr_refillstate(xfs_da_state_t *state)
1220 {
1221 xfs_da_state_path_t *path;
1222 xfs_da_state_blk_t *blk;
1223 int level, error;
1224
1225 trace_xfs_attr_refillstate(state->args);
1226
1227 /*
1228 * Roll down the "path" in the state structure, storing the on-disk
1229 * block number for those buffers in the "path".
1230 */
1231 path = &state->path;
1232 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1233 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1234 if (blk->disk_blkno) {
1235 error = xfs_da3_node_read(state->args->trans,
1236 state->args->dp,
1237 blk->blkno, blk->disk_blkno,
1238 &blk->bp, XFS_ATTR_FORK);
1239 if (error)
1240 return error;
1241 } else {
1242 blk->bp = NULL;
1243 }
1244 }
1245
1246 /*
1247 * Roll down the "altpath" in the state structure, storing the on-disk
1248 * block number for those buffers in the "altpath".
1249 */
1250 path = &state->altpath;
1251 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1252 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1253 if (blk->disk_blkno) {
1254 error = xfs_da3_node_read(state->args->trans,
1255 state->args->dp,
1256 blk->blkno, blk->disk_blkno,
1257 &blk->bp, XFS_ATTR_FORK);
1258 if (error)
1259 return error;
1260 } else {
1261 blk->bp = NULL;
1262 }
1263 }
1264
1265 return 0;
1266 }
1267
1268 /*
1269 * Look up a filename in a node attribute list.
1270 *
1271 * This routine gets called for any attribute fork that has more than one
1272 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1273 * "remote" values taking up more blocks.
1274 */
1275 STATIC int
1276 xfs_attr_node_get(xfs_da_args_t *args)
1277 {
1278 xfs_da_state_t *state;
1279 xfs_da_state_blk_t *blk;
1280 int error, retval;
1281 int i;
1282
1283 trace_xfs_attr_node_get(args);
1284
1285 state = xfs_da_state_alloc();
1286 state->args = args;
1287 state->mp = args->dp->i_mount;
1288
1289 /*
1290 * Search to see if name exists, and get back a pointer to it.
1291 */
1292 error = xfs_da3_node_lookup_int(state, &retval);
1293 if (error) {
1294 retval = error;
1295 } else if (retval == -EEXIST) {
1296 blk = &state->path.blk[ state->path.active-1 ];
1297 ASSERT(blk->bp != NULL);
1298 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1299
1300 /*
1301 * Get the value, local or "remote"
1302 */
1303 retval = xfs_attr3_leaf_getvalue(blk->bp, args);
1304 if (!retval && (args->rmtblkno > 0)
1305 && !(args->flags & ATTR_KERNOVAL)) {
1306 retval = xfs_attr_rmtval_get(args);
1307 }
1308 }
1309
1310 /*
1311 * If not in a transaction, we have to release all the buffers.
1312 */
1313 for (i = 0; i < state->path.active; i++) {
1314 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1315 state->path.blk[i].bp = NULL;
1316 }
1317
1318 xfs_da_state_free(state);
1319 return retval;
1320 }