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