~ubuntu-branches/ubuntu/utopic/xfsprogs/utopic-proposed

« back to all changes in this revision

Viewing changes to libxfs/xfs_dir2_data.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Scott
  • Date: 2009-05-06 11:29:18 UTC
  • mfrom: (8.1.1 jaunty)
  • Revision ID: james.westby@ubuntu.com-20090506112918-uzoyzcp90rtr8td7
Tags: 3.0.2
New bugfix release

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/*
20
 
 * xfs_dir2_data.c
21
 
 * Core data block handling routines for XFS V2 directories.
22
 
 * See xfs_dir2_data.h for data structures.
23
 
 */
24
 
 
25
19
#include <xfs.h>
26
20
 
27
21
 
53
47
        xfs_mount_t             *mp;            /* filesystem mount point */
54
48
        char                    *p;             /* current data position */
55
49
        int                     stale;          /* count of stale leaves */
 
50
        struct xfs_name         name;
56
51
 
57
52
        mp = dp->i_mount;
58
53
        d = bp->data;
59
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
60
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
54
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
55
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
61
56
        bf = d->hdr.bestfree;
62
57
        p = (char *)d->u;
63
 
        if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
64
 
                btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
65
 
                lep = XFS_DIR2_BLOCK_LEAF_P(btp);
 
58
        if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
 
59
                btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d);
 
60
                lep = xfs_dir2_block_leaf_p(btp);
66
61
                endp = (char *)lep;
67
62
        } else
68
63
                endp = (char *)d + mp->m_dirblksize;
82
77
                ASSERT(!bf[2].offset);
83
78
                freeseen |= 1 << 2;
84
79
        }
85
 
        ASSERT(INT_GET(bf[0].length, ARCH_CONVERT) >= INT_GET(bf[1].length, ARCH_CONVERT));
86
 
        ASSERT(INT_GET(bf[1].length, ARCH_CONVERT) >= INT_GET(bf[2].length, ARCH_CONVERT));
 
80
        ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length));
 
81
        ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length));
87
82
        /*
88
83
         * Loop over the data/unused entries.
89
84
         */
94
89
                 * If we find it, account for that, else make sure it
95
90
                 * doesn't need to be there.
96
91
                 */
97
 
                if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
 
92
                if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
98
93
                        ASSERT(lastfree == 0);
99
 
                        ASSERT(INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT) ==
 
94
                        ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) ==
100
95
                               (char *)dup - (char *)d);
101
96
                        dfp = xfs_dir2_data_freefind(d, dup);
102
97
                        if (dfp) {
103
98
                                i = (int)(dfp - bf);
104
99
                                ASSERT((freeseen & (1 << i)) == 0);
105
100
                                freeseen |= 1 << i;
106
 
                        } else
107
 
                                ASSERT(INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(bf[2].length, ARCH_CONVERT));
108
 
                        p += INT_GET(dup->length, ARCH_CONVERT);
 
101
                        } else {
 
102
                                ASSERT(be16_to_cpu(dup->length) <=
 
103
                                       be16_to_cpu(bf[2].length));
 
104
                        }
 
105
                        p += be16_to_cpu(dup->length);
109
106
                        lastfree = 1;
110
107
                        continue;
111
108
                }
117
114
                 */
118
115
                dep = (xfs_dir2_data_entry_t *)p;
119
116
                ASSERT(dep->namelen != 0);
120
 
                ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0);
121
 
                ASSERT(INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) ==
 
117
                ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
 
118
                ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) ==
122
119
                       (char *)dep - (char *)d);
123
120
                count++;
124
121
                lastfree = 0;
125
 
                if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
126
 
                        addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
 
122
                if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
 
123
                        addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
127
124
                                (xfs_dir2_data_aoff_t)
128
125
                                ((char *)dep - (char *)d));
129
 
                        hash = xfs_da_hashname((char *)dep->name, dep->namelen);
130
 
                        for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
131
 
                                if (INT_GET(lep[i].address, ARCH_CONVERT) == addr &&
132
 
                                    INT_GET(lep[i].hashval, ARCH_CONVERT) == hash)
 
126
                        name.name = dep->name;
 
127
                        name.len = dep->namelen;
 
128
                        hash = mp->m_dirnameops->hashname(&name);
 
