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