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