129
                        for (i = 0; i < be32_to_cpu(btp->count); i++) {
 
130
                                if (be32_to_cpu(lep[i].address) == addr &&
 
131
                                    be32_to_cpu(lep[i].hashval) == hash)
133
132
                                        break;
134
133
                        }
135
 
                        ASSERT(i < INT_GET(btp->count, ARCH_CONVERT));
 
134
                        ASSERT(i < be32_to_cpu(btp->count));
136
135
                }
137
 
                p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
 
136
                p += xfs_dir2_data_entsize(dep->namelen);
138
137
        }
139
138
        /*
140
139
         * Need to have seen all the entries and all the bestfree slots.
141
140
         */
142
141
        ASSERT(freeseen == 7);
143
 
        if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
144
 
                for (i = stale = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
145
 
                        if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
 
142
        if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
 
143
                for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
 
144
                        if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR)
146
145
                                stale++;
147
146
                        if (i > 0)
148
 
                                ASSERT(INT_GET(lep[i].hashval, ARCH_CONVERT) >= INT_GET(lep[i - 1].hashval, ARCH_CONVERT));
 
147
                                ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval));
149
148
                }
150
 
                ASSERT(count == INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT));
151
 
                ASSERT(stale == INT_GET(btp->stale, ARCH_CONVERT));
 
149
                ASSERT(count == be32_to_cpu(btp->count) - be32_to_cpu(btp->stale));
 
150
                ASSERT(stale == be32_to_cpu(btp->stale));
152
151
        }
153
152
}
154
153
#endif
176
175
         * Check order, non-overlapping entries, and if we find the
177
176
         * one we're looking for it has to be exact.
178
177
         */
179
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
180
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
178
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
179
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
181
180
        for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0;
182
181
             dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
183
182
             dfp++) {
187
186
                        continue;
188
187
                }
189
188
                ASSERT(seenzero == 0);
190
 
                if (INT_GET(dfp->offset, ARCH_CONVERT) == off) {
 
189
                if (be16_to_cpu(dfp->offset) == off) {
191
190
                        matched = 1;
192
 
                        ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(dup->length, ARCH_CONVERT));
193
 
                } else if (off < INT_GET(dfp->offset, ARCH_CONVERT))
194
 
                        ASSERT(off + INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(dfp->offset, ARCH_CONVERT));
 
191
                        ASSERT(dfp->length == dup->length);
 
192
                } else if (off < be16_to_cpu(dfp->offset))
 
193
                        ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset));
195
194
                else
196
 
                        ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) + INT_GET(dfp->length, ARCH_CONVERT) <= off);
197
 
                ASSERT(matched || INT_GET(dfp->length, ARCH_CONVERT) >= INT_GET(dup->length, ARCH_CONVERT));
 
195
                        ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off);
 
196
                ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length));
198
197
                if (dfp > &d->hdr.bestfree[0])
199
 
                        ASSERT(INT_GET(dfp[-1].length, ARCH_CONVERT) >= INT_GET(dfp[0].length, ARCH_CONVERT));
 
198
                        ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length));
200
199
        }
201
200
#endif
202
201
        /*
203
202
         * If this is smaller than the smallest bestfree entry,
204
203
         * it can't be there since they're sorted.
205
204
         */
206
 
        if (INT_GET(dup->length, ARCH_CONVERT) < INT_GET(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length, ARCH_CONVERT))
 
205
        if (be16_to_cpu(dup->length) <
 
206
            be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length))
207
207
                return NULL;
208
208
        /*
209
209
         * Look at the three bestfree entries for our guy.
213
213
             dfp++) {
214
214
                if (!dfp->offset)
215
215
                        return NULL;
216
 
                if (INT_GET(dfp->offset, ARCH_CONVERT) == off)
 
216
                if (be16_to_cpu(dfp->offset) == off)
217
217
                        return dfp;
218
218
        }
219
219
        /*
235
235
        xfs_dir2_data_free_t    new;            /* new bestfree entry */
236
236
 
237
237
#ifdef __KERNEL__
238
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
239
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
238
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
239
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
240
240
#endif
241
241
        dfp = d->hdr.bestfree;
242
 
        INT_COPY(new.length, dup->length, ARCH_CONVERT);
243
 
        INT_SET(new.offset, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dup - (char *)d));
 
242
        new.length = dup->length;
 
