~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to fs/xfs/xfs_dir2_block.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include "xfs_trans.h"
24
24
#include "xfs_sb.h"
25
25
#include "xfs_ag.h"
26
 
#include "xfs_dir2.h"
27
26
#include "xfs_mount.h"
28
27
#include "xfs_da_btree.h"
29
28
#include "xfs_bmap_btree.h"
30
 
#include "xfs_dir2_sf.h"
31
29
#include "xfs_dinode.h"
32
30
#include "xfs_inode.h"
33
31
#include "xfs_inode_item.h"
34
 
#include "xfs_dir2_data.h"
35
 
#include "xfs_dir2_leaf.h"
36
 
#include "xfs_dir2_block.h"
 
32
#include "xfs_dir2_format.h"
 
33
#include "xfs_dir2_priv.h"
37
34
#include "xfs_error.h"
38
35
#include "xfs_trace.h"
39
36
 
67
64
        xfs_da_args_t           *args)          /* directory op arguments */
68
65
{
69
66
        xfs_dir2_data_free_t    *bf;            /* bestfree table in block */
70
 
        xfs_dir2_block_t        *block;         /* directory block structure */
 
67
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
71
68
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf entries */
72
69
        xfs_dabuf_t             *bp;            /* buffer for block */
73
70
        xfs_dir2_block_tail_t   *btp;           /* block tail */
105
102
                return error;
106
103
        }
107
104
        ASSERT(bp != NULL);
108
 
        block = bp->data;
 
105
        hdr = bp->data;
109
106
        /*
110
107
         * Check the magic number, corrupted if wrong.
111
108
         */
112
 
        if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) {
 
109
        if (unlikely(hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))) {
113
110
                XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
114
 
                                     XFS_ERRLEVEL_LOW, mp, block);
 
111
                                     XFS_ERRLEVEL_LOW, mp, hdr);
115
112
                xfs_da_brelse(tp, bp);
116
113
                return XFS_ERROR(EFSCORRUPTED);
117
114
        }
119
116
        /*
120
117
         * Set up pointers to parts of the block.
121
118
         */
122
 
        bf = block->hdr.bestfree;
123
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
119
        bf = hdr->bestfree;
 
120
        btp = xfs_dir2_block_tail_p(mp, hdr);
124
121
        blp = xfs_dir2_block_leaf_p(btp);
125
122
        /*
126
123
         * No stale entries?  Need space for entry and new leaf.
133
130
                /*
134
131
                 * Data object just before the first leaf entry.
135
132
                 */
136
 
                enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
 
133
                enddup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
137
134
                /*
138
135
                 * If it's not free then can't do this add without cleaning up:
139
136
                 * the space before the first leaf entry needs to be free so it
146
143
                 */
147
144
                else {
148
145
                        dup = (xfs_dir2_data_unused_t *)
149
 
                              ((char *)block + be16_to_cpu(bf[0].offset));
 
146
                              ((char *)hdr + be16_to_cpu(bf[0].offset));
150
147
                        if (dup == enddup) {
151
148
                                /*
152
149
                                 * It is the biggest freespace, is it too small
159
156
                                         */
160
157
                                        if (be16_to_cpu(bf[1].length) >= len)
161
158
                                                dup = (xfs_dir2_data_unused_t *)
162
 
                                                      ((char *)block +
 
159
                                                      ((char *)hdr +
163
160
                                                       be16_to_cpu(bf[1].offset));
164
161
                                        else
165
162
                                                dup = NULL;
182
179
         */
183
180
        else if (be16_to_cpu(bf[0].length) >= len) {
184
181
                dup = (xfs_dir2_data_unused_t *)
185
 
                      ((char *)block + be16_to_cpu(bf[0].offset));
 
182
                      ((char *)hdr + be16_to_cpu(bf[0].offset));
186
183
                compact = 0;
187
184
        }
188
185
        /*
196
193
                /*
197
194
                 * Data object just before the first leaf entry.
198
195
                 */
199
 
                dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
 
196
                dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
200
197
                /*
201
198
                 * If it's not free then the data will go where the
202
199
                 * leaf data starts now, if it works at all.
255
252
                        highstale = lfloghigh = -1;
256
253
                     fromidx >= 0;
257
254
                     fromidx--) {
258
 
                        if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) {
 
255
                        if (blp[fromidx].address ==
 
256
                            cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
259
257
                                if (highstale == -1)
260
258
                                        highstale = toidx;
261
259
                                else {
272
270
                lfloghigh -= be32_to_cpu(btp->stale) - 1;
273
271
                be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
274
272
                xfs_dir2_data_make_free(tp, bp,
275
 
                        (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
 
273
                        (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
276
274
                        (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
277
275
                        &needlog, &needscan);
278
276
                blp += be32_to_cpu(btp->stale) - 1;
282
280
                 * This needs to happen before the next call to use_free.
283
281
                 */
284
282
                if (needscan) {
285
 
                        xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
 
283
                        xfs_dir2_data_freescan(mp, hdr, &needlog);
286
284
                        needscan = 0;
287
285
                }
288
286
        }
318
316
                 */
319
317
                xfs_dir2_data_use_free(tp, bp, enddup,
320
318
                        (xfs_dir2_data_aoff_t)
321
 
                        ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) -
 
319
                        ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) -
322
320
                         sizeof(*blp)),
