hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/xfs/libxfs/xfs_attr_leaf.c
....@@ -10,14 +10,12 @@
1010 #include "xfs_format.h"
1111 #include "xfs_log_format.h"
1212 #include "xfs_trans_resv.h"
13
-#include "xfs_bit.h"
1413 #include "xfs_sb.h"
1514 #include "xfs_mount.h"
1615 #include "xfs_da_format.h"
1716 #include "xfs_da_btree.h"
1817 #include "xfs_inode.h"
1918 #include "xfs_trans.h"
20
-#include "xfs_inode_item.h"
2119 #include "xfs_bmap_btree.h"
2220 #include "xfs_bmap.h"
2321 #include "xfs_attr_sf.h"
....@@ -27,7 +25,6 @@
2725 #include "xfs_error.h"
2826 #include "xfs_trace.h"
2927 #include "xfs_buf_item.h"
30
-#include "xfs_cksum.h"
3128 #include "xfs_dir2.h"
3229 #include "xfs_log.h"
3330
....@@ -236,41 +233,80 @@
236233 }
237234
238235 static xfs_failaddr_t
236
+xfs_attr3_leaf_verify_entry(
237
+ struct xfs_mount *mp,
238
+ char *buf_end,
239
+ struct xfs_attr_leafblock *leaf,
240
+ struct xfs_attr3_icleaf_hdr *leafhdr,
241
+ struct xfs_attr_leaf_entry *ent,
242
+ int idx,
243
+ __u32 *last_hashval)
244
+{
245
+ struct xfs_attr_leaf_name_local *lentry;
246
+ struct xfs_attr_leaf_name_remote *rentry;
247
+ char *name_end;
248
+ unsigned int nameidx;
249
+ unsigned int namesize;
250
+ __u32 hashval;
251
+
252
+ /* hash order check */
253
+ hashval = be32_to_cpu(ent->hashval);
254
+ if (hashval < *last_hashval)
255
+ return __this_address;
256
+ *last_hashval = hashval;
257
+
258
+ nameidx = be16_to_cpu(ent->nameidx);
259
+ if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize)
260
+ return __this_address;
261
+
262
+ /*
263
+ * Check the name information. The namelen fields are u8 so we can't
264
+ * possibly exceed the maximum name length of 255 bytes.
265
+ */
266
+ if (ent->flags & XFS_ATTR_LOCAL) {
267
+ lentry = xfs_attr3_leaf_name_local(leaf, idx);
268
+ namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
269
+ be16_to_cpu(lentry->valuelen));
270
+ name_end = (char *)lentry + namesize;
271
+ if (lentry->namelen == 0)
272
+ return __this_address;
273
+ } else {
274
+ rentry = xfs_attr3_leaf_name_remote(leaf, idx);
275
+ namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
276
+ name_end = (char *)rentry + namesize;
277
+ if (rentry->namelen == 0)
278
+ return __this_address;
279
+ if (!(ent->flags & XFS_ATTR_INCOMPLETE) &&
280
+ rentry->valueblk == 0)
281
+ return __this_address;
282
+ }
283
+
284
+ if (name_end > buf_end)
285
+ return __this_address;
286
+
287
+ return NULL;
288
+}
289
+
290
+static xfs_failaddr_t
239291 xfs_attr3_leaf_verify(
240292 struct xfs_buf *bp)
241293 {
242294 struct xfs_attr3_icleaf_hdr ichdr;
243
- struct xfs_mount *mp = bp->b_target->bt_mount;
295
+ struct xfs_mount *mp = bp->b_mount;
244296 struct xfs_attr_leafblock *leaf = bp->b_addr;
245297 struct xfs_attr_leaf_entry *entries;
298
+ struct xfs_attr_leaf_entry *ent;
299
+ char *buf_end;
246300 uint32_t end; /* must be 32bit - see below */
301
+ __u32 last_hashval = 0;
247302 int i;
303
+ xfs_failaddr_t fa;
248304
249305 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
250306
251
- if (xfs_sb_version_hascrc(&mp->m_sb)) {
252
- struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
253
-
254
- if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC)
255
- return __this_address;
256
-
257
- if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))
258
- return __this_address;
259
- if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
260
- return __this_address;
261
- if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))
262
- return __this_address;
263
- } else {
264
- if (ichdr.magic != XFS_ATTR_LEAF_MAGIC)
265
- return __this_address;
266
- }
267
- /*
268
- * In recovery there is a transient state where count == 0 is valid
269
- * because we may have transitioned an empty shortform attr to a leaf
270
- * if the attr didn't fit in shortform.
271
- */
272
- if (!xfs_log_in_recovery(mp) && ichdr.count == 0)
273
- return __this_address;
307
+ fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
308
+ if (fa)
309
+ return fa;
274310
275311 /*
276312 * firstused is the block offset of the first name info structure.
....@@ -287,8 +323,20 @@
287323 (char *)bp->b_addr + ichdr.firstused)
288324 return __this_address;
289325
290
- /* XXX: need to range check rest of attr header values */
291
- /* XXX: hash order check? */
326
+ /*
327
+ * NOTE: This verifier historically failed empty leaf buffers because
328
+ * we expect the fork to be in another format. Empty attr fork format
329
+ * conversions are possible during xattr set, however, and format
330
+ * conversion is not atomic with the xattr set that triggers it. We
331
+ * cannot assume leaf blocks are non-empty until that is addressed.
332
+ */
333
+ buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
334
+ for (i = 0, ent = entries; i < ichdr.count; ent++, i++) {
335
+ fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr,
336
+ ent, i, &last_hashval);
337
+ if (fa)
338
+ return fa;
339
+ }
292340
293341 /*
294342 * Quickly check the freemap information. Attribute data has to be
....@@ -324,7 +372,7 @@
324372 xfs_attr3_leaf_write_verify(
325373 struct xfs_buf *bp)
326374 {
327
- struct xfs_mount *mp = bp->b_target->bt_mount;
375
+ struct xfs_mount *mp = bp->b_mount;
328376 struct xfs_buf_log_item *bip = bp->b_log_item;
329377 struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
330378 xfs_failaddr_t fa;
....@@ -354,7 +402,7 @@
354402 xfs_attr3_leaf_read_verify(
355403 struct xfs_buf *bp)
356404 {
357
- struct xfs_mount *mp = bp->b_target->bt_mount;
405
+ struct xfs_mount *mp = bp->b_mount;
358406 xfs_failaddr_t fa;
359407
360408 if (xfs_sb_version_hascrc(&mp->m_sb) &&
....@@ -369,6 +417,8 @@
369417
370418 const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
371419 .name = "xfs_attr3_leaf",
420
+ .magic16 = { cpu_to_be16(XFS_ATTR_LEAF_MAGIC),
421
+ cpu_to_be16(XFS_ATTR3_LEAF_MAGIC) },
372422 .verify_read = xfs_attr3_leaf_read_verify,
373423 .verify_write = xfs_attr3_leaf_write_verify,
374424 .verify_struct = xfs_attr3_leaf_verify,
....@@ -379,13 +429,12 @@
379429 struct xfs_trans *tp,
380430 struct xfs_inode *dp,
381431 xfs_dablk_t bno,
382
- xfs_daddr_t mappedbno,
383432 struct xfs_buf **bpp)
384433 {
385434 int err;
386435
387
- err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
388
- XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops);
436
+ err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK,
437
+ &xfs_attr3_leaf_buf_ops);
389438 if (!err && tp && *bpp)
390439 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF);
391440 return err;
....@@ -395,23 +444,78 @@
395444 * Namespace helper routines
396445 *========================================================================*/
397446
398
-/*
399
- * If namespace bits don't match return 0.
400
- * If all match then return 1.
401
- */
402
-STATIC int
403
-xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
447
+static bool
448
+xfs_attr_match(
449
+ struct xfs_da_args *args,
450
+ uint8_t namelen,
451
+ unsigned char *name,
452
+ int flags)
404453 {
405
- return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
454
+ if (args->namelen != namelen)
455
+ return false;
456
+ if (memcmp(args->name, name, namelen) != 0)
457
+ return false;
458
+ /*
459
+ * If we are looking for incomplete entries, show only those, else only
460
+ * show complete entries.
461
+ */
462
+ if (args->attr_filter !=
463
+ (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
464
+ return false;
465
+ return true;
406466 }
407467
468
+static int
469
+xfs_attr_copy_value(
470
+ struct xfs_da_args *args,
471
+ unsigned char *value,
472
+ int valuelen)
473
+{
474
+ /*
475
+ * No copy if all we have to do is get the length
476
+ */
477
+ if (!args->valuelen) {
478
+ args->valuelen = valuelen;
479
+ return 0;
480
+ }
481
+
482
+ /*
483
+ * No copy if the length of the existing buffer is too small
484
+ */
485
+ if (args->valuelen < valuelen) {
486
+ args->valuelen = valuelen;
487
+ return -ERANGE;
488
+ }
489
+
490
+ if (!args->value) {
491
+ args->value = kmem_alloc_large(valuelen, KM_NOLOCKDEP);
492
+ if (!args->value)
493
+ return -ENOMEM;
494
+ }
495
+ args->valuelen = valuelen;
496
+
497
+ /* remote block xattr requires IO for copy-in */
498
+ if (args->rmtblkno)
499
+ return xfs_attr_rmtval_get(args);
500
+
501
+ /*
502
+ * This is to prevent a GCC warning because the remote xattr case
503
+ * doesn't have a value to pass in. In that case, we never reach here,
504
+ * but GCC can't work that out and so throws a "passing NULL to
505
+ * memcpy" warning.
506
+ */
507
+ if (!value)
508
+ return -EINVAL;
509
+ memcpy(args->value, value, valuelen);
510
+ return 0;
511
+}
408512
409513 /*========================================================================
410514 * External routines when attribute fork size < XFS_LITINO(mp).
411515 *========================================================================*/
412516
413517 /*
414
- * Query whether the requested number of additional bytes of extended
518
+ * Query whether the total requested number of attr fork bytes of extended
415519 * attribute space will be able to fit inline.
416520 *
417521 * Returns zero if not, else the di_forkoff fork offset to be used in the
....@@ -421,18 +525,26 @@
421525 * special case for dev/uuid inodes, they have fixed size data forks.
422526 */
423527 int
424
-xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
528
+xfs_attr_shortform_bytesfit(
529
+ struct xfs_inode *dp,
530
+ int bytes)
425531 {
426
- int offset;
427
- int minforkoff; /* lower limit on valid forkoff locations */
428
- int maxforkoff; /* upper limit on valid forkoff locations */
429
- int dsize;
430
- xfs_mount_t *mp = dp->i_mount;
532
+ struct xfs_mount *mp = dp->i_mount;
533
+ int64_t dsize;
534
+ int minforkoff;
535
+ int maxforkoff;
536
+ int offset;
537
+
538
+ /*
539
+ * Check if the new size could fit at all first:
540
+ */
541
+ if (bytes > XFS_LITINO(mp))
542
+ return 0;
431543
432544 /* rounded down */
433
- offset = (XFS_LITINO(mp, dp->i_d.di_version) - bytes) >> 3;
545
+ offset = (XFS_LITINO(mp) - bytes) >> 3;
434546
435
- if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) {
547
+ if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) {
436548 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
437549 return (offset >= minforkoff) ? minforkoff : 0;
438550 }
....@@ -460,7 +572,7 @@
460572
461573 dsize = dp->i_df.if_bytes;
462574
463
- switch (dp->i_d.di_format) {
575
+ switch (dp->i_df.if_format) {
464576 case XFS_DINODE_FMT_EXTENTS:
465577 /*
466578 * If there is no attr fork and the data fork is extents,
....@@ -493,12 +605,11 @@
493605 * A data fork btree root must have space for at least
494606 * MINDBTPTRS key/ptr pairs if the data fork is small or empty.
495607 */
496
- minforkoff = max(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
608
+ minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
497609 minforkoff = roundup(minforkoff, 8) >> 3;
498610
499611 /* attr fork btree root can have at least this many key/ptr pairs */
500
- maxforkoff = XFS_LITINO(mp, dp->i_d.di_version) -
501
- XFS_BMDR_SPACE_CALC(MINABTPTRS);
612
+ maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
502613 maxforkoff = maxforkoff >> 3; /* rounded down */
503614
504615 if (offset >= maxforkoff)
....@@ -530,22 +641,19 @@
530641 * Create the initial contents of a shortform attribute list.
531642 */
532643 void
533
-xfs_attr_shortform_create(xfs_da_args_t *args)
644
+xfs_attr_shortform_create(
645
+ struct xfs_da_args *args)
534646 {
535
- xfs_attr_sf_hdr_t *hdr;
536
- xfs_inode_t *dp;
537
- struct xfs_ifork *ifp;
647
+ struct xfs_inode *dp = args->dp;
648
+ struct xfs_ifork *ifp = dp->i_afp;
649
+ struct xfs_attr_sf_hdr *hdr;
538650
539651 trace_xfs_attr_sf_create(args);
540652
541
- dp = args->dp;
542
- ASSERT(dp != NULL);
543
- ifp = dp->i_afp;
544
- ASSERT(ifp != NULL);
545653 ASSERT(ifp->if_bytes == 0);
546
- if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) {
654
+ if (ifp->if_format == XFS_DINODE_FMT_EXTENTS) {
547655 ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */
548
- dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL;
656
+ ifp->if_format = XFS_DINODE_FMT_LOCAL;
549657 ifp->if_flags |= XFS_IFINLINE;
550658 } else {
551659 ASSERT(ifp->if_flags & XFS_IFINLINE);
....@@ -558,18 +666,65 @@
558666 }
559667
560668 /*
669
+ * Return -EEXIST if attr is found, or -ENOATTR if not
670
+ * args: args containing attribute name and namelen
671
+ * sfep: If not null, pointer will be set to the last attr entry found on
672
+ -EEXIST. On -ENOATTR pointer is left at the last entry in the list
673
+ * basep: If not null, pointer is set to the byte offset of the entry in the
674
+ * list on -EEXIST. On -ENOATTR, pointer is left at the byte offset of
675
+ * the last entry in the list
676
+ */
677
+int
678
+xfs_attr_sf_findname(
679
+ struct xfs_da_args *args,
680
+ struct xfs_attr_sf_entry **sfep,
681
+ unsigned int *basep)
682
+{
683
+ struct xfs_attr_shortform *sf;
684
+ struct xfs_attr_sf_entry *sfe;
685
+ unsigned int base = sizeof(struct xfs_attr_sf_hdr);
686
+ int size = 0;
687
+ int end;
688
+ int i;
689
+
690
+ sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data;
691
+ sfe = &sf->list[0];
692
+ end = sf->hdr.count;
693
+ for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
694
+ base += size, i++) {
695
+ size = xfs_attr_sf_entsize(sfe);
696
+ if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
697
+ sfe->flags))
698
+ continue;
699
+ break;
700
+ }
701
+
702
+ if (sfep != NULL)
703
+ *sfep = sfe;
704
+
705
+ if (basep != NULL)
706
+ *basep = base;
707
+
708
+ if (i == end)
709
+ return -ENOATTR;
710
+ return -EEXIST;
711
+}
712
+
713
+/*
561714 * Add a name/value pair to the shortform attribute list.
562715 * Overflow from the inode has already been checked for.
563716 */
564717 void
565
-xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
718
+xfs_attr_shortform_add(
719
+ struct xfs_da_args *args,
720
+ int forkoff)
566721 {
567
- xfs_attr_shortform_t *sf;
568
- xfs_attr_sf_entry_t *sfe;
569
- int i, offset, size;
570
- xfs_mount_t *mp;
571
- xfs_inode_t *dp;
572
- struct xfs_ifork *ifp;
722
+ struct xfs_attr_shortform *sf;
723
+ struct xfs_attr_sf_entry *sfe;
724
+ int offset, size;
725
+ struct xfs_mount *mp;
726
+ struct xfs_inode *dp;
727
+ struct xfs_ifork *ifp;
573728
574729 trace_xfs_attr_sf_add(args);
575730
....@@ -579,29 +734,19 @@
579734
580735 ifp = dp->i_afp;
581736 ASSERT(ifp->if_flags & XFS_IFINLINE);
582
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
583
- sfe = &sf->list[0];
584
- for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
585
-#ifdef DEBUG
586
- if (sfe->namelen != args->namelen)
587
- continue;
588
- if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
589
- continue;
590
- if (!xfs_attr_namesp_match(args->flags, sfe->flags))
591
- continue;
737
+ sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
738
+ if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
592739 ASSERT(0);
593
-#endif
594
- }
595740
596741 offset = (char *)sfe - (char *)sf;
597
- size = XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
742
+ size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
598743 xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
599
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
600
- sfe = (xfs_attr_sf_entry_t *)((char *)sf + offset);
744
+ sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
745
+ sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
601746
602747 sfe->namelen = args->namelen;
603748 sfe->valuelen = args->valuelen;
604
- sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
749
+ sfe->flags = args->attr_filter;
605750 memcpy(sfe->nameval, args->name, args->namelen);
606751 memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
607752 sf->hdr.count++;
....@@ -620,13 +765,12 @@
620765 struct xfs_inode *ip,
621766 struct xfs_trans *tp)
622767 {
623
- xfs_idestroy_fork(ip, XFS_ATTR_FORK);
768
+ ASSERT(ip->i_afp->if_nextents == 0);
769
+
770
+ xfs_idestroy_fork(ip->i_afp);
771
+ kmem_cache_free(xfs_ifork_zone, ip->i_afp);
772
+ ip->i_afp = NULL;
624773 ip->i_d.di_forkoff = 0;
625
- ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
626
-
627
- ASSERT(ip->i_d.di_anextents == 0);
628
- ASSERT(ip->i_afp == NULL);
629
-
630774 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
631775 }
632776
....@@ -634,35 +778,27 @@
634778 * Remove an attribute from the shortform attribute list structure.
635779 */
636780 int
637
-xfs_attr_shortform_remove(xfs_da_args_t *args)
781
+xfs_attr_shortform_remove(
782
+ struct xfs_da_args *args)
638783 {
639
- xfs_attr_shortform_t *sf;
640
- xfs_attr_sf_entry_t *sfe;
641
- int base, size=0, end, totsize, i;
642
- xfs_mount_t *mp;
643
- xfs_inode_t *dp;
784
+ struct xfs_attr_shortform *sf;
785
+ struct xfs_attr_sf_entry *sfe;
786
+ int size = 0, end, totsize;
787
+ unsigned int base;
788
+ struct xfs_mount *mp;
789
+ struct xfs_inode *dp;
790
+ int error;
644791
645792 trace_xfs_attr_sf_remove(args);
646793
647794 dp = args->dp;
648795 mp = dp->i_mount;
649
- base = sizeof(xfs_attr_sf_hdr_t);
650
- sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
651
- sfe = &sf->list[0];
652
- end = sf->hdr.count;
653
- for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
654
- base += size, i++) {
655
- size = XFS_ATTR_SF_ENTSIZE(sfe);
656
- if (sfe->namelen != args->namelen)
657
- continue;
658
- if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
659
- continue;
660
- if (!xfs_attr_namesp_match(args->flags, sfe->flags))
661
- continue;
662
- break;
663
- }
664
- if (i == end)
665
- return -ENOATTR;
796
+ sf = (struct xfs_attr_shortform *)dp->i_afp->if_u1.if_data;
797
+
798
+ error = xfs_attr_sf_findname(args, &sfe, &base);
799
+ if (error != -EEXIST)
800
+ return error;
801
+ size = xfs_attr_sf_entsize(sfe);
666802
667803 /*
668804 * Fix up the attribute fork data, covering the hole
....@@ -680,7 +816,7 @@
680816 totsize -= size;
681817 if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
682818 (mp->m_flags & XFS_MOUNT_ATTR2) &&
683
- (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
819
+ (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
684820 !(args->op_flags & XFS_DA_OP_ADDNAME)) {
685821 xfs_attr_fork_remove(dp, args->trans);
686822 } else {
....@@ -690,7 +826,7 @@
690826 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) ||
691827 (args->op_flags & XFS_DA_OP_ADDNAME) ||
692828 !(mp->m_flags & XFS_MOUNT_ATTR2) ||
693
- dp->i_d.di_format == XFS_DINODE_FMT_BTREE);
829
+ dp->i_df.if_format == XFS_DINODE_FMT_BTREE);
694830 xfs_trans_log_inode(args->trans, dp,
695831 XFS_ILOG_CORE | XFS_ILOG_ADATA);
696832 }
....@@ -707,8 +843,8 @@
707843 int
708844 xfs_attr_shortform_lookup(xfs_da_args_t *args)
709845 {
710
- xfs_attr_shortform_t *sf;
711
- xfs_attr_sf_entry_t *sfe;
846
+ struct xfs_attr_shortform *sf;
847
+ struct xfs_attr_sf_entry *sfe;
712848 int i;
713849 struct xfs_ifork *ifp;
714850
....@@ -716,55 +852,41 @@
716852
717853 ifp = args->dp->i_afp;
718854 ASSERT(ifp->if_flags & XFS_IFINLINE);
719
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
855
+ sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
720856 sfe = &sf->list[0];
721857 for (i = 0; i < sf->hdr.count;
722
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
723
- if (sfe->namelen != args->namelen)
724
- continue;
725
- if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
726
- continue;
727
- if (!xfs_attr_namesp_match(args->flags, sfe->flags))
728
- continue;
729
- return -EEXIST;
858
+ sfe = xfs_attr_sf_nextentry(sfe), i++) {
859
+ if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
860
+ sfe->flags))
861
+ return -EEXIST;
730862 }
731863 return -ENOATTR;
732864 }
733865
734866 /*
735
- * Look up a name in a shortform attribute list structure.
867
+ * Retrieve the attribute value and length.
868
+ *
869
+ * If args->valuelen is zero, only the length needs to be returned. Unlike a
870
+ * lookup, we only return an error if the attribute does not exist or we can't
871
+ * retrieve the value.
736872 */
737
-/*ARGSUSED*/
738873 int
739
-xfs_attr_shortform_getvalue(xfs_da_args_t *args)
874
+xfs_attr_shortform_getvalue(
875
+ struct xfs_da_args *args)
740876 {
741
- xfs_attr_shortform_t *sf;
742
- xfs_attr_sf_entry_t *sfe;
743
- int i;
877
+ struct xfs_attr_shortform *sf;
878
+ struct xfs_attr_sf_entry *sfe;
879
+ int i;
744880
745881 ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE);
746
- sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data;
882
+ sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data;
747883 sfe = &sf->list[0];
748884 for (i = 0; i < sf->hdr.count;
749
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
750
- if (sfe->namelen != args->namelen)
751
- continue;
752
- if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
753
- continue;
754
- if (!xfs_attr_namesp_match(args->flags, sfe->flags))
755
- continue;
756
- if (args->flags & ATTR_KERNOVAL) {
757
- args->valuelen = sfe->valuelen;
758
- return -EEXIST;
759
- }
760
- if (args->valuelen < sfe->valuelen) {
761
- args->valuelen = sfe->valuelen;
762
- return -ERANGE;
763
- }
764
- args->valuelen = sfe->valuelen;
765
- memcpy(args->value, &sfe->nameval[args->namelen],
766
- args->valuelen);
767
- return -EEXIST;
885
+ sfe = xfs_attr_sf_nextentry(sfe), i++) {
886
+ if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
887
+ sfe->flags))
888
+ return xfs_attr_copy_value(args,
889
+ &sfe->nameval[args->namelen], sfe->valuelen);
768890 }
769891 return -ENOATTR;
770892 }
....@@ -792,40 +914,25 @@
792914
793915 dp = args->dp;
794916 ifp = dp->i_afp;
795
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
917
+ sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
796918 size = be16_to_cpu(sf->hdr.totsize);
797
- tmpbuffer = kmem_alloc(size, KM_SLEEP);
919
+ tmpbuffer = kmem_alloc(size, 0);
798920 ASSERT(tmpbuffer != NULL);
799921 memcpy(tmpbuffer, ifp->if_u1.if_data, size);
800
- sf = (xfs_attr_shortform_t *)tmpbuffer;
922
+ sf = (struct xfs_attr_shortform *)tmpbuffer;
801923
802924 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
803
- xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK);
925
+ xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
804926
805927 bp = NULL;
806928 error = xfs_da_grow_inode(args, &blkno);
807
- if (error) {
808
- /*
809
- * If we hit an IO error middle of the transaction inside
810
- * grow_inode(), we may have inconsistent data. Bail out.
811
- */
812
- if (error == -EIO)
813
- goto out;
814
- xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
815
- memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
929
+ if (error)
816930 goto out;
817
- }
818931
819932 ASSERT(blkno == 0);
820933 error = xfs_attr3_leaf_create(args, blkno, &bp);
821
- if (error) {
822
- /* xfs_attr3_leaf_create may not have instantiated a block */
823
- if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0))
824
- goto out;
825
- xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
826
- memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
934
+ if (error)
827935 goto out;
828
- }
829936
830937 memset((char *)&nargs, 0, sizeof(nargs));
831938 nargs.dp = dp;
....@@ -843,14 +950,14 @@
843950 nargs.valuelen = sfe->valuelen;
844951 nargs.hashval = xfs_da_hashname(sfe->nameval,
845952 sfe->namelen);
846
- nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
953
+ nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
847954 error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
848955 ASSERT(error == -ENOATTR);
849956 error = xfs_attr3_leaf_add(bp, &nargs);
850957 ASSERT(error != -ENOSPC);
851958 if (error)
852959 goto out;
853
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
960
+ sfe = xfs_attr_sf_nextentry(sfe);
854961 }
855962 error = 0;
856963 *leaf_bp = bp;
....@@ -874,7 +981,7 @@
874981 struct xfs_attr3_icleaf_hdr leafhdr;
875982 int bytes;
876983 int i;
877
- struct xfs_mount *mp = bp->b_target->bt_mount;
984
+ struct xfs_mount *mp = bp->b_mount;
878985
879986 leaf = bp->b_addr;
880987 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
....@@ -891,12 +998,11 @@
891998 return 0;
892999 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
8931000 return 0;
894
- bytes += sizeof(struct xfs_attr_sf_entry) - 1
895
- + name_loc->namelen
896
- + be16_to_cpu(name_loc->valuelen);
1001
+ bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
1002
+ be16_to_cpu(name_loc->valuelen));
8971003 }
8981004 if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
899
- (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
1005
+ (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
9001006 (bytes == sizeof(struct xfs_attr_sf_hdr)))
9011007 return -1;
9021008 return xfs_attr_shortform_bytesfit(dp, bytes);
....@@ -913,9 +1019,9 @@
9131019 char *endp;
9141020 struct xfs_ifork *ifp;
9151021 int i;
916
- int size;
1022
+ int64_t size;
9171023
918
- ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL);
1024
+ ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL);
9191025 ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK);
9201026 sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
9211027 size = ifp->if_bytes;
....@@ -938,7 +1044,7 @@
9381044 * xfs_attr_sf_entry is defined with a 1-byte variable
9391045 * array at the end, so we must subtract that off.
9401046 */
941
- if (((char *)sfep + sizeof(*sfep) - 1) >= endp)
1047
+ if (((char *)sfep + sizeof(*sfep)) >= endp)
9421048 return __this_address;
9431049
9441050 /* Don't allow names with known bad length. */
....@@ -950,7 +1056,7 @@
9501056 * within the data buffer. The next entry starts after the
9511057 * name component, so nextentry is an acceptable test.
9521058 */
953
- next_sfep = XFS_ATTR_SF_NEXTENTRY(sfep);
1059
+ next_sfep = xfs_attr_sf_nextentry(sfep);
9541060 if ((char *)next_sfep > endp)
9551061 return __this_address;
9561062
....@@ -999,7 +1105,7 @@
9991105
10001106 trace_xfs_attr_leaf_to_sf(args);
10011107
1002
- tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
1108
+ tmpbuffer = kmem_alloc(args->geo->blksize, 0);
10031109 if (!tmpbuffer)
10041110 return -ENOMEM;
10051111
....@@ -1021,7 +1127,7 @@
10211127
10221128 if (forkoff == -1) {
10231129 ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
1024
- ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
1130
+ ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE);
10251131 xfs_attr_fork_remove(dp, args->trans);
10261132 goto out;
10271133 }
....@@ -1051,7 +1157,7 @@
10511157 nargs.value = &name_loc->nameval[nargs.namelen];
10521158 nargs.valuelen = be16_to_cpu(name_loc->valuelen);
10531159 nargs.hashval = be32_to_cpu(entry->hashval);
1054
- nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
1160
+ nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
10551161 xfs_attr_shortform_add(&nargs, forkoff);
10561162 }
10571163 error = 0;
....@@ -1071,7 +1177,6 @@
10711177 struct xfs_attr_leafblock *leaf;
10721178 struct xfs_attr3_icleaf_hdr icleafhdr;
10731179 struct xfs_attr_leaf_entry *entries;
1074
- struct xfs_da_node_entry *btree;
10751180 struct xfs_da3_icnode_hdr icnodehdr;
10761181 struct xfs_da_intnode *node;
10771182 struct xfs_inode *dp = args->dp;
....@@ -1086,11 +1191,11 @@
10861191 error = xfs_da_grow_inode(args, &blkno);
10871192 if (error)
10881193 goto out;
1089
- error = xfs_attr3_leaf_read(args->trans, dp, 0, -1, &bp1);
1194
+ error = xfs_attr3_leaf_read(args->trans, dp, 0, &bp1);
10901195 if (error)
10911196 goto out;
10921197
1093
- error = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp2, XFS_ATTR_FORK);
1198
+ error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK);
10941199 if (error)
10951200 goto out;
10961201
....@@ -1111,18 +1216,17 @@
11111216 if (error)
11121217 goto out;
11131218 node = bp1->b_addr;
1114
- dp->d_ops->node_hdr_from_disk(&icnodehdr, node);
1115
- btree = dp->d_ops->node_tree_p(node);
1219
+ xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
11161220
11171221 leaf = bp2->b_addr;
11181222 xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
11191223 entries = xfs_attr3_leaf_entryp(leaf);
11201224
11211225 /* both on-disk, don't endian-flip twice */
1122
- btree[0].hashval = entries[icleafhdr.count - 1].hashval;
1123
- btree[0].before = cpu_to_be32(blkno);
1226
+ icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
1227
+ icnodehdr.btree[0].before = cpu_to_be32(blkno);
11241228 icnodehdr.count = 1;
1125
- dp->d_ops->node_hdr_to_disk(node, &icnodehdr);
1229
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
11261230 xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
11271231 error = 0;
11281232 out:
....@@ -1152,7 +1256,7 @@
11521256
11531257 trace_xfs_attr_leaf_create(args);
11541258
1155
- error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp,
1259
+ error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp,
11561260 XFS_ATTR_FORK);
11571261 if (error)
11581262 return error;
....@@ -1378,8 +1482,9 @@
13781482 entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
13791483 ichdr->freemap[mapindex].size);
13801484 entry->hashval = cpu_to_be32(args->hashval);
1381
- entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
1382
- entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
1485
+ entry->flags = args->attr_filter;
1486
+ if (tmp)
1487
+ entry->flags |= XFS_ATTR_LOCAL;
13831488 if (args->op_flags & XFS_DA_OP_RENAME) {
13841489 entry->flags |= XFS_ATTR_INCOMPLETE;
13851490 if ((args->blkno2 == args->blkno) &&
....@@ -1464,7 +1569,7 @@
14641569
14651570 trace_xfs_attr_leaf_compact(args);
14661571
1467
- tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
1572
+ tmpbuffer = kmem_alloc(args->geo->blksize, 0);
14681573 memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
14691574 memset(bp->b_addr, 0, args->geo->blksize);
14701575 leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
....@@ -1538,7 +1643,7 @@
15381643 {
15391644 struct xfs_attr3_icleaf_hdr ichdr1;
15401645 struct xfs_attr3_icleaf_hdr ichdr2;
1541
- struct xfs_mount *mp = leaf1_bp->b_target->bt_mount;
1646
+ struct xfs_mount *mp = leaf1_bp->b_mount;
15421647
15431648 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr);
15441649 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr);
....@@ -1924,7 +2029,7 @@
19242029 if (blkno == 0)
19252030 continue;
19262031 error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
1927
- blkno, -1, &bp);
2032
+ blkno, &bp);
19282033 if (error)
19292034 return error;
19302035
....@@ -2183,7 +2288,7 @@
21832288 struct xfs_attr_leafblock *tmp_leaf;
21842289 struct xfs_attr3_icleaf_hdr tmphdr;
21852290
2186
- tmp_leaf = kmem_zalloc(state->args->geo->blksize, KM_SLEEP);
2291
+ tmp_leaf = kmem_zalloc(state->args->geo->blksize, 0);
21872292
21882293 /*
21892294 * Copy the header into the temp leaf so that all the stuff
....@@ -2274,8 +2379,10 @@
22742379 leaf = bp->b_addr;
22752380 xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
22762381 entries = xfs_attr3_leaf_entryp(leaf);
2277
- if (ichdr.count >= args->geo->blksize / 8)
2382
+ if (ichdr.count >= args->geo->blksize / 8) {
2383
+ xfs_buf_mark_corrupt(bp);
22782384 return -EFSCORRUPTED;
2385
+ }
22792386
22802387 /*
22812388 * Binary search. (note: small blocks will skip this loop)
....@@ -2291,10 +2398,14 @@
22912398 else
22922399 break;
22932400 }
2294
- if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count)))
2401
+ if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
2402
+ xfs_buf_mark_corrupt(bp);
22952403 return -EFSCORRUPTED;
2296
- if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval))
2404
+ }
2405
+ if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
2406
+ xfs_buf_mark_corrupt(bp);
22972407 return -EFSCORRUPTED;
2408
+ }
22982409
22992410 /*
23002411 * Since we may have duplicate hashval's, find the first matching
....@@ -2322,33 +2433,17 @@
23222433 /*
23232434 * GROT: Add code to remove incomplete entries.
23242435 */
2325
- /*
2326
- * If we are looking for INCOMPLETE entries, show only those.
2327
- * If we are looking for complete entries, show only those.
2328
- */
2329
- if ((args->flags & XFS_ATTR_INCOMPLETE) !=
2330
- (entry->flags & XFS_ATTR_INCOMPLETE)) {
2331
- continue;
2332
- }
23332436 if (entry->flags & XFS_ATTR_LOCAL) {
23342437 name_loc = xfs_attr3_leaf_name_local(leaf, probe);
2335
- if (name_loc->namelen != args->namelen)
2336
- continue;
2337
- if (memcmp(args->name, name_loc->nameval,
2338
- args->namelen) != 0)
2339
- continue;
2340
- if (!xfs_attr_namesp_match(args->flags, entry->flags))
2438
+ if (!xfs_attr_match(args, name_loc->namelen,
2439
+ name_loc->nameval, entry->flags))
23412440 continue;
23422441 args->index = probe;
23432442 return -EEXIST;
23442443 } else {
23452444 name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
2346
- if (name_rmt->namelen != args->namelen)
2347
- continue;
2348
- if (memcmp(args->name, name_rmt->name,
2349
- args->namelen) != 0)
2350
- continue;
2351
- if (!xfs_attr_namesp_match(args->flags, entry->flags))
2445
+ if (!xfs_attr_match(args, name_rmt->namelen,
2446
+ name_rmt->name, entry->flags))
23522447 continue;
23532448 args->index = probe;
23542449 args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
....@@ -2366,6 +2461,10 @@
23662461 /*
23672462 * Get the value associated with an attribute name from a leaf attribute
23682463 * list structure.
2464
+ *
2465
+ * If args->valuelen is zero, only the length needs to be returned. Unlike a
2466
+ * lookup, we only return an error if the attribute does not exist or we can't
2467
+ * retrieve the value.
23692468 */
23702469 int
23712470 xfs_attr3_leaf_getvalue(
....@@ -2377,7 +2476,6 @@
23772476 struct xfs_attr_leaf_entry *entry;
23782477 struct xfs_attr_leaf_name_local *name_loc;
23792478 struct xfs_attr_leaf_name_remote *name_rmt;
2380
- int valuelen;
23812479
23822480 leaf = bp->b_addr;
23832481 xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
....@@ -2389,36 +2487,19 @@
23892487 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
23902488 ASSERT(name_loc->namelen == args->namelen);
23912489 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
2392
- valuelen = be16_to_cpu(name_loc->valuelen);
2393
- if (args->flags & ATTR_KERNOVAL) {
2394
- args->valuelen = valuelen;
2395
- return 0;
2396
- }
2397
- if (args->valuelen < valuelen) {
2398
- args->valuelen = valuelen;
2399
- return -ERANGE;
2400
- }
2401
- args->valuelen = valuelen;
2402
- memcpy(args->value, &name_loc->nameval[args->namelen], valuelen);
2403
- } else {
2404
- name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2405
- ASSERT(name_rmt->namelen == args->namelen);
2406
- ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
2407
- args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
2408
- args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2409
- args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
2410
- args->rmtvaluelen);
2411
- if (args->flags & ATTR_KERNOVAL) {
2412
- args->valuelen = args->rmtvaluelen;
2413
- return 0;
2414
- }
2415
- if (args->valuelen < args->rmtvaluelen) {
2416
- args->valuelen = args->rmtvaluelen;
2417
- return -ERANGE;
2418
- }
2419
- args->valuelen = args->rmtvaluelen;
2490
+ return xfs_attr_copy_value(args,
2491
+ &name_loc->nameval[args->namelen],
2492
+ be16_to_cpu(name_loc->valuelen));
24202493 }
2421
- return 0;
2494
+
2495
+ name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2496
+ ASSERT(name_rmt->namelen == args->namelen);
2497
+ ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
2498
+ args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
2499
+ args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2500
+ args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
2501
+ args->rmtvaluelen);
2502
+ return xfs_attr_copy_value(args, NULL, args->rmtvaluelen);
24222503 }
24232504
24242505 /*========================================================================
....@@ -2581,7 +2662,7 @@
25812662 {
25822663 struct xfs_attr3_icleaf_hdr ichdr;
25832664 struct xfs_attr_leaf_entry *entries;
2584
- struct xfs_mount *mp = bp->b_target->bt_mount;
2665
+ struct xfs_mount *mp = bp->b_mount;
25852666
25862667 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr);
25872668 entries = xfs_attr3_leaf_entryp(bp->b_addr);
....@@ -2668,7 +2749,7 @@
26682749 /*
26692750 * Set up the operation.
26702751 */
2671
- error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
2752
+ error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp);
26722753 if (error)
26732754 return error;
26742755
....@@ -2708,10 +2789,7 @@
27082789 XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
27092790 }
27102791
2711
- /*
2712
- * Commit the flag value change and start the next trans in series.
2713
- */
2714
- return xfs_trans_roll_inode(&args->trans, args->dp);
2792
+ return 0;
27152793 }
27162794
27172795 /*
....@@ -2735,7 +2813,7 @@
27352813 /*
27362814 * Set up the operation.
27372815 */
2738
- error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
2816
+ error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp);
27392817 if (error)
27402818 return error;
27412819
....@@ -2759,10 +2837,7 @@
27592837 XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
27602838 }
27612839
2762
- /*
2763
- * Commit the flag value change and start the next trans in series.
2764
- */
2765
- return xfs_trans_roll_inode(&args->trans, args->dp);
2840
+ return 0;
27662841 }
27672842
27682843 /*
....@@ -2797,7 +2872,7 @@
27972872 /*
27982873 * Read the block containing the "old" attr
27992874 */
2800
- error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1);
2875
+ error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp1);
28012876 if (error)
28022877 return error;
28032878
....@@ -2806,7 +2881,7 @@
28062881 */
28072882 if (args->blkno2 != args->blkno) {
28082883 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2,
2809
- -1, &bp2);
2884
+ &bp2);
28102885 if (error)
28112886 return error;
28122887 } else {
....@@ -2877,10 +2952,5 @@
28772952 XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
28782953 }
28792954
2880
- /*
2881
- * Commit the flag value change and start the next trans in series.
2882
- */
2883
- error = xfs_trans_roll_inode(&args->trans, args->dp);
2884
-
2885
- return error;
2955
+ return 0;
28862956 }