]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - fs/xfs/xfs_attr.c
ocfs2: fix the end cluster offset of FIEMAP
[linux-3.10.git] / fs / xfs / 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_types.h"
21 #include "xfs_bit.h"
22 #include "xfs_log.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_mount.h"
27 #include "xfs_da_btree.h"
28 #include "xfs_bmap_btree.h"
29 #include "xfs_attr_sf.h"
30 #include "xfs_dinode.h"
31 #include "xfs_inode.h"
32 #include "xfs_alloc.h"
33 #include "xfs_inode_item.h"
34 #include "xfs_bmap.h"
35 #include "xfs_attr.h"
36 #include "xfs_attr_leaf.h"
37 #include "xfs_attr_remote.h"
38 #include "xfs_error.h"
39 #include "xfs_quota.h"
40 #include "xfs_trans_space.h"
41 #include "xfs_vnodeops.h"
42 #include "xfs_trace.h"
43
44 /*
45  * xfs_attr.c
46  *
47  * Provide the external interfaces to manage attribute lists.
48  */
49
50 /*========================================================================
51  * Function prototypes for the kernel.
52  *========================================================================*/
53
54 /*
55  * Internal routines when attribute list fits inside the inode.
56  */
57 STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
58
59 /*
60  * Internal routines when attribute list is one block.
61  */
62 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
63 STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
64 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
65 STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
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_node_list(xfs_attr_list_context_t *context);
74 STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
75 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
76
77
78 STATIC int
79 xfs_attr_name_to_xname(
80         struct xfs_name *xname,
81         const unsigned char *aname)
82 {
83         if (!aname)
84                 return EINVAL;
85         xname->name = aname;
86         xname->len = strlen((char *)aname);
87         if (xname->len >= MAXNAMELEN)
88                 return EFAULT;          /* match IRIX behaviour */
89
90         return 0;
91 }
92
93 STATIC int
94 xfs_inode_hasattr(
95         struct xfs_inode        *ip)
96 {
97         if (!XFS_IFORK_Q(ip) ||
98             (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
99              ip->i_d.di_anextents == 0))
100                 return 0;
101         return 1;
102 }
103
104 /*========================================================================
105  * Overall external interface routines.
106  *========================================================================*/
107
108 STATIC int
109 xfs_attr_get_int(
110         struct xfs_inode        *ip,
111         struct xfs_name         *name,
112         unsigned char           *value,
113         int                     *valuelenp,
114         int                     flags)
115 {
116         xfs_da_args_t   args;
117         int             error;
118
119         if (!xfs_inode_hasattr(ip))
120                 return ENOATTR;
121
122         /*
123          * Fill in the arg structure for this request.
124          */
125         memset((char *)&args, 0, sizeof(args));
126         args.name = name->name;
127         args.namelen = name->len;
128         args.value = value;
129         args.valuelen = *valuelenp;
130         args.flags = flags;
131         args.hashval = xfs_da_hashname(args.name, args.namelen);
132         args.dp = ip;
133         args.whichfork = XFS_ATTR_FORK;
134
135         /*
136          * Decide on what work routines to call based on the inode size.
137          */
138         if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
139                 error = xfs_attr_shortform_getvalue(&args);
140         } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) {
141                 error = xfs_attr_leaf_get(&args);
142         } else {
143                 error = xfs_attr_node_get(&args);
144         }
145
146         /*
147          * Return the number of bytes in the value to the caller.
148          */
149         *valuelenp = args.valuelen;
150
151         if (error == EEXIST)
152                 error = 0;
153         return(error);
154 }
155
156 int
157 xfs_attr_get(
158         xfs_inode_t     *ip,
159         const unsigned char *name,
160         unsigned char   *value,
161         int             *valuelenp,
162         int             flags)
163 {
164         int             error;
165         struct xfs_name xname;
166
167         XFS_STATS_INC(xs_attr_get);
168
169         if (XFS_FORCED_SHUTDOWN(ip->i_mount))
170                 return(EIO);
171
172         error = xfs_attr_name_to_xname(&xname, name);
173         if (error)
174                 return error;
175
176         xfs_ilock(ip, XFS_ILOCK_SHARED);
177         error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags);
178         xfs_iunlock(ip, XFS_ILOCK_SHARED);
179         return(error);
180 }
181
182 /*
183  * Calculate how many blocks we need for the new attribute,
184  */
185 STATIC int
186 xfs_attr_calc_size(
187         struct xfs_inode        *ip,
188         int                     namelen,
189         int                     valuelen,
190         int                     *local)
191 {
192         struct xfs_mount        *mp = ip->i_mount;
193         int                     size;
194         int                     nblks;
195
196         /*
197          * Determine space new attribute will use, and if it would be
198          * "local" or "remote" (note: local != inline).
199          */
200         size = xfs_attr_leaf_newentsize(namelen, valuelen,
201                                         mp->m_sb.sb_blocksize, local);
202
203         nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
204         if (*local) {
205                 if (size > (mp->m_sb.sb_blocksize >> 1)) {
206                         /* Double split possible */
207                         nblks *= 2;
208                 }
209         } else {
210                 /*
211                  * Out of line attribute, cannot double split, but
212                  * make room for the attribute value itself.
213                  */
214                 uint    dblocks = XFS_B_TO_FSB(mp, valuelen);
215                 nblks += dblocks;
216                 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
217         }
218
219         return nblks;
220 }
221
222 STATIC int
223 xfs_attr_set_int(
224         struct xfs_inode *dp,
225         struct xfs_name *name,
226         unsigned char   *value,
227         int             valuelen,
228         int             flags)
229 {
230         xfs_da_args_t   args;
231         xfs_fsblock_t   firstblock;
232         xfs_bmap_free_t flist;
233         int             error, err2, committed;
234         xfs_mount_t     *mp = dp->i_mount;
235         int             rsvd = (flags & ATTR_ROOT) != 0;
236         int             local;
237
238         /*
239          * Attach the dquots to the inode.
240          */
241         error = xfs_qm_dqattach(dp, 0);
242         if (error)
243                 return error;
244
245         /*
246          * If the inode doesn't have an attribute fork, add one.
247          * (inode must not be locked when we call this routine)
248          */
249         if (XFS_IFORK_Q(dp) == 0) {
250                 int sf_size = sizeof(xfs_attr_sf_hdr_t) +
251                               XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen);
252
253                 if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd)))
254                         return(error);
255         }
256
257         /*
258          * Fill in the arg structure for this request.
259          */
260         memset((char *)&args, 0, sizeof(args));
261         args.name = name->name;
262         args.namelen = name->len;
263         args.value = value;
264         args.valuelen = valuelen;
265         args.flags = flags;
266         args.hashval = xfs_da_hashname(args.name, args.namelen);
267         args.dp = dp;
268         args.firstblock = &firstblock;
269         args.flist = &flist;
270         args.whichfork = XFS_ATTR_FORK;
271         args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
272
273         /* Size is now blocks for attribute data */
274         args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local);
275
276         /*
277          * Start our first transaction of the day.
278          *
279          * All future transactions during this code must be "chained" off
280          * this one via the trans_dup() call.  All transactions will contain
281          * the inode, and the inode will always be marked with trans_ihold().
282          * Since the inode will be locked in all transactions, we must log
283          * the inode in every transaction to let it float upward through
284          * the log.
285          */
286         args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET);
287
288         /*
289          * Root fork attributes can use reserved data blocks for this
290          * operation if necessary
291          */
292
293         if (rsvd)
294                 args.trans->t_flags |= XFS_TRANS_RESERVE;
295
296         error = xfs_trans_reserve(args.trans, args.total,
297                                   XFS_ATTRSETM_LOG_RES(mp) +
298                                   XFS_ATTRSETRT_LOG_RES(mp) * args.total,
299                                   0, XFS_TRANS_PERM_LOG_RES,
300                                   XFS_ATTRSET_LOG_COUNT);
301         if (error) {
302                 xfs_trans_cancel(args.trans, 0);
303                 return(error);
304         }
305         xfs_ilock(dp, XFS_ILOCK_EXCL);
306
307         error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
308                                 rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
309                                        XFS_QMOPT_RES_REGBLKS);
310         if (error) {
311                 xfs_iunlock(dp, XFS_ILOCK_EXCL);
312                 xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
313                 return (error);
314         }
315
316         xfs_trans_ijoin(args.trans, dp, 0);
317
318         /*
319          * If the attribute list is non-existent or a shortform list,
320          * upgrade it to a single-leaf-block attribute list.
321          */
322         if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
323             ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) &&
324              (dp->i_d.di_anextents == 0))) {
325
326                 /*
327                  * Build initial attribute list (if required).
328                  */
329                 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
330                         xfs_attr_shortform_create(&args);
331
332                 /*
333                  * Try to add the attr to the attribute list in
334                  * the inode.
335                  */
336                 error = xfs_attr_shortform_addname(&args);
337                 if (error != ENOSPC) {
338                         /*
339                          * Commit the shortform mods, and we're done.
340                          * NOTE: this is also the error path (EEXIST, etc).
341                          */
342                         ASSERT(args.trans != NULL);
343
344                         /*
345                          * If this is a synchronous mount, make sure that
346                          * the transaction goes to disk before returning
347                          * to the user.
348                          */
349                         if (mp->m_flags & XFS_MOUNT_WSYNC) {
350                                 xfs_trans_set_sync(args.trans);
351                         }
352
353                         if (!error && (flags & ATTR_KERNOTIME) == 0) {
354                                 xfs_trans_ichgtime(args.trans, dp,
355                                                         XFS_ICHGTIME_CHG);
356                         }
357                         err2 = xfs_trans_commit(args.trans,
358                                                  XFS_TRANS_RELEASE_LOG_RES);
359                         xfs_iunlock(dp, XFS_ILOCK_EXCL);
360
361                         return(error == 0 ? err2 : error);
362                 }
363
364                 /*
365                  * It won't fit in the shortform, transform to a leaf block.
366                  * GROT: another possible req'mt for a double-split btree op.
367                  */
368                 xfs_bmap_init(args.flist, args.firstblock);
369                 error = xfs_attr_shortform_to_leaf(&args);
370                 if (!error) {
371                         error = xfs_bmap_finish(&args.trans, args.flist,
372                                                 &committed);
373                 }
374                 if (error) {
375                         ASSERT(committed);
376                         args.trans = NULL;
377                         xfs_bmap_cancel(&flist);
378                         goto out;
379                 }
380
381                 /*
382                  * bmap_finish() may have committed the last trans and started
383                  * a new one.  We need the inode to be in all transactions.
384                  */
385                 if (committed)
386                         xfs_trans_ijoin(args.trans, dp, 0);
387
388                 /*
389                  * Commit the leaf transformation.  We'll need another (linked)
390                  * transaction to add the new attribute to the leaf.
391                  */
392
393                 error = xfs_trans_roll(&args.trans, dp);
394                 if (error)
395                         goto out;
396
397         }
398
399         if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
400                 error = xfs_attr_leaf_addname(&args);
401         } else {
402                 error = xfs_attr_node_addname(&args);
403         }
404         if (error) {
405                 goto out;
406         }
407
408         /*
409          * If this is a synchronous mount, make sure that the
410          * transaction goes to disk before returning to the user.
411          */
412         if (mp->m_flags & XFS_MOUNT_WSYNC) {
413                 xfs_trans_set_sync(args.trans);
414         }
415
416         if ((flags & ATTR_KERNOTIME) == 0)
417                 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
418
419         /*
420          * Commit the last in the sequence of transactions.
421          */
422         xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
423         error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
424         xfs_iunlock(dp, XFS_ILOCK_EXCL);
425
426         return(error);
427
428 out:
429         if (args.trans)
430                 xfs_trans_cancel(args.trans,
431                         XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
432         xfs_iunlock(dp, XFS_ILOCK_EXCL);
433         return(error);
434 }
435
436 int
437 xfs_attr_set(
438         xfs_inode_t     *dp,
439         const unsigned char *name,
440         unsigned char   *value,
441         int             valuelen,
442         int             flags)
443 {
444         int             error;
445         struct xfs_name xname;
446
447         XFS_STATS_INC(xs_attr_set);
448
449         if (XFS_FORCED_SHUTDOWN(dp->i_mount))
450                 return (EIO);
451
452         error = xfs_attr_name_to_xname(&xname, name);
453         if (error)
454                 return error;
455
456         return xfs_attr_set_int(dp, &xname, value, valuelen, flags);
457 }
458
459 /*
460  * Generic handler routine to remove a name from an attribute list.
461  * Transitions attribute list from Btree to shortform as necessary.
462  */
463 STATIC int
464 xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
465 {
466         xfs_da_args_t   args;
467         xfs_fsblock_t   firstblock;
468         xfs_bmap_free_t flist;
469         int             error;
470         xfs_mount_t     *mp = dp->i_mount;
471
472         /*
473          * Fill in the arg structure for this request.
474          */
475         memset((char *)&args, 0, sizeof(args));
476         args.name = name->name;
477         args.namelen = name->len;
478         args.flags = flags;
479         args.hashval = xfs_da_hashname(args.name, args.namelen);
480         args.dp = dp;
481         args.firstblock = &firstblock;
482         args.flist = &flist;
483         args.total = 0;
484         args.whichfork = XFS_ATTR_FORK;
485
486         /*
487          * we have no control over the attribute names that userspace passes us
488          * to remove, so we have to allow the name lookup prior to attribute
489          * removal to fail.
490          */
491         args.op_flags = XFS_DA_OP_OKNOENT;
492
493         /*
494          * Attach the dquots to the inode.
495          */
496         error = xfs_qm_dqattach(dp, 0);
497         if (error)
498                 return error;
499
500         /*
501          * Start our first transaction of the day.
502          *
503          * All future transactions during this code must be "chained" off
504          * this one via the trans_dup() call.  All transactions will contain
505          * the inode, and the inode will always be marked with trans_ihold().
506          * Since the inode will be locked in all transactions, we must log
507          * the inode in every transaction to let it float upward through
508          * the log.
509          */
510         args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM);
511
512         /*
513          * Root fork attributes can use reserved data blocks for this
514          * operation if necessary
515          */
516
517         if (flags & ATTR_ROOT)
518                 args.trans->t_flags |= XFS_TRANS_RESERVE;
519
520         if ((error = xfs_trans_reserve(args.trans,
521                                       XFS_ATTRRM_SPACE_RES(mp),
522                                       XFS_ATTRRM_LOG_RES(mp),
523                                       0, XFS_TRANS_PERM_LOG_RES,
524                                       XFS_ATTRRM_LOG_COUNT))) {
525                 xfs_trans_cancel(args.trans, 0);
526                 return(error);
527         }
528
529         xfs_ilock(dp, XFS_ILOCK_EXCL);
530         /*
531          * No need to make quota reservations here. We expect to release some
532          * blocks not allocate in the common case.
533          */
534         xfs_trans_ijoin(args.trans, dp, 0);
535
536         /*
537          * Decide on what work routines to call based on the inode size.
538          */
539         if (!xfs_inode_hasattr(dp)) {
540                 error = XFS_ERROR(ENOATTR);
541                 goto out;
542         }
543         if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
544                 ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
545                 error = xfs_attr_shortform_remove(&args);
546                 if (error) {
547                         goto out;
548                 }
549         } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
550                 error = xfs_attr_leaf_removename(&args);
551         } else {
552                 error = xfs_attr_node_removename(&args);
553         }
554         if (error) {
555                 goto out;
556         }
557
558         /*
559          * If this is a synchronous mount, make sure that the
560          * transaction goes to disk before returning to the user.
561          */
562         if (mp->m_flags & XFS_MOUNT_WSYNC) {
563                 xfs_trans_set_sync(args.trans);
564         }
565
566         if ((flags & ATTR_KERNOTIME) == 0)
567                 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
568
569         /*
570          * Commit the last in the sequence of transactions.
571          */
572         xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
573         error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
574         xfs_iunlock(dp, XFS_ILOCK_EXCL);
575
576         return(error);
577
578 out:
579         if (args.trans)
580                 xfs_trans_cancel(args.trans,
581                         XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
582         xfs_iunlock(dp, XFS_ILOCK_EXCL);
583         return(error);
584 }
585
586 int
587 xfs_attr_remove(
588         xfs_inode_t     *dp,
589         const unsigned char *name,
590         int             flags)
591 {
592         int             error;
593         struct xfs_name xname;
594
595         XFS_STATS_INC(xs_attr_remove);
596
597         if (XFS_FORCED_SHUTDOWN(dp->i_mount))
598                 return (EIO);
599
600         error = xfs_attr_name_to_xname(&xname, name);
601         if (error)
602                 return error;
603
604         xfs_ilock(dp, XFS_ILOCK_SHARED);
605         if (!xfs_inode_hasattr(dp)) {
606                 xfs_iunlock(dp, XFS_ILOCK_SHARED);
607                 return XFS_ERROR(ENOATTR);
608         }
609         xfs_iunlock(dp, XFS_ILOCK_SHARED);
610
611         return xfs_attr_remove_int(dp, &xname, flags);
612 }
613
614 int
615 xfs_attr_list_int(xfs_attr_list_context_t *context)
616 {
617         int error;
618         xfs_inode_t *dp = context->dp;
619
620         XFS_STATS_INC(xs_attr_list);
621
622         if (XFS_FORCED_SHUTDOWN(dp->i_mount))
623                 return EIO;
624
625         xfs_ilock(dp, XFS_ILOCK_SHARED);
626
627         /*
628          * Decide on what work routines to call based on the inode size.
629          */
630         if (!xfs_inode_hasattr(dp)) {
631                 error = 0;
632         } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
633                 error = xfs_attr_shortform_list(context);
634         } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
635                 error = xfs_attr_leaf_list(context);
636         } else {
637                 error = xfs_attr_node_list(context);
638         }
639
640         xfs_iunlock(dp, XFS_ILOCK_SHARED);
641
642         return error;
643 }
644
645 #define ATTR_ENTBASESIZE                /* minimum bytes used by an attr */ \
646         (((struct attrlist_ent *) 0)->a_name - (char *) 0)
647 #define ATTR_ENTSIZE(namelen)           /* actual bytes used by an attr */ \
648         ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
649          & ~(sizeof(u_int32_t)-1))
650
651 /*
652  * Format an attribute and copy it out to the user's buffer.
653  * Take care to check values and protect against them changing later,
654  * we may be reading them directly out of a user buffer.
655  */
656 /*ARGSUSED*/
657 STATIC int
658 xfs_attr_put_listent(
659         xfs_attr_list_context_t *context,
660         int             flags,
661         unsigned char   *name,
662         int             namelen,
663         int             valuelen,
664         unsigned char   *value)
665 {
666         struct attrlist *alist = (struct attrlist *)context->alist;
667         attrlist_ent_t *aep;
668         int arraytop;
669
670         ASSERT(!(context->flags & ATTR_KERNOVAL));
671         ASSERT(context->count >= 0);
672         ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
673         ASSERT(context->firstu >= sizeof(*alist));
674         ASSERT(context->firstu <= context->bufsize);
675
676         /*
677          * Only list entries in the right namespace.
678          */
679         if (((context->flags & ATTR_SECURE) == 0) !=
680             ((flags & XFS_ATTR_SECURE) == 0))
681                 return 0;
682         if (((context->flags & ATTR_ROOT) == 0) !=
683             ((flags & XFS_ATTR_ROOT) == 0))
684                 return 0;
685
686         arraytop = sizeof(*alist) +
687                         context->count * sizeof(alist->al_offset[0]);
688         context->firstu -= ATTR_ENTSIZE(namelen);
689         if (context->firstu < arraytop) {
690                 trace_xfs_attr_list_full(context);
691                 alist->al_more = 1;
692                 context->seen_enough = 1;
693                 return 1;
694         }
695
696         aep = (attrlist_ent_t *)&context->alist[context->firstu];
697         aep->a_valuelen = valuelen;
698         memcpy(aep->a_name, name, namelen);
699         aep->a_name[namelen] = 0;
700         alist->al_offset[context->count++] = context->firstu;
701         alist->al_count = context->count;
702         trace_xfs_attr_list_add(context);
703         return 0;
704 }
705
706 /*
707  * Generate a list of extended attribute names and optionally
708  * also value lengths.  Positive return value follows the XFS
709  * convention of being an error, zero or negative return code
710  * is the length of the buffer returned (negated), indicating
711  * success.
712  */
713 int
714 xfs_attr_list(
715         xfs_inode_t     *dp,
716         char            *buffer,
717         int             bufsize,
718         int             flags,
719         attrlist_cursor_kern_t *cursor)
720 {
721         xfs_attr_list_context_t context;
722         struct attrlist *alist;
723         int error;
724
725         /*
726          * Validate the cursor.
727          */
728         if (cursor->pad1 || cursor->pad2)
729                 return(XFS_ERROR(EINVAL));
730         if ((cursor->initted == 0) &&
731             (cursor->hashval || cursor->blkno || cursor->offset))
732                 return XFS_ERROR(EINVAL);
733
734         /*
735          * Check for a properly aligned buffer.
736          */
737         if (((long)buffer) & (sizeof(int)-1))
738                 return XFS_ERROR(EFAULT);
739         if (flags & ATTR_KERNOVAL)
740                 bufsize = 0;
741
742         /*
743          * Initialize the output buffer.
744          */
745         memset(&context, 0, sizeof(context));
746         context.dp = dp;
747         context.cursor = cursor;
748         context.resynch = 1;
749         context.flags = flags;
750         context.alist = buffer;
751         context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
752         context.firstu = context.bufsize;
753         context.put_listent = xfs_attr_put_listent;
754
755         alist = (struct attrlist *)context.alist;
756         alist->al_count = 0;
757         alist->al_more = 0;
758         alist->al_offset[0] = context.bufsize;
759
760         error = xfs_attr_list_int(&context);
761         ASSERT(error >= 0);
762         return error;
763 }
764
765 int                                                             /* error */
766 xfs_attr_inactive(xfs_inode_t *dp)
767 {
768         xfs_trans_t *trans;
769         xfs_mount_t *mp;
770         int error;
771
772         mp = dp->i_mount;
773         ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
774
775         xfs_ilock(dp, XFS_ILOCK_SHARED);
776         if (!xfs_inode_hasattr(dp) ||
777             dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
778                 xfs_iunlock(dp, XFS_ILOCK_SHARED);
779                 return 0;
780         }
781         xfs_iunlock(dp, XFS_ILOCK_SHARED);
782
783         /*
784          * Start our first transaction of the day.
785          *
786          * All future transactions during this code must be "chained" off
787          * this one via the trans_dup() call.  All transactions will contain
788          * the inode, and the inode will always be marked with trans_ihold().
789          * Since the inode will be locked in all transactions, we must log
790          * the inode in every transaction to let it float upward through
791          * the log.
792          */
793         trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL);
794         if ((error = xfs_trans_reserve(trans, 0, XFS_ATTRINVAL_LOG_RES(mp), 0,
795                                       XFS_TRANS_PERM_LOG_RES,
796                                       XFS_ATTRINVAL_LOG_COUNT))) {
797                 xfs_trans_cancel(trans, 0);
798                 return(error);
799         }
800         xfs_ilock(dp, XFS_ILOCK_EXCL);
801
802         /*
803          * No need to make quota reservations here. We expect to release some
804          * blocks, not allocate, in the common case.
805          */
806         xfs_trans_ijoin(trans, dp, 0);
807
808         /*
809          * Decide on what work routines to call based on the inode size.
810          */
811         if (!xfs_inode_hasattr(dp) ||
812             dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
813                 error = 0;
814                 goto out;
815         }
816         error = xfs_attr3_root_inactive(&trans, dp);
817         if (error)
818                 goto out;
819
820         error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
821         if (error)
822                 goto out;
823
824         error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES);
825         xfs_iunlock(dp, XFS_ILOCK_EXCL);
826
827         return(error);
828
829 out:
830         xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
831         xfs_iunlock(dp, XFS_ILOCK_EXCL);
832         return(error);
833 }
834
835
836
837 /*========================================================================
838  * External routines when attribute list is inside the inode
839  *========================================================================*/
840
841 /*
842  * Add a name to the shortform attribute list structure
843  * This is the external routine.
844  */
845 STATIC int
846 xfs_attr_shortform_addname(xfs_da_args_t *args)
847 {
848         int newsize, forkoff, retval;
849
850         trace_xfs_attr_sf_addname(args);
851
852         retval = xfs_attr_shortform_lookup(args);
853         if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
854                 return(retval);
855         } else if (retval == EEXIST) {
856                 if (args->flags & ATTR_CREATE)
857                         return(retval);
858                 retval = xfs_attr_shortform_remove(args);
859                 ASSERT(retval == 0);
860         }
861
862         if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
863             args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
864                 return(XFS_ERROR(ENOSPC));
865
866         newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
867         newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
868
869         forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
870         if (!forkoff)
871                 return(XFS_ERROR(ENOSPC));
872
873         xfs_attr_shortform_add(args, forkoff);
874         return(0);
875 }
876
877
878 /*========================================================================
879  * External routines when attribute list is one block
880  *========================================================================*/
881
882 /*
883  * Add a name to the leaf attribute list structure
884  *
885  * This leaf block cannot have a "remote" value, we only call this routine
886  * if bmap_one_block() says there is only one block (ie: no remote blks).
887  */
888 STATIC int
889 xfs_attr_leaf_addname(xfs_da_args_t *args)
890 {
891         xfs_inode_t *dp;
892         struct xfs_buf *bp;
893         int retval, error, committed, forkoff;
894
895         trace_xfs_attr_leaf_addname(args);
896
897         /*
898          * Read the (only) block in the attribute list in.
899          */
900         dp = args->dp;
901         args->blkno = 0;
902         error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
903         if (error)
904                 return error;
905
906         /*
907          * Look up the given attribute in the leaf block.  Figure out if
908          * the given flags produce an error or call for an atomic rename.
909          */
910         retval = xfs_attr3_leaf_lookup_int(bp, args);
911         if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
912                 xfs_trans_brelse(args->trans, bp);
913                 return retval;
914         } else if (retval == EEXIST) {
915                 if (args->flags & ATTR_CREATE) {        /* pure create op */
916                         xfs_trans_brelse(args->trans, bp);
917                         return retval;
918                 }
919
920                 trace_xfs_attr_leaf_replace(args);
921
922                 args->op_flags |= XFS_DA_OP_RENAME;     /* an atomic rename */
923                 args->blkno2 = args->blkno;             /* set 2nd entry info*/
924                 args->index2 = args->index;
925                 args->rmtblkno2 = args->rmtblkno;
926                 args->rmtblkcnt2 = args->rmtblkcnt;
927         }
928
929         /*
930          * Add the attribute to the leaf block, transitioning to a Btree
931          * if required.
932          */
933         retval = xfs_attr3_leaf_add(bp, args);
934         if (retval == ENOSPC) {
935                 /*
936                  * Promote the attribute list to the Btree format, then
937                  * Commit that transaction so that the node_addname() call
938                  * can manage its own transactions.
939                  */
940                 xfs_bmap_init(args->flist, args->firstblock);
941                 error = xfs_attr3_leaf_to_node(args);
942                 if (!error) {
943                         error = xfs_bmap_finish(&args->trans, args->flist,
944                                                 &committed);
945                 }
946                 if (error) {
947                         ASSERT(committed);
948                         args->trans = NULL;
949                         xfs_bmap_cancel(args->flist);
950                         return(error);
951                 }
952
953                 /*
954                  * bmap_finish() may have committed the last trans and started
955                  * a new one.  We need the inode to be in all transactions.
956                  */
957                 if (committed)
958                         xfs_trans_ijoin(args->trans, dp, 0);
959
960                 /*
961                  * Commit the current trans (including the inode) and start
962                  * a new one.
963                  */
964                 error = xfs_trans_roll(&args->trans, dp);
965                 if (error)
966                         return (error);
967
968                 /*
969                  * Fob the whole rest of the problem off on the Btree code.
970                  */
971                 error = xfs_attr_node_addname(args);
972                 return(error);
973         }
974
975         /*
976          * Commit the transaction that added the attr name so that
977          * later routines can manage their own transactions.
978          */
979         error = xfs_trans_roll(&args->trans, dp);
980         if (error)
981                 return (error);
982
983         /*
984          * If there was an out-of-line value, allocate the blocks we
985          * identified for its storage and copy the value.  This is done
986          * after we create the attribute so that we don't overflow the
987          * maximum size of a transaction and/or hit a deadlock.
988          */
989         if (args->rmtblkno > 0) {
990                 error = xfs_attr_rmtval_set(args);
991                 if (error)
992                         return(error);
993         }
994
995         /*
996          * If this is an atomic rename operation, we must "flip" the
997          * incomplete flags on the "new" and "old" attribute/value pairs
998          * so that one disappears and one appears atomically.  Then we
999          * must remove the "old" attribute/value pair.
1000          */
1001         if (args->op_flags & XFS_DA_OP_RENAME) {
1002                 /*
1003                  * In a separate transaction, set the incomplete flag on the
1004                  * "old" attr and clear the incomplete flag on the "new" attr.
1005                  */
1006                 error = xfs_attr3_leaf_flipflags(args);
1007                 if (error)
1008                         return(error);
1009
1010                 /*
1011                  * Dismantle the "old" attribute/value pair by removing
1012                  * a "remote" value (if it exists).
1013                  */
1014                 args->index = args->index2;
1015                 args->blkno = args->blkno2;
1016                 args->rmtblkno = args->rmtblkno2;
1017                 args->rmtblkcnt = args->rmtblkcnt2;
1018                 if (args->rmtblkno) {
1019                         error = xfs_attr_rmtval_remove(args);
1020                         if (error)
1021                                 return(error);
1022                 }
1023
1024                 /*
1025                  * Read in the block containing the "old" attr, then
1026                  * remove the "old" attr from that block (neat, huh!)
1027                  */
1028                 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
1029                                            -1, &bp);
1030                 if (error)
1031                         return error;
1032
1033                 xfs_attr3_leaf_remove(bp, args);
1034
1035                 /*
1036                  * If the result is small enough, shrink it all into the inode.
1037                  */
1038                 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1039                         xfs_bmap_init(args->flist, args->firstblock);
1040                         error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1041                         /* bp is gone due to xfs_da_shrink_inode */
1042                         if (!error) {
1043                                 error = xfs_bmap_finish(&args->trans,
1044                                                         args->flist,
1045                                                         &committed);
1046                         }
1047                         if (error) {
1048                                 ASSERT(committed);
1049                                 args->trans = NULL;
1050                                 xfs_bmap_cancel(args->flist);
1051                                 return(error);
1052                         }
1053
1054                         /*
1055                          * bmap_finish() may have committed the last trans
1056                          * and started a new one.  We need the inode to be
1057                          * in all transactions.
1058                          */
1059                         if (committed)
1060                                 xfs_trans_ijoin(args->trans, dp, 0);
1061                 }
1062
1063                 /*
1064                  * Commit the remove and start the next trans in series.
1065                  */
1066                 error = xfs_trans_roll(&args->trans, dp);
1067
1068         } else if (args->rmtblkno > 0) {
1069                 /*
1070                  * Added a "remote" value, just clear the incomplete flag.
1071                  */
1072                 error = xfs_attr3_leaf_clearflag(args);
1073         }
1074         return error;
1075 }
1076
1077 /*
1078  * Remove a name from the leaf attribute list structure
1079  *
1080  * This leaf block cannot have a "remote" value, we only call this routine
1081  * if bmap_one_block() says there is only one block (ie: no remote blks).
1082  */
1083 STATIC int
1084 xfs_attr_leaf_removename(xfs_da_args_t *args)
1085 {
1086         xfs_inode_t *dp;
1087         struct xfs_buf *bp;
1088         int error, committed, forkoff;
1089
1090         trace_xfs_attr_leaf_removename(args);
1091
1092         /*
1093          * Remove the attribute.
1094          */
1095         dp = args->dp;
1096         args->blkno = 0;
1097         error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
1098         if (error)
1099                 return error;
1100
1101         error = xfs_attr3_leaf_lookup_int(bp, args);
1102         if (error == ENOATTR) {
1103                 xfs_trans_brelse(args->trans, bp);
1104                 return error;
1105         }
1106
1107         xfs_attr3_leaf_remove(bp, args);
1108
1109         /*
1110          * If the result is small enough, shrink it all into the inode.
1111          */
1112         if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1113                 xfs_bmap_init(args->flist, args->firstblock);
1114                 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1115                 /* bp is gone due to xfs_da_shrink_inode */
1116                 if (!error) {
1117                         error = xfs_bmap_finish(&args->trans, args->flist,
1118                                                 &committed);
1119                 }
1120                 if (error) {
1121                         ASSERT(committed);
1122                         args->trans = NULL;
1123                         xfs_bmap_cancel(args->flist);
1124                         return error;
1125                 }
1126
1127                 /*
1128                  * bmap_finish() may have committed the last trans and started
1129                  * a new one.  We need the inode to be in all transactions.
1130                  */
1131                 if (committed)
1132                         xfs_trans_ijoin(args->trans, dp, 0);
1133         }
1134         return 0;
1135 }
1136
1137 /*
1138  * Look up a name in a leaf attribute list structure.
1139  *
1140  * This leaf block cannot have a "remote" value, we only call this routine
1141  * if bmap_one_block() says there is only one block (ie: no remote blks).
1142  */
1143 STATIC int
1144 xfs_attr_leaf_get(xfs_da_args_t *args)
1145 {
1146         struct xfs_buf *bp;
1147         int error;
1148
1149         trace_xfs_attr_leaf_get(args);
1150
1151         args->blkno = 0;
1152         error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
1153         if (error)
1154                 return error;
1155
1156         error = xfs_attr3_leaf_lookup_int(bp, args);
1157         if (error != EEXIST)  {
1158                 xfs_trans_brelse(args->trans, bp);
1159                 return error;
1160         }
1161         error = xfs_attr3_leaf_getvalue(bp, args);
1162         xfs_trans_brelse(args->trans, bp);
1163         if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
1164                 error = xfs_attr_rmtval_get(args);
1165         }
1166         return error;
1167 }
1168
1169 /*
1170  * Copy out attribute entries for attr_list(), for leaf attribute lists.
1171  */
1172 STATIC int
1173 xfs_attr_leaf_list(xfs_attr_list_context_t *context)
1174 {
1175         int error;
1176         struct xfs_buf *bp;
1177
1178         trace_xfs_attr_leaf_list(context);
1179
1180         context->cursor->blkno = 0;
1181         error = xfs_attr3_leaf_read(NULL, context->dp, 0, -1, &bp);
1182         if (error)
1183                 return XFS_ERROR(error);
1184
1185         error = xfs_attr3_leaf_list_int(bp, context);
1186         xfs_trans_brelse(NULL, bp);
1187         return XFS_ERROR(error);
1188 }
1189
1190
1191 /*========================================================================
1192  * External routines when attribute list size > XFS_LBSIZE(mp).
1193  *========================================================================*/
1194
1195 /*
1196  * Add a name to a Btree-format attribute list.
1197  *
1198  * This will involve walking down the Btree, and may involve splitting
1199  * leaf nodes and even splitting intermediate nodes up to and including
1200  * the root node (a special case of an intermediate node).
1201  *
1202  * "Remote" attribute values confuse the issue and atomic rename operations
1203  * add a whole extra layer of confusion on top of that.
1204  */
1205 STATIC int
1206 xfs_attr_node_addname(xfs_da_args_t *args)
1207 {
1208         xfs_da_state_t *state;
1209         xfs_da_state_blk_t *blk;
1210         xfs_inode_t *dp;
1211         xfs_mount_t *mp;
1212         int committed, retval, error;
1213
1214         trace_xfs_attr_node_addname(args);
1215
1216         /*
1217          * Fill in bucket of arguments/results/context to carry around.
1218          */
1219         dp = args->dp;
1220         mp = dp->i_mount;
1221 restart:
1222         state = xfs_da_state_alloc();
1223         state->args = args;
1224         state->mp = mp;
1225         state->blocksize = state->mp->m_sb.sb_blocksize;
1226         state->node_ents = state->mp->m_attr_node_ents;
1227
1228         /*
1229          * Search to see if name already exists, and get back a pointer
1230          * to where it should go.
1231          */
1232         error = xfs_da3_node_lookup_int(state, &retval);
1233         if (error)
1234                 goto out;
1235         blk = &state->path.blk[ state->path.active-1 ];
1236         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1237         if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
1238                 goto out;
1239         } else if (retval == EEXIST) {
1240                 if (args->flags & ATTR_CREATE)
1241                         goto out;
1242
1243                 trace_xfs_attr_node_replace(args);
1244
1245                 args->op_flags |= XFS_DA_OP_RENAME;     /* atomic rename op */
1246                 args->blkno2 = args->blkno;             /* set 2nd entry info*/
1247                 args->index2 = args->index;
1248                 args->rmtblkno2 = args->rmtblkno;
1249                 args->rmtblkcnt2 = args->rmtblkcnt;
1250                 args->rmtblkno = 0;
1251                 args->rmtblkcnt = 0;
1252         }
1253
1254         retval = xfs_attr3_leaf_add(blk->bp, state->args);
1255         if (retval == ENOSPC) {
1256                 if (state->path.active == 1) {
1257                         /*
1258                          * Its really a single leaf node, but it had
1259                          * out-of-line values so it looked like it *might*
1260                          * have been a b-tree.
1261                          */
1262                         xfs_da_state_free(state);
1263                         xfs_bmap_init(args->flist, args->firstblock);
1264                         error = xfs_attr3_leaf_to_node(args);
1265                         if (!error) {
1266                                 error = xfs_bmap_finish(&args->trans,
1267                                                         args->flist,
1268                                                         &committed);
1269                         }
1270                         if (error) {
1271                                 ASSERT(committed);
1272                                 args->trans = NULL;
1273                                 xfs_bmap_cancel(args->flist);
1274                                 goto out;
1275                         }
1276
1277                         /*
1278                          * bmap_finish() may have committed the last trans
1279                          * and started a new one.  We need the inode to be
1280                          * in all transactions.
1281                          */
1282                         if (committed)
1283                                 xfs_trans_ijoin(args->trans, dp, 0);
1284
1285                         /*
1286                          * Commit the node conversion and start the next
1287                          * trans in the chain.
1288                          */
1289                         error = xfs_trans_roll(&args->trans, dp);
1290                         if (error)
1291                                 goto out;
1292
1293                         goto restart;
1294                 }
1295
1296                 /*
1297                  * Split as many Btree elements as required.
1298                  * This code tracks the new and old attr's location
1299                  * in the index/blkno/rmtblkno/rmtblkcnt fields and
1300                  * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1301                  */
1302                 xfs_bmap_init(args->flist, args->firstblock);
1303                 error = xfs_da3_split(state);
1304                 if (!error) {
1305                         error = xfs_bmap_finish(&args->trans, args->flist,
1306                                                 &committed);
1307                 }
1308                 if (error) {
1309                         ASSERT(committed);
1310                         args->trans = NULL;
1311                         xfs_bmap_cancel(args->flist);
1312                         goto out;
1313                 }
1314
1315                 /*
1316                  * bmap_finish() may have committed the last trans and started
1317                  * a new one.  We need the inode to be in all transactions.
1318                  */
1319                 if (committed)
1320                         xfs_trans_ijoin(args->trans, dp, 0);
1321         } else {
1322                 /*
1323                  * Addition succeeded, update Btree hashvals.
1324                  */
1325                 xfs_da3_fixhashpath(state, &state->path);
1326         }
1327
1328         /*
1329          * Kill the state structure, we're done with it and need to
1330          * allow the buffers to come back later.
1331          */
1332         xfs_da_state_free(state);
1333         state = NULL;
1334
1335         /*
1336          * Commit the leaf addition or btree split and start the next
1337          * trans in the chain.
1338          */
1339         error = xfs_trans_roll(&args->trans, dp);
1340         if (error)
1341                 goto out;
1342
1343         /*
1344          * If there was an out-of-line value, allocate the blocks we
1345          * identified for its storage and copy the value.  This is done
1346          * after we create the attribute so that we don't overflow the
1347          * maximum size of a transaction and/or hit a deadlock.
1348          */
1349         if (args->rmtblkno > 0) {
1350                 error = xfs_attr_rmtval_set(args);
1351                 if (error)
1352                         return(error);
1353         }
1354
1355         /*
1356          * If this is an atomic rename operation, we must "flip" the
1357          * incomplete flags on the "new" and "old" attribute/value pairs
1358          * so that one disappears and one appears atomically.  Then we
1359          * must remove the "old" attribute/value pair.
1360          */
1361         if (args->op_flags & XFS_DA_OP_RENAME) {
1362                 /*
1363                  * In a separate transaction, set the incomplete flag on the
1364                  * "old" attr and clear the incomplete flag on the "new" attr.
1365                  */
1366                 error = xfs_attr3_leaf_flipflags(args);
1367                 if (error)
1368                         goto out;
1369
1370                 /*
1371                  * Dismantle the "old" attribute/value pair by removing
1372                  * a "remote" value (if it exists).
1373                  */
1374                 args->index = args->index2;
1375                 args->blkno = args->blkno2;
1376                 args->rmtblkno = args->rmtblkno2;
1377                 args->rmtblkcnt = args->rmtblkcnt2;
1378                 if (args->rmtblkno) {
1379                         error = xfs_attr_rmtval_remove(args);
1380                         if (error)
1381                                 return(error);
1382                 }
1383
1384                 /*
1385                  * Re-find the "old" attribute entry after any split ops.
1386                  * The INCOMPLETE flag means that we will find the "old"
1387                  * attr, not the "new" one.
1388                  */
1389                 args->flags |= XFS_ATTR_INCOMPLETE;
1390                 state = xfs_da_state_alloc();
1391                 state->args = args;
1392                 state->mp = mp;
1393                 state->blocksize = state->mp->m_sb.sb_blocksize;
1394                 state->node_ents = state->mp->m_attr_node_ents;
1395                 state->inleaf = 0;
1396                 error = xfs_da3_node_lookup_int(state, &retval);
1397                 if (error)
1398                         goto out;
1399
1400                 /*
1401                  * Remove the name and update the hashvals in the tree.
1402                  */
1403                 blk = &state->path.blk[ state->path.active-1 ];
1404                 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1405                 error = xfs_attr3_leaf_remove(blk->bp, args);
1406                 xfs_da3_fixhashpath(state, &state->path);
1407
1408                 /*
1409                  * Check to see if the tree needs to be collapsed.
1410                  */
1411                 if (retval && (state->path.active > 1)) {
1412                         xfs_bmap_init(args->flist, args->firstblock);
1413                         error = xfs_da3_join(state);
1414                         if (!error) {
1415                                 error = xfs_bmap_finish(&args->trans,
1416                                                         args->flist,
1417                                                         &committed);
1418                         }
1419                         if (error) {
1420                                 ASSERT(committed);
1421                                 args->trans = NULL;
1422                                 xfs_bmap_cancel(args->flist);
1423                                 goto out;
1424                         }
1425
1426                         /*
1427                          * bmap_finish() may have committed the last trans
1428                          * and started a new one.  We need the inode to be
1429                          * in all transactions.
1430                          */
1431                         if (committed)
1432                                 xfs_trans_ijoin(args->trans, dp, 0);
1433                 }
1434
1435                 /*
1436                  * Commit and start the next trans in the chain.
1437                  */
1438                 error = xfs_trans_roll(&args->trans, dp);
1439                 if (error)
1440                         goto out;
1441
1442         } else if (args->rmtblkno > 0) {
1443                 /*
1444                  * Added a "remote" value, just clear the incomplete flag.
1445                  */
1446                 error = xfs_attr3_leaf_clearflag(args);
1447                 if (error)
1448                         goto out;
1449         }
1450         retval = error = 0;
1451
1452 out:
1453         if (state)
1454                 xfs_da_state_free(state);
1455         if (error)
1456                 return(error);
1457         return(retval);
1458 }
1459
1460 /*
1461  * Remove a name from a B-tree attribute list.
1462  *
1463  * This will involve walking down the Btree, and may involve joining
1464  * leaf nodes and even joining intermediate nodes up to and including
1465  * the root node (a special case of an intermediate node).
1466  */
1467 STATIC int
1468 xfs_attr_node_removename(xfs_da_args_t *args)
1469 {
1470         xfs_da_state_t *state;
1471         xfs_da_state_blk_t *blk;
1472         xfs_inode_t *dp;
1473         struct xfs_buf *bp;
1474         int retval, error, committed, forkoff;
1475
1476         trace_xfs_attr_node_removename(args);
1477
1478         /*
1479          * Tie a string around our finger to remind us where we are.
1480          */
1481         dp = args->dp;
1482         state = xfs_da_state_alloc();
1483         state->args = args;
1484         state->mp = dp->i_mount;
1485         state->blocksize = state->mp->m_sb.sb_blocksize;
1486         state->node_ents = state->mp->m_attr_node_ents;
1487
1488         /*
1489          * Search to see if name exists, and get back a pointer to it.
1490          */
1491         error = xfs_da3_node_lookup_int(state, &retval);
1492         if (error || (retval != EEXIST)) {
1493                 if (error == 0)
1494                         error = retval;
1495                 goto out;
1496         }
1497
1498         /*
1499          * If there is an out-of-line value, de-allocate the blocks.
1500          * This is done before we remove the attribute so that we don't
1501          * overflow the maximum size of a transaction and/or hit a deadlock.
1502          */
1503         blk = &state->path.blk[ state->path.active-1 ];
1504         ASSERT(blk->bp != NULL);
1505         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1506         if (args->rmtblkno > 0) {
1507                 /*
1508                  * Fill in disk block numbers in the state structure
1509                  * so that we can get the buffers back after we commit
1510                  * several transactions in the following calls.
1511                  */
1512                 error = xfs_attr_fillstate(state);
1513                 if (error)
1514                         goto out;
1515
1516                 /*
1517                  * Mark the attribute as INCOMPLETE, then bunmapi() the
1518                  * remote value.
1519                  */
1520                 error = xfs_attr3_leaf_setflag(args);
1521                 if (error)
1522                         goto out;
1523                 error = xfs_attr_rmtval_remove(args);
1524                 if (error)
1525                         goto out;
1526
1527                 /*
1528                  * Refill the state structure with buffers, the prior calls
1529                  * released our buffers.
1530                  */
1531                 error = xfs_attr_refillstate(state);
1532                 if (error)
1533                         goto out;
1534         }
1535
1536         /*
1537          * Remove the name and update the hashvals in the tree.
1538          */
1539         blk = &state->path.blk[ state->path.active-1 ];
1540         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1541         retval = xfs_attr3_leaf_remove(blk->bp, args);
1542         xfs_da3_fixhashpath(state, &state->path);
1543
1544         /*
1545          * Check to see if the tree needs to be collapsed.
1546          */
1547         if (retval && (state->path.active > 1)) {
1548                 xfs_bmap_init(args->flist, args->firstblock);
1549                 error = xfs_da3_join(state);
1550                 if (!error) {
1551                         error = xfs_bmap_finish(&args->trans, args->flist,
1552                                                 &committed);
1553                 }
1554                 if (error) {
1555                         ASSERT(committed);
1556                         args->trans = NULL;
1557                         xfs_bmap_cancel(args->flist);
1558                         goto out;
1559                 }
1560
1561                 /*
1562                  * bmap_finish() may have committed the last trans and started
1563                  * a new one.  We need the inode to be in all transactions.
1564                  */
1565                 if (committed)
1566                         xfs_trans_ijoin(args->trans, dp, 0);
1567
1568                 /*
1569                  * Commit the Btree join operation and start a new trans.
1570                  */
1571                 error = xfs_trans_roll(&args->trans, dp);
1572                 if (error)
1573                         goto out;
1574         }
1575
1576         /*
1577          * If the result is small enough, push it all into the inode.
1578          */
1579         if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
1580                 /*
1581                  * Have to get rid of the copy of this dabuf in the state.
1582                  */
1583                 ASSERT(state->path.active == 1);
1584                 ASSERT(state->path.blk[0].bp);
1585                 state->path.blk[0].bp = NULL;
1586
1587                 error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp);
1588                 if (error)
1589                         goto out;
1590
1591                 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1592                         xfs_bmap_init(args->flist, args->firstblock);
1593                         error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1594                         /* bp is gone due to xfs_da_shrink_inode */
1595                         if (!error) {
1596                                 error = xfs_bmap_finish(&args->trans,
1597                                                         args->flist,
1598                                                         &committed);
1599                         }
1600                         if (error) {
1601                                 ASSERT(committed);
1602                                 args->trans = NULL;
1603                                 xfs_bmap_cancel(args->flist);
1604                                 goto out;
1605                         }
1606
1607                         /*
1608                          * bmap_finish() may have committed the last trans
1609                          * and started a new one.  We need the inode to be
1610                          * in all transactions.
1611                          */
1612                         if (committed)
1613                                 xfs_trans_ijoin(args->trans, dp, 0);
1614                 } else
1615                         xfs_trans_brelse(args->trans, bp);
1616         }
1617         error = 0;
1618
1619 out:
1620         xfs_da_state_free(state);
1621         return(error);
1622 }
1623
1624 /*
1625  * Fill in the disk block numbers in the state structure for the buffers
1626  * that are attached to the state structure.
1627  * This is done so that we can quickly reattach ourselves to those buffers
1628  * after some set of transaction commits have released these buffers.
1629  */
1630 STATIC int
1631 xfs_attr_fillstate(xfs_da_state_t *state)
1632 {
1633         xfs_da_state_path_t *path;
1634         xfs_da_state_blk_t *blk;
1635         int level;
1636
1637         trace_xfs_attr_fillstate(state->args);
1638
1639         /*
1640          * Roll down the "path" in the state structure, storing the on-disk
1641          * block number for those buffers in the "path".
1642          */
1643         path = &state->path;
1644         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1645         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1646                 if (blk->bp) {
1647                         blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
1648                         blk->bp = NULL;
1649                 } else {
1650                         blk->disk_blkno = 0;
1651                 }
1652         }
1653
1654         /*
1655          * Roll down the "altpath" in the state structure, storing the on-disk
1656          * block number for those buffers in the "altpath".
1657          */
1658         path = &state->altpath;
1659         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1660         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1661                 if (blk->bp) {
1662                         blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
1663                         blk->bp = NULL;
1664                 } else {
1665                         blk->disk_blkno = 0;
1666                 }
1667         }
1668
1669         return(0);
1670 }
1671
1672 /*
1673  * Reattach the buffers to the state structure based on the disk block
1674  * numbers stored in the state structure.
1675  * This is done after some set of transaction commits have released those
1676  * buffers from our grip.
1677  */
1678 STATIC int
1679 xfs_attr_refillstate(xfs_da_state_t *state)
1680 {
1681         xfs_da_state_path_t *path;
1682         xfs_da_state_blk_t *blk;
1683         int level, error;
1684
1685         trace_xfs_attr_refillstate(state->args);
1686
1687         /*
1688          * Roll down the "path" in the state structure, storing the on-disk
1689          * block number for those buffers in the "path".
1690          */
1691         path = &state->path;
1692         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1693         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1694                 if (blk->disk_blkno) {
1695                         error = xfs_da3_node_read(state->args->trans,
1696                                                 state->args->dp,
1697                                                 blk->blkno, blk->disk_blkno,
1698                                                 &blk->bp, XFS_ATTR_FORK);
1699                         if (error)
1700                                 return(error);
1701                 } else {
1702                         blk->bp = NULL;
1703                 }
1704         }
1705
1706         /*
1707          * Roll down the "altpath" in the state structure, storing the on-disk
1708          * block number for those buffers in the "altpath".
1709          */
1710         path = &state->altpath;
1711         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1712         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1713                 if (blk->disk_blkno) {
1714                         error = xfs_da3_node_read(state->args->trans,
1715                                                 state->args->dp,
1716                                                 blk->blkno, blk->disk_blkno,
1717                                                 &blk->bp, XFS_ATTR_FORK);
1718                         if (error)
1719                                 return(error);
1720                 } else {
1721                         blk->bp = NULL;
1722                 }
1723         }
1724
1725         return(0);
1726 }
1727
1728 /*
1729  * Look up a filename in a node attribute list.
1730  *
1731  * This routine gets called for any attribute fork that has more than one
1732  * block, ie: both true Btree attr lists and for single-leaf-blocks with
1733  * "remote" values taking up more blocks.
1734  */
1735 STATIC int
1736 xfs_attr_node_get(xfs_da_args_t *args)
1737 {
1738         xfs_da_state_t *state;
1739         xfs_da_state_blk_t *blk;
1740         int error, retval;
1741         int i;
1742
1743         trace_xfs_attr_node_get(args);
1744
1745         state = xfs_da_state_alloc();
1746         state->args = args;
1747         state->mp = args->dp->i_mount;
1748         state->blocksize = state->mp->m_sb.sb_blocksize;
1749         state->node_ents = state->mp->m_attr_node_ents;
1750
1751         /*
1752          * Search to see if name exists, and get back a pointer to it.
1753          */
1754         error = xfs_da3_node_lookup_int(state, &retval);
1755         if (error) {
1756                 retval = error;
1757         } else if (retval == EEXIST) {
1758                 blk = &state->path.blk[ state->path.active-1 ];
1759                 ASSERT(blk->bp != NULL);
1760                 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1761
1762                 /*
1763                  * Get the value, local or "remote"
1764                  */
1765                 retval = xfs_attr3_leaf_getvalue(blk->bp, args);
1766                 if (!retval && (args->rmtblkno > 0)
1767                     && !(args->flags & ATTR_KERNOVAL)) {
1768                         retval = xfs_attr_rmtval_get(args);
1769                 }
1770         }
1771
1772         /*
1773          * If not in a transaction, we have to release all the buffers.
1774          */
1775         for (i = 0; i < state->path.active; i++) {
1776                 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1777                 state->path.blk[i].bp = NULL;
1778         }
1779
1780         xfs_da_state_free(state);
1781         return(retval);
1782 }
1783
1784 STATIC int                                                      /* error */
1785 xfs_attr_node_list(xfs_attr_list_context_t *context)
1786 {
1787         attrlist_cursor_kern_t *cursor;
1788         xfs_attr_leafblock_t *leaf;
1789         xfs_da_intnode_t *node;
1790         struct xfs_attr3_icleaf_hdr leafhdr;
1791         struct xfs_da3_icnode_hdr nodehdr;
1792         struct xfs_da_node_entry *btree;
1793         int error, i;
1794         struct xfs_buf *bp;
1795
1796         trace_xfs_attr_node_list(context);
1797
1798         cursor = context->cursor;
1799         cursor->initted = 1;
1800
1801         /*
1802          * Do all sorts of validation on the passed-in cursor structure.
1803          * If anything is amiss, ignore the cursor and look up the hashval
1804          * starting from the btree root.
1805          */
1806         bp = NULL;
1807         if (cursor->blkno > 0) {
1808                 error = xfs_da3_node_read(NULL, context->dp, cursor->blkno, -1,
1809                                               &bp, XFS_ATTR_FORK);
1810                 if ((error != 0) && (error != EFSCORRUPTED))
1811                         return(error);
1812                 if (bp) {
1813                         struct xfs_attr_leaf_entry *entries;
1814
1815                         node = bp->b_addr;
1816                         switch (be16_to_cpu(node->hdr.info.magic)) {
1817                         case XFS_DA_NODE_MAGIC:
1818                         case XFS_DA3_NODE_MAGIC:
1819                                 trace_xfs_attr_list_wrong_blk(context);
1820                                 xfs_trans_brelse(NULL, bp);
1821                                 bp = NULL;
1822                                 break;
1823                         case XFS_ATTR_LEAF_MAGIC:
1824                         case XFS_ATTR3_LEAF_MAGIC:
1825                                 leaf = bp->b_addr;
1826                                 xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
1827                                 entries = xfs_attr3_leaf_entryp(leaf);
1828                                 if (cursor->hashval > be32_to_cpu(
1829                                                 entries[leafhdr.count - 1].hashval)) {
1830                                         trace_xfs_attr_list_wrong_blk(context);
1831                                         xfs_trans_brelse(NULL, bp);
1832                                         bp = NULL;
1833                                 } else if (cursor->hashval <= be32_to_cpu(
1834                                                 entries[0].hashval)) {
1835                                         trace_xfs_attr_list_wrong_blk(context);
1836                                         xfs_trans_brelse(NULL, bp);
1837                                         bp = NULL;
1838                                 }
1839                                 break;
1840                         default:
1841                                 trace_xfs_attr_list_wrong_blk(context);
1842                                 xfs_trans_brelse(NULL, bp);
1843                                 bp = NULL;
1844                         }
1845                 }
1846         }
1847
1848         /*
1849          * We did not find what we expected given the cursor's contents,
1850          * so we start from the top and work down based on the hash value.
1851          * Note that start of node block is same as start of leaf block.
1852          */
1853         if (bp == NULL) {
1854                 cursor->blkno = 0;
1855                 for (;;) {
1856                         __uint16_t magic;
1857
1858                         error = xfs_da3_node_read(NULL, context->dp,
1859                                                       cursor->blkno, -1, &bp,
1860                                                       XFS_ATTR_FORK);
1861                         if (error)
1862                                 return(error);
1863                         node = bp->b_addr;
1864                         magic = be16_to_cpu(node->hdr.info.magic);
1865                         if (magic == XFS_ATTR_LEAF_MAGIC ||
1866                             magic == XFS_ATTR3_LEAF_MAGIC)
1867                                 break;
1868                         if (magic != XFS_DA_NODE_MAGIC &&
1869                             magic != XFS_DA3_NODE_MAGIC) {
1870                                 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
1871                                                      XFS_ERRLEVEL_LOW,
1872                                                      context->dp->i_mount,
1873                                                      node);
1874                                 xfs_trans_brelse(NULL, bp);
1875                                 return XFS_ERROR(EFSCORRUPTED);
1876                         }
1877
1878                         xfs_da3_node_hdr_from_disk(&nodehdr, node);
1879                         btree = xfs_da3_node_tree_p(node);
1880                         for (i = 0; i < nodehdr.count; btree++, i++) {
1881                                 if (cursor->hashval
1882                                                 <= be32_to_cpu(btree->hashval)) {
1883                                         cursor->blkno = be32_to_cpu(btree->before);
1884                                         trace_xfs_attr_list_node_descend(context,
1885                                                                          btree);
1886                                         break;
1887                                 }
1888                         }
1889                         if (i == nodehdr.count) {
1890                                 xfs_trans_brelse(NULL, bp);
1891                                 return 0;
1892                         }
1893                         xfs_trans_brelse(NULL, bp);
1894                 }
1895         }
1896         ASSERT(bp != NULL);
1897
1898         /*
1899          * Roll upward through the blocks, processing each leaf block in
1900          * order.  As long as there is space in the result buffer, keep
1901          * adding the information.
1902          */
1903         for (;;) {
1904                 leaf = bp->b_addr;
1905                 error = xfs_attr3_leaf_list_int(bp, context);
1906                 if (error) {
1907                         xfs_trans_brelse(NULL, bp);
1908                         return error;
1909                 }
1910                 xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
1911                 if (context->seen_enough || leafhdr.forw == 0)
1912                         break;
1913                 cursor->blkno = leafhdr.forw;
1914                 xfs_trans_brelse(NULL, bp);
1915                 error = xfs_attr3_leaf_read(NULL, context->dp, cursor->blkno, -1,
1916                                            &bp);
1917                 if (error)
1918                         return error;
1919         }
1920         xfs_trans_brelse(NULL, bp);
1921         return 0;
1922 }