323
321
                        (xfs_dir2_data_aoff_t)sizeof(*blp),
324
322
                        &needlog, &needscan);
331
329
                 * This needs to happen before the next call to use_free.
332
330
                 */
333
331
                if (needscan) {
334
 
                        xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
335
 
                                &needlog);
 
332
                        xfs_dir2_data_freescan(mp, hdr, &needlog);
336
333
                        needscan = 0;
337
334
                }
338
335
                /*
353
350
        else {
354
351
                for (lowstale = mid;
355
352
                     lowstale >= 0 &&
356
 
                        be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR;
 
353
                        blp[lowstale].address !=
 
354
                        cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
357
355
                     lowstale--)
358
356
                        continue;
359
357
                for (highstale = mid + 1;
360
358
                     highstale < be32_to_cpu(btp->count) &&
361
 
                        be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR &&
 
359
                        blp[highstale].address !=
 
360
                        cpu_to_be32(XFS_DIR2_NULL_DATAPTR) &&
362
361
                        (lowstale < 0 || mid - lowstale > highstale - mid);
363
362
                     highstale++)
364
363
                        continue;
397
396
         */
398
397
        blp[mid].hashval = cpu_to_be32(args->hashval);
399
398
        blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
400
 
                                (char *)dep - (char *)block));
 
399
                                (char *)dep - (char *)hdr));
401
400
        xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh);
402
401
        /*
403
402
         * Mark space for the data entry used.
404
403
         */
405
404
        xfs_dir2_data_use_free(tp, bp, dup,
406
 
                (xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
 
405
                (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
407
406
                (xfs_dir2_data_aoff_t)len, &needlog, &needscan);
408
407
        /*
409
408
         * Create the new data entry.
412
411
        dep->namelen = args->namelen;
413
412
        memcpy(dep->name, args->name, args->namelen);
414
413
        tagp = xfs_dir2_data_entry_tag_p(dep);
415
 
        *tagp = cpu_to_be16((char *)dep - (char *)block);
 
414
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
416
415
        /*
417
416
         * Clean up the bestfree array and log the header, tail, and entry.
418
417
         */
419
418
        if (needscan)
420
 
                xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
 
419
                xfs_dir2_data_freescan(mp, hdr, &needlog);
421
420
        if (needlog)
422
421
                xfs_dir2_data_log_header(tp, bp);
423
422
        xfs_dir2_block_log_tail(tp, bp);
437
436
        xfs_off_t               *offset,
438
437
        filldir_t               filldir)
439
438
{
440
 
        xfs_dir2_block_t        *block;         /* directory block structure */
 
439
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
441
440
        xfs_dabuf_t             *bp;            /* buffer for block */
442
441
        xfs_dir2_block_tail_t   *btp;           /* block tail */
443
442
        xfs_dir2_data_entry_t   *dep;           /* block data entry */
470
469
         * We'll skip entries before this.
471
470
         */
472
471
        wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
473
 
        block = bp->data;
 
472
        hdr = bp->data;
474
473
        xfs_dir2_data_check(dp, bp);
475
474
        /*
476
475
         * Set up values for the loop.
477
476
         */
478
 
        btp = xfs_dir2_block_tail_p(mp, block);
479
 
        ptr = (char *)block->u;
 
477
        btp = xfs_dir2_block_tail_p(mp, hdr);
 
478
        ptr = (char *)(hdr + 1);
480
479
        endptr = (char *)xfs_dir2_block_leaf_p(btp);
481
480
 
482
481
        /*
502
501
                /*
503
502
                 * The entry is before the desired starting point, skip it.
504
503
                 */
505
 
                if ((char *)dep - (char *)block < wantoff)
 
504
                if ((char *)dep - (char *)hdr < wantoff)
506
505
                        continue;
507
506
 
508
507
                cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
509
 
                                            (char *)dep - (char *)block);
 
508
                                            (char *)dep - (char *)hdr);
