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