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