510
509
 
511
510
                /*
512
511
                 * If it didn't fit, set the final offset to here & return.
540
539
        int                     first,          /* index of first logged leaf */
541
540
        int                     last)           /* index of last logged leaf */
542
541
{
543
 
        xfs_dir2_block_t        *block;         /* directory block structure */
544
 
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf entries */
545
 
        xfs_dir2_block_tail_t   *btp;           /* block tail */
546
 
        xfs_mount_t             *mp;            /* filesystem mount point */
 
542
        xfs_dir2_data_hdr_t     *hdr = bp->data;
 
543
        xfs_dir2_leaf_entry_t   *blp;
 
544
        xfs_dir2_block_tail_t   *btp;
547
545
 
548
 
        mp = tp->t_mountp;
549
 
        block = bp->data;
550
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
546
        btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr);
551
547
        blp = xfs_dir2_block_leaf_p(btp);
552
 
        xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block),
553
 
                (uint)((char *)&blp[last + 1] - (char *)block - 1));
 
548
        xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr),
 
549
                (uint)((char *)&blp[last + 1] - (char *)hdr - 1));
554
550
}
555
551
 
556
552
/*
561
557
        xfs_trans_t             *tp,            /* transaction structure */
562
558
        xfs_dabuf_t             *bp)            /* block buffer */
563
559
{
564
 
        xfs_dir2_block_t        *block;         /* directory block structure */
565
 
        xfs_dir2_block_tail_t   *btp;           /* block tail */
566
 
        xfs_mount_t             *mp;            /* filesystem mount point */
 
560
        xfs_dir2_data_hdr_t     *hdr = bp->data;
 
561
        xfs_dir2_block_tail_t   *btp;
567
562
 
568
 
        mp = tp->t_mountp;
569
 
        block = bp->data;
570
 
        btp = xfs_dir2_block_tail_p(mp, block);
571
 
        xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block),
572
 
                (uint)((char *)(btp + 1) - (char *)block - 1));
 
563
        btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr);
 
564
        xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr),
 
565
                (uint)((char *)(btp + 1) - (char *)hdr - 1));
573
566
}
574
567
 
575
568
/*
580
573
xfs_dir2_block_lookup(
581
574
        xfs_da_args_t           *args)          /* dir lookup arguments */