243
        new.offset = cpu_to_be16((char *)dup - (char *)d);
244
244
        /*
245
245
         * Insert at position 0, 1, or 2; or not at all.
246
246
         */
247
 
        if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[0].length, ARCH_CONVERT)) {
 
247
        if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
248
248
                dfp[2] = dfp[1];
249
249
                dfp[1] = dfp[0];
250
250
                dfp[0] = new;
251
251
                *loghead = 1;
252
252
                return &dfp[0];
253
253
        }
254
 
        if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[1].length, ARCH_CONVERT)) {
 
254
        if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
255
255
                dfp[2] = dfp[1];
256
256
                dfp[1] = new;
257
257
                *loghead = 1;
258
258
                return &dfp[1];
259
259
        }
260
 
        if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[2].length, ARCH_CONVERT)) {
 
260
        if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
261
261
                dfp[2] = new;
262
262
                *loghead = 1;
263
263
                return &dfp[2];
268
268
/*
269
269
 * Remove a bestfree entry from the table.
270
270
 */
271
 
void
 
271
STATIC void
272
272
xfs_dir2_data_freeremove(
273
273
        xfs_dir2_data_t         *d,             /* data block pointer */
274
274
        xfs_dir2_data_free_t    *dfp,           /* bestfree entry pointer */
275
275
        int                     *loghead)       /* out: log data header */
276
276
{
277
277
#ifdef __KERNEL__
278
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
279
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
278
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
279
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
280
280
#endif
281
281
        /*
282
282
         * It's the first entry, slide the next 2 up.
310
310
xfs_dir2_data_freescan(
311
311
        xfs_mount_t             *mp,            /* filesystem mount point */
312
312
        xfs_dir2_data_t         *d,             /* data block pointer */
313
 
        int                     *loghead,       /* out: log data header */
314
 
        char                    *aendp)         /* in: caller's endp */
 
313
        int                     *loghead)       /* out: log data header */
315
314
{
316
315
        xfs_dir2_block_tail_t   *btp;           /* block tail */
317
316
        xfs_dir2_data_entry_t   *dep;           /* active data entry */
320
319
        char                    *p;             /* current entry pointer */
321
320
 
322
321
#ifdef __KERNEL__
323
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
324
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
322
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
323
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
325
324
#endif
326
325
        /*
327
326
         * Start by clearing the table.
332
331
         * Set up pointers.
333
332
         */
334
333
        p = (char *)d->u;
335
 
        if (aendp)
336
 
                endp = aendp;
337
 
        else if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
338
 
                btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
339
 
                endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
 
334
        if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
 
335
                btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d);
 
336
                endp = (char *)xfs_dir2_block_leaf_p(btp);
340
337
        } else
341
338
                endp = (char *)d + mp->m_dirblksize;
342
339
        /*
347
344
                /*
348
345
                 * If it's a free entry, insert it.
349
346
                 */
350
 
                if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
 
347
                if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
351
348
                        ASSERT((char *)dup - (char *)d ==
352
 
                               INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT));
 
349
                               be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
353
350
                        xfs_dir2_data_freeinsert(d, dup, loghead);
354
 
                        p += INT_GET(dup->length, ARCH_CONVERT);
 
351
                        p += be16_to_cpu(dup->length);
355
352
                }
356
353
                /*
357
354
                 * For active entries, check their tags and skip them.
359
356
                else {
360
357
                        dep = (xfs_dir2_data_entry_t *)p;
361
358
                        ASSERT((char *)dep - (char *)d ==
362
 
                               INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT));
363
 
                        p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
 
359
                               be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)));
 
360
                        p += xfs_dir2_data_entsize(dep->namelen);
364
361
                }
365
362
        }
366
363
}
391
388
        /*
392
389
         * Get the buffer set up for the block.
393
390
         */
394
 
        error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, blkno), -1, &bp,
 
391
        error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp,
395
392
                XFS_DATA_FORK);
396
393
        if (error) {
397
394
                return error;
401
398
         * Initialize the header.
402
399
         */
403
400
        d = bp->data;
404
 
        INT_SET(d->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC);
405
 
        INT_SET(d->hdr.bestfree[0].offset, ARCH_CONVERT, (xfs_dir2_data_off_t)sizeof(d->hdr));
 
401
        d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
 
402
        d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr));
