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