582
575
{
583
 
        xfs_dir2_block_t        *block;         /* block structure */
 
576
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
584
577
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf entries */
585
578
        xfs_dabuf_t             *bp;            /* block buffer */
586
579
        xfs_dir2_block_tail_t   *btp;           /* block tail */
600
593
                return error;
601
594
        dp = args->dp;
602
595
        mp = dp->i_mount;
603
 
        block = bp->data;
 
596
        hdr = bp->data;
604
597
        xfs_dir2_data_check(dp, bp);
605
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
598
        btp = xfs_dir2_block_tail_p(mp, hdr);
606
599
        blp = xfs_dir2_block_leaf_p(btp);
607
600
        /*
608
601
         * Get the offset from the leaf entry, to point to the data.
609
602
         */
610
 
        dep = (xfs_dir2_data_entry_t *)((char *)block +
 
603
        dep = (xfs_dir2_data_entry_t *)((char *)hdr +
611
604
                xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
612
605
        /*
613
606
         * Fill in inode number, CI name if appropriate, release the block.
628
621
        int                     *entno)         /* returned entry number */
629
622
{
630
623
        xfs_dir2_dataptr_t      addr;           /* data entry address */
631
 
        xfs_dir2_block_t        *block;         /* block structure */
 
624
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
632
625
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf entries */
633
626
        xfs_dabuf_t             *bp;            /* block buffer */
634
627
        xfs_dir2_block_tail_t   *btp;           /* block tail */
654
647
                return error;
655
648
        }
656
649
        ASSERT(bp != NULL);
657
 
        block = bp->data;
 
650
        hdr = bp->data;
658
651
        xfs_dir2_data_check(dp, bp);
659
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
652
        btp = xfs_dir2_block_tail_p(mp, hdr);
660
653
        blp = xfs_dir2_block_leaf_p(btp);
661
654
        /*
662
655
         * Loop doing a binary search for our hash value.
694
687
                 * Get pointer to the entry from the leaf.
695
688
                 */
696
689
                dep = (xfs_dir2_data_entry_t *)
697
 
                        ((char *)block + xfs_dir2_dataptr_to_off(mp, addr));
 
690
                        ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr));
698
691
                /*
699
692
                 * Compare name and if it's an exact match, return the index
700
693
                 * and buffer. If it's the first case-insensitive match, store
733
726
xfs_dir2_block_removename(
734
727
        xfs_da_args_t           *args)          /* directory operation args */
735
728
{
736
 
        xfs_dir2_block_t        *block;         /* block structure */
 
729
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
737
730
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf pointer */
738
731
        xfs_dabuf_t             *bp;            /* block buffer */
739
732
        xfs_dir2_block_tail_t   *btp;           /* block tail */
760
753
        dp = args->dp;
761
754
        tp = args->trans;
762
755
        mp = dp->i_mount;
763
 
        block = bp->data;
764
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
756
        hdr = bp->data;
 
757
        btp = xfs_dir2_block_tail_p(mp, hdr);
765
758
        blp = xfs_dir2_block_leaf_p(btp);
766
759
        /*
767
760
         * Point to the data entry using the leaf entry.
768
761
         */
769
762
        dep = (xfs_dir2_data_entry_t *)
770
 
              ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
 
763
              ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
771
764
        /*
772
765
         * Mark the data entry's space free.
773
766
         */
774
767
        needlog = needscan = 0;
775
768
        xfs_dir2_data_make_free(tp, bp,
776
 
                (xfs_dir2_data_aoff_t)((char *)dep - (char *)block),
 
769
                (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
777
770
                xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
778
771
        /*
779
772
         * Fix up the block tail.
789
782
         * Fix up bestfree, log the header if necessary.
790
783
         */
791
784
        if (needscan)
792
 
                xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
 
785
                xfs_dir2_data_freescan(mp, hdr, &needlog);
793
786
        if (needlog)
794
787
                xfs_dir2_data_log_header(tp, bp);
795
788
        xfs_dir2_data_check(dp, bp);
796
789
        /*
797
790
         * See if the size as a shortform is good enough.
798
791
         */
799
 
        if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) >
800
 
            XFS_IFORK_DSIZE(dp)) {
 
792
        size = xfs_dir2_block_sfsize(dp, hdr, &sfh);
 
793
        if (size > XFS_IFORK_DSIZE(dp)) {
801
794
                xfs_da_buf_done(bp);
802
795
                return 0;
803
796
        }
815
808
xfs_dir2_block_replace(
816
809
        xfs_da_args_t           *args)          /* directory operation args */
817
810
{
818
 
        xfs_dir2_block_t        *block;         /* block structure */
 
811
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
819
812
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf entries */
820
813
        xfs_dabuf_t             *bp;            /* block buffer */
821
814
        xfs_dir2_block_tail_t   *btp;           /* block tail */
836
829
        }
837
830
        dp = args->dp;
838
831
        mp = dp->i_mount;
839
 
        block = bp->data;
840
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
832
        hdr = bp->data;
 
833
        btp = xfs_dir2_block_tail_p(mp, hdr);
841
834
        blp = xfs_dir2_block_leaf_p(btp);
842
835
        /*
843
836
         * Point to the data entry we need to change.
844
837
         */
845
838
        dep = (xfs_dir2_data_entry_t *)
846
 
              ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
 
839
              ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
847
840
        ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
848
841
        /*
849
842
         * Change the inode number to the new value.
882
875
        xfs_dabuf_t             *dbp)           /* data buffer */
883
876
{
884
877
        __be16                  *bestsp;        /* leaf bests table */
885
 
        xfs_dir2_block_t        *block;         /* block structure */
 
878
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
886
879
        xfs_dir2_block_tail_t   *btp;           /* block tail */
887
880
        xfs_inode_t             *dp;            /* incore directory inode */
888
881
        xfs_dir2_data_unused_t  *dup;           /* unused data entry */
906
899
        tp = args->trans;
907
900
        mp = dp->i_mount;
908
901
        leaf = lbp->data;
909
 
        ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
 
902
        ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
910
903
        ltp = xfs_dir2_leaf_tail_p(mp, leaf);
911
904
        /*
912
905
         * If there are data blocks other than the first one, take this
917
910
        while (dp->i_d.di_size > mp->m_dirblksize) {
918
911
                bestsp = xfs_dir2_leaf_bests_p(ltp);
919
912
                if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
920
 
                    mp->m_dirblksize - (uint)sizeof(block->hdr)) {
 
913
                    mp->m_dirblksize - (uint)sizeof(*hdr)) {
921
914
                        if ((error =
922
915
                            xfs_dir2_leaf_trim_data(args, lbp,
923
916
                                    (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
935
928
                    XFS_DATA_FORK))) {
936
929
                goto out;
937
930
        }
938
 
        block = dbp->data;
939
 
        ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC);
 
931
        hdr = dbp->data;
 
932
        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
940
933
        /*
941
934
         * Size of the "leaf" area in the block.
942
935
         */
943
 
        size = (uint)sizeof(block->tail) +
 
936
        size = (uint)sizeof(xfs_dir2_block_tail_t) +
944
937
               (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
945
938
        /*
946
939
         * Look at the last data entry.
947
940
         */
948
 
        tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1;
949
 
        dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
 
941
        tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1;
 
942
        dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
950
943
        /*
951
944
         * If it's not free or is too short we can't do it.
952
945
         */
958
951
        /*
959
952
         * Start converting it to block form.
960
953
         */
961
 
        block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
 
954
        hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
962
955
        needlog = 1;
963
956
        needscan = 0;
964
957
        /*
969
962
        /*
970
963
         * Initialize the block tail.
971
964
         */
972
 
        btp = xfs_dir2_block_tail_p(mp, block);
 
965
        btp = xfs_dir2_block_tail_p(mp, hdr);
973
966
        btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
974
967
        btp->stale = 0;
975
968
        xfs_dir2_block_log_tail(tp, dbp);
978
971
         */
979
972
        lep = xfs_dir2_block_leaf_p(btp);
980
973
        for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
981
 
                if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR)
 
974
                if (leaf->ents[from].address ==
 
975
                    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
982
976
                        continue;
983
977
                lep[to++] = leaf->ents[from];
984
978
        }
988
982
         * Scan the bestfree if we need it and log the data block header.
989
983
         */
990
984
        if (needscan)
991
 
                xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
 
985
                xfs_dir2_data_freescan(mp, hdr, &needlog);
992
986
        if (needlog)
993
987
                xfs_dir2_data_log_header(tp, dbp);
994
988
        /*
1002
996
        /*
1003
997
         * Now see if the resulting block can be shrunken to shortform.
1004
998
         */
1005
 
        if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) >
1006
 
            XFS_IFORK_DSIZE(dp)) {
 
999
        size = xfs_dir2_block_sfsize(dp, hdr, &sfh);
 
1000
        if (size > XFS_IFORK_DSIZE(dp)) {
1007
1001
                error = 0;
1008
1002
                goto out;
1009
1003
        }
1024
1018
        xfs_da_args_t           *args)          /* operation arguments */
1025
1019
{
1026
1020
        xfs_dir2_db_t           blkno;          /* dir-relative block # (0) */
1027
 
        xfs_dir2_block_t        *block;         /* block structure */
 
1021
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
1028
1022
        xfs_dir2_leaf_entry_t   *blp;           /* block leaf entries */
1029
1023
        xfs_dabuf_t             *bp;            /* block buffer */
1030
1024
        xfs_dir2_block_tail_t   *btp;           /* block tail pointer */
1031
 
        char                    *buf;           /* sf buffer */
1032
 
        int                     buf_len;
1033
1025
        xfs_dir2_data_entry_t   *dep;           /* data entry pointer */
1034
1026
        xfs_inode_t             *dp;            /* incore directory inode */
1035
1027
        int                     dummy;          /* trash */
1043
1035
        int                     newoffset;      /* offset from current entry */
1044
1036
        int                     offset;         /* target block offset */
1045
1037
        xfs_dir2_sf_entry_t     *sfep;          /* sf entry pointer */
1046
 
        xfs_dir2_sf_t           *sfp;           /* shortform structure */
 
1038
        xfs_dir2_sf_hdr_t       *oldsfp;        /* old shortform header  */
 
1039
        xfs_dir2_sf_hdr_t       *sfp;           /* shortform header  */
1047
1040
        __be16                  *tagp;          /* end of data entry */
1048
1041
        xfs_trans_t             *tp;            /* transaction pointer */
1049
1042
        struct xfs_name         name;
1061
1054
                ASSERT(XFS_FORCED_SHUTDOWN(mp));
1062
1055
                return XFS_ERROR(EIO);
1063
1056
        }
 
1057
 
 
1058
        oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 
1059
 
1064
1060
        ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
1065
1061
        ASSERT(dp->i_df.if_u1.if_data != NULL);
1066
 
        sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
1067
 
        ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count));
 