406
403
        for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
407
404
                d->hdr.bestfree[i].length = 0;
408
405
                d->hdr.bestfree[i].offset = 0;
411
408
         * Set up an unused entry for the block's body.
412
409
         */
413
410
        dup = &d->u[0].unused;
414
 
        INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
 
411
        dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
415
412
 
416
413
        t=mp->m_dirblksize - (uint)sizeof(d->hdr);
417
 
        INT_SET(d->hdr.bestfree[0].length, ARCH_CONVERT, t);
418
 
        INT_SET(dup->length, ARCH_CONVERT, t);
419
 
        INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT,
420
 
                (xfs_dir2_data_off_t)((char *)dup - (char *)d));
 
414
        d->hdr.bestfree[0].length = cpu_to_be16(t);
 
415
        dup->length = cpu_to_be16(t);
 
416
        *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d);
421
417
        /*
422
418
         * Log it and return it.
423
419
         */
439
435
        xfs_dir2_data_t         *d;             /* data block pointer */
440
436
 
441
437
        d = bp->data;
442
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
443
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
438
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
439
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
444
440
        xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d),
445
 
                (uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) -
 
441
                (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) -
446
442
                       (char *)d - 1));
447
443
}
448
444
 
457
453
        xfs_dir2_data_t         *d;             /* data block pointer */
458
454
 
459
455
        d = bp->data;
460
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
461
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
456
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
457
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
462
458
        xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d),
463
459
                (uint)(sizeof(d->hdr) - 1));
464
460
}
475
471
        xfs_dir2_data_t         *d;             /* data block pointer */
476
472
 
477
473
        d = bp->data;
478
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
479
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
 
474
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
475
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
480
476
        /*
481
477
         * Log the first part of the unused entry.
482
478
         */
487
483
         * Log the end (tag) of the unused entry.
488
484
         */
489
485
        xfs_da_log_buf(tp, bp,
490
 
                (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d),
491
 
                (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d +
 
486
                (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d),
 
487
                (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d +
492
488
                       sizeof(xfs_dir2_data_off_t) - 1));
493
489
}
494
490
 
519
515
        /*
520
516
         * Figure out where the end of the data area is.
521
517
         */
522
 
        if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC)
 
518
        if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC)
523
519
                endptr = (char *)d + mp->m_dirblksize;
524
520
        else {
525
521
                xfs_dir2_block_tail_t   *btp;   /* block tail */
526
522
 
527
 
                ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
528
 
                btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
529
 
                endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
 
523
                ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
 
524
                btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d);
 
525
                endptr = (char *)xfs_dir2_block_leaf_p(btp);
530
526
        }
531
527
        /*
532
528
         * If this isn't the start of the block, then back up to
533
529
         * the previous entry and see if it's free.
534
530
         */
535
531
        if (offset > sizeof(d->hdr)) {
536
 
                xfs_dir2_data_off_t     *tagp;  /* tag just before us */
 
532
                __be16                  *tagp;  /* tag just before us */
537
533
 
538
 
                tagp = (xfs_dir2_data_off_t *)((char *)d + offset) - 1;
539
 
                prevdup = (xfs_dir2_data_unused_t *)((char *)d + INT_GET(*tagp, ARCH_CONVERT));
540
 
                if (INT_GET(prevdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
 
534
                tagp = (__be16 *)((char *)d + offset) - 1;
 
535
                prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp));
 
536
                if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
541
537
                        prevdup = NULL;
542
538
        } else
543
539
                prevdup = NULL;
548
544
        if ((char *)d + offset + len < endptr) {
549
545
                postdup =
550
546
                        (xfs_dir2_data_unused_t *)((char *)d + offset + len);
551
 
                if (INT_GET(postdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
 
547
                if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
552
548
                        postdup = NULL;
553
549
        } else
554
550
                postdup = NULL;
572
568
                 * since the third bestfree is there, there might be more
573
569
                 * entries.
574
570
                 */
575
 
                needscan = d->hdr.bestfree[2].length;
 
571
                needscan = (d->hdr.bestfree[2].length != 0);
576
572
                /*
577
573
                 * Fix up the new big freespace.
578
574
                 */
579
 
                INT_MOD(prevdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT));
580
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT,
581
 
                        (xfs_dir2_data_off_t)((char *)prevdup - (char *)d));
 