1062
        ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count));
 
1063
 
1068
1064
        /*
1069
 
         * Copy the directory into the stack buffer.
 
1065
         * Copy the directory into a temporary buffer.
1070
1066
         * Then pitch the incore inode data so we can make extents.
1071
1067
         */
1072
 
 
1073
 
        buf_len = dp->i_df.if_bytes;
1074
 
        buf = kmem_alloc(buf_len, KM_SLEEP);
1075
 
 
1076
 
        memcpy(buf, sfp, buf_len);
1077
 
        xfs_idata_realloc(dp, -buf_len, XFS_DATA_FORK);
 
1068
        sfp = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP);
 
1069
        memcpy(sfp, oldsfp, dp->i_df.if_bytes);
 
1070
 
 
1071
        xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK);
1078
1072
        dp->i_d.di_size = 0;
1079
1073
        xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1080
 
        /*
1081
 
         * Reset pointer - old sfp is gone.
1082
 
         */
1083
 
        sfp = (xfs_dir2_sf_t *)buf;
 
1074
 
1084
1075
        /*
1085
1076
         * Add block 0 to the inode.
1086
1077
         */
1087
1078
        error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno);
1088
1079
        if (error) {
1089
 
                kmem_free(buf);
 
1080
                kmem_free(sfp);
1090
1081
                return error;
1091
1082
        }