575
                be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
 
576
                *xfs_dir2_data_unused_tag_p(prevdup) =
 
577
                        cpu_to_be16((char *)prevdup - (char *)d);
582
578
                xfs_dir2_data_log_unused(tp, bp, prevdup);
583
579
                if (!needscan) {
584
580
                        /*
600
596
                         */
601
597
                        dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp);
602
598
                        ASSERT(dfp == &d->hdr.bestfree[0]);
603
 
                        ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(prevdup->length, ARCH_CONVERT));
 
599
                        ASSERT(dfp->length == prevdup->length);
604
600
                        ASSERT(!dfp[1].length);
605
601
                        ASSERT(!dfp[2].length);
606
602
                }
610
606
         */
611
607
        else if (prevdup) {
612
608
                dfp = xfs_dir2_data_freefind(d, prevdup);
613
 
                INT_MOD(prevdup->length, ARCH_CONVERT, len);
614
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT,
615
 
                        (xfs_dir2_data_off_t)((char *)prevdup - (char *)d));
 
609
                be16_add_cpu(&prevdup->length, len);
 
610
                *xfs_dir2_data_unused_tag_p(prevdup) =
 
611
                        cpu_to_be16((char *)prevdup - (char *)d);
616
612
                xfs_dir2_data_log_unused(tp, bp, prevdup);
617
613
                /*
618
614
                 * If the previous entry was in the table, the new entry
626
622
                /*
627
623
                 * Otherwise we need a scan if the new entry is big enough.
628
624
                 */
629
 
                else
630
 
                        needscan = INT_GET(prevdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT);
 
625
                else {
 
626
                        needscan = be16_to_cpu(prevdup->length) >
 
627
                                   be16_to_cpu(d->hdr.bestfree[2].length);
 
628
                }
631
629
        }
632
630
        /*
633
631
         * The following entry is free, merge with it.
635
633
        else if (postdup) {
636
634
                dfp = xfs_dir2_data_freefind(d, postdup);
637
635
                newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
638
 
                INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
639
 
                INT_SET(newdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT));
640
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
641
 
                        (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
 
636
                newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 
637
                newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
 
638
                *xfs_dir2_data_unused_tag_p(newdup) =
 
639
                        cpu_to_be16((char *)newdup - (char *)d);
642
640
                xfs_dir2_data_log_unused(tp, bp, newdup);
643
641
                /*
644
642
                 * If the following entry was in the table, the new entry
652
650
                /*
653
651
                 * Otherwise we need a scan if the new entry is big enough.
654
652
                 */
655
 
                else
656
 
                        needscan = INT_GET(newdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT);
 
653
                else {
 
654
                        needscan = be16_to_cpu(newdup->length) >
 
655
                                   be16_to_cpu(d->hdr.bestfree[2].length);
 
656
                }
657
657
        }
658
658
        /*
659
659
         * Neither neighbor is free.  Make a new entry.
660
660
         */
661
661
        else {
662
662
                newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
663
 
                INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
664
 
                INT_SET(newdup->length, ARCH_CONVERT, len);
665
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
666
 
                        (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
 
663
                newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 
664
                newdup->length = cpu_to_be16(len);
 
665
                *xfs_dir2_data_unused_tag_p(newdup) =
 
666
                        cpu_to_be16((char *)newdup - (char *)d);
667
667
                xfs_dir2_data_log_unused(tp, bp, newdup);
668
668
                (void)xfs_dir2_data_freeinsert(d, newdup, needlogp);
669
669
        }
693
693
        int                     oldlen;         /* old unused entry's length */
694
694
 
695
695
        d = bp->data;
696
 
        ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
697
 
               INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
698
 
        ASSERT(INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG);
 
696
        ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
 
697
               be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
 
698
        ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);
699
699
        ASSERT(offset >= (char *)dup - (char *)d);
700
 
        ASSERT(offset + len <= (char *)dup + INT_GET(dup->length, ARCH_CONVERT) - (char *)d);
701
 
        ASSERT((char *)dup - (char *)d == INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT));
 
700
        ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d);
 
701
        ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
702
702
        /*
703
703
         * Look up the entry in the bestfree table.
704
704
         */
705
705
        dfp = xfs_dir2_data_freefind(d, dup);
706
 
        oldlen = INT_GET(dup->length, ARCH_CONVERT);
707
 
        ASSERT(dfp || oldlen <= INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT));
 
706
        oldlen = be16_to_cpu(dup->length);
 
707
        ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length));
708
708
        /*
709
709
         * Check for alignment with front and back of the entry.
710
710
         */
718
718
         */
719
719
        if (matchfront && matchback) {
720
720
                if (dfp) {
721
 
                        needscan = d->hdr.bestfree[2].offset;
 
721
                        needscan = (d->hdr.bestfree[2].offset != 0);
722
722
                        if (!needscan)
723
723
                                xfs_dir2_data_freeremove(d, dfp, needlogp);
724
724
                }
729
729
         */
730
730
        else if (matchfront) {
731
731
                newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
732
 
                INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
733
 
                INT_SET(newdup->length, ARCH_CONVERT, oldlen - len);
734
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
735
 
                        (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
 
732
                newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 
733
                newdup->length = cpu_to_be16(oldlen - len);
 
734
                *xfs_dir2_data_unused_tag_p(newdup) =
 
735
                        cpu_to_be16((char *)newdup - (char *)d);
736
736
                xfs_dir2_data_log_unused(tp, bp, newdup);
737
737
                /*
738
738
                 * If it was in the table, remove it and add the new one.
741
741
                        xfs_dir2_data_freeremove(d, dfp, needlogp);
742
742
                        dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
743
743
                        ASSERT(dfp != NULL);
744
 
                        ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT));
745
 
                        ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d);
 
744
                        ASSERT(dfp->length == newdup->length);
 
745
                        ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
746
746
                        /*
747
747
                         * If we got inserted at the last slot,
748
748
                         * that means we don't know if there was a better
757
757
         */
758
758
        else if (matchback) {
759
759
                newdup = dup;
760
 
                INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t)
761
 
                        (((char *)d + offset) - (char *)newdup));
762
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
763
 
                        (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
 
760
                newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup);
 
761
                *xfs_dir2_data_unused_tag_p(newdup) =
 
762
                        cpu_to_be16((char *)newdup - (char *)d);
764
763
                xfs_dir2_data_log_unused(tp, bp, newdup);
765
764
                /*
766
765
                 * If it was in the table, remove it and add the new one.
769
768
                        xfs_dir2_data_freeremove(d, dfp, needlogp);
770
769
                        dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
771
770
                        ASSERT(dfp != NULL);
772
 
                        ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT));
773
 
                        ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d);
 
771
                        ASSERT(dfp->length == newdup->length);
 
772
                        ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
774
773
                        /*
775
774
                         * If we got inserted at the last slot,
776
775
                         * that means we don't know if there was a better
785
784
         */
786
785
        else {
787
786
                newdup = dup;
788
 
                INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t)
789
 
                        (((char *)d + offset) - (char *)newdup));
790
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
791
 
                        (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
 
787
                newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup);
 
788
                *xfs_dir2_data_unused_tag_p(newdup) =
 
789
                        cpu_to_be16((char *)newdup - (char *)d);
792
790
                xfs_dir2_data_log_unused(tp, bp, newdup);
793
791
                newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
794
 
                INT_SET(newdup2->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
795
 
                INT_SET(newdup2->length, ARCH_CONVERT, oldlen - len - INT_GET(newdup->length, ARCH_CONVERT));
796
 
                INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup2), ARCH_CONVERT,
797
 
                        (xfs_dir2_data_off_t)((char *)newdup2 - (char *)d));
 
792
                newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 
793
                newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
 
794
                *xfs_dir2_data_unused_tag_p(newdup2) =
 
795
                        cpu_to_be16((char *)newdup2 - (char *)d);
798
796
                xfs_dir2_data_log_unused(tp, bp, newdup2);
799
797
                /*
800
798
                 * If the old entry was in the table, we need to scan
805
803
                 * the 2 new will work.
806
804
                 */
807
805
                if (dfp) {
808
 
                        needscan = d->hdr.bestfree[2].length;
 
806
                        needscan = (d->hdr.bestfree[2].length != 0);
809
807
                        if (!needscan) {
810
808
                                xfs_dir2_data_freeremove(d, dfp, needlogp);
811
809
                                (void)xfs_dir2_data_freeinsert(d, newdup,