1092
1083
        /*
1094
1085
         */
1095
1086
        error = xfs_dir2_data_init(args, blkno, &bp);
1096
1087
        if (error) {
1097
 
                kmem_free(buf);
 
1088
                kmem_free(sfp);
1098
1089
                return error;
1099
1090
        }
1100
 
        block = bp->data;
1101
 
        block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
 
1091
        hdr = bp->data;
 
1092
        hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
1102
1093
        /*
1103
1094
         * Compute size of block "tail" area.
1104
1095
         */
1105
1096
        i = (uint)sizeof(*btp) +
1106
 
            (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
 
1097
            (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
1107
1098
        /*
1108
1099
         * The whole thing is initialized to free by the init routine.
1109
1100
         * Say we're using the leaf and tail area.
1110
1101
         */
1111
 
        dup = (xfs_dir2_data_unused_t *)block->u;
 
1102
        dup = (xfs_dir2_data_unused_t *)(hdr + 1);
1112
1103
        needlog = needscan = 0;
1113
1104
        xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog,
1114
1105
                &needscan);
1116
1107
        /*
1117
1108
         * Fill in the tail.
1118
1109
         */
1119
 
        btp = xfs_dir2_block_tail_p(mp, block);
1120
 
        btp->count = cpu_to_be32(sfp->hdr.count + 2);   /* ., .. */
 
1110
        btp = xfs_dir2_block_tail_p(mp, hdr);
 
1111
        btp->count = cpu_to_be32(sfp->count + 2);       /* ., .. */
1121
1112
        btp->stale = 0;
1122
1113
        blp = xfs_dir2_block_leaf_p(btp);
1123
 
        endoffset = (uint)((char *)blp - (char *)block);
 
1114
        endoffset = (uint)((char *)blp - (char *)hdr);
1124
1115
        /*
1125
1116
         * Remove the freespace, we'll manage it.
1126
1117
         */
1127
1118
        xfs_dir2_data_use_free(tp, bp, dup,
1128
 
                (xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
 
1119
                (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
1129
1120
                be16_to_cpu(dup->length), &needlog, &needscan);
1130
1121
        /*
1131
1122
         * Create entry for .
1132
1123
         */
1133
1124
        dep = (xfs_dir2_data_entry_t *)
1134
 
              ((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
 
1125
              ((char *)hdr + XFS_DIR2_DATA_DOT_OFFSET);
1135
1126
        dep->inumber = cpu_to_be64(dp->i_ino);
1136
1127
        dep->namelen = 1;
1137
1128
        dep->name[0] = '.';
1138
1129
        tagp = xfs_dir2_data_entry_tag_p(dep);
1139
 
        *tagp = cpu_to_be16((char *)dep - (char *)block);
 
1130
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1140
1131
        xfs_dir2_data_log_entry(tp, bp, dep);
1141
1132
        blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
1142
1133
        blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1143
 
                                (char *)dep - (char *)block));
 
1134
                                (char *)dep - (char *)hdr));
1144
1135
        /*
1145
1136
         * Create entry for ..
1146
1137
         */
1147
1138
        dep = (xfs_dir2_data_entry_t *)
1148
 
                ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
1149
 
        dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent));
 
1139
                ((char *)hdr + XFS_DIR2_DATA_DOTDOT_OFFSET);
 
1140
        dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
1150
1141
        dep->namelen = 2;
1151
1142
        dep->name[0] = dep->name[1] = '.';
1152
1143
        tagp = xfs_dir2_data_entry_tag_p(dep);
1153
 
        *tagp = cpu_to_be16((char *)dep - (char *)block);
 
1144
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1154
1145
        xfs_dir2_data_log_entry(tp, bp, dep);
1155
1146
        blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
1156
1147
        blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1157
 
                                (char *)dep - (char *)block));
 
1148
                                (char *)dep - (char *)hdr));
1158
1149
        offset = XFS_DIR2_DATA_FIRST_OFFSET;
1159
1150
        /*
1160
1151
         * Loop over existing entries, stuff them in.
1161
1152
         */
1162
 
        if ((i = 0) == sfp->hdr.count)
 
1153
        i = 0;
 
1154
        if (!sfp->count)
1163
1155
                sfep = NULL;
1164
1156
        else
1165
1157
                sfep = xfs_dir2_sf_firstentry(sfp);
1179
1171
                 * There should be a hole here, make one.
1180
1172
                 */
1181
1173
                if (offset < newoffset) {
1182
 
                        dup = (xfs_dir2_data_unused_t *)
1183
 
                              ((char *)block + offset);
 
1174
                        dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
1184
1175
                        dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1185
1176
                        dup->length = cpu_to_be16(newoffset - offset);
1186
1177
                        *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
1187
 
                                ((char *)dup - (char *)block));
 
1178
                                ((char *)dup - (char *)hdr));
1188
1179
                        xfs_dir2_data_log_unused(tp, bp, dup);
1189
 
                        (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block,
1190
 
                                dup, &dummy);
 
1180
                        xfs_dir2_data_freeinsert(hdr, dup, &dummy);
1191
1181
                        offset += be16_to_cpu(dup->length);
1192
1182
                        continue;
1193
1183
                }
1194
1184
                /*
1195
1185
                 * Copy a real entry.
1196
1186
                 */
1197
 
                dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
1198
 
                dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp,
1199
 
                                xfs_dir2_sf_inumberp(sfep)));
 
1187
                dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
 
1188
                dep->inumber = cpu_to_be64(xfs_dir2_sfe_get_ino(sfp, sfep));
1200
1189
                dep->namelen = sfep->namelen;
1201
1190
                memcpy(dep->name, sfep->name, dep->namelen);
1202
1191
                tagp = xfs_dir2_data_entry_tag_p(dep);
1203
 
                *tagp = cpu_to_be16((char *)dep - (char *)block);
 
1192
                *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1204
1193
                xfs_dir2_data_log_entry(tp, bp, dep);
1205
1194
                name.name = sfep->name;
1206
1195
                name.len = sfep->namelen;
1207
1196
                blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
1208
1197
                                                        hashname(&name));
1209
1198
                blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1210
 
                                                 (char *)dep - (char *)block));
1211
 
                offset = (int)((char *)(tagp + 1) - (char *)block);
1212
 
                if (++i == sfp->hdr.count)
 
1199
                                                 (char *)dep - (char *)hdr));
 
1200
                offset = (int)((char *)(tagp + 1) - (char *)hdr);
 
1201
                if (++i == sfp->count)
1213
1202
                        sfep = NULL;
1214
1203
                else
1215
1204
                        sfep = xfs_dir2_sf_nextentry(sfp, sfep);
1216
1205
        }
1217
1206
        /* Done with the temporary buffer */
1218
 
        kmem_free(buf);
 
1207
        kmem_free(sfp);
1219
1208
        /*
1220
1209
         * Sort the leaf entries by hash value.
1221
1210
         */