53
47
xfs_mount_t *mp; /* filesystem mount point */
54
48
char *p; /* current data position */
55
49
int stale; /* count of stale leaves */
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;
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;
68
63
endp = (char *)d + mp->m_dirblksize;
82
77
ASSERT(!bf[2].offset);
83
78
freeseen |= 1 << 2;
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));
88
83
* Loop over the data/unused entries.
94
89
* If we find it, account for that, else make sure it
95
90
* doesn't need to be there.
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);
103
98
i = (int)(dfp - bf);
104
99
ASSERT((freeseen & (1 << i)) == 0);
105
100
freeseen |= 1 << i;
107
ASSERT(INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(bf[2].length, ARCH_CONVERT));
108
p += INT_GET(dup->length, ARCH_CONVERT);
102
ASSERT(be16_to_cpu(dup->length) <=
103
be16_to_cpu(bf[2].length));
105
p += be16_to_cpu(dup->length);
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);
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)
135
ASSERT(i < INT_GET(btp->count, ARCH_CONVERT));
134
ASSERT(i < be32_to_cpu(btp->count));
137
p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
136
p += xfs_dir2_data_entsize(dep->namelen);
140
139
* Need to have seen all the entries and all the bestfree slots.
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)
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));
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));
176
175
* Check order, non-overlapping entries, and if we find the
177
176
* one we're looking for it has to be exact.
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];
189
188
ASSERT(seenzero == 0);
190
if (INT_GET(dfp->offset, ARCH_CONVERT) == off) {
189
if (be16_to_cpu(dfp->offset) == off) {
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));
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));
203
202
* If this is smaller than the smallest bestfree entry,
204
203
* it can't be there since they're sorted.
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))
209
209
* Look at the three bestfree entries for our guy.
235
235
xfs_dir2_data_free_t new; /* new bestfree entry */
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);
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);
245
245
* Insert at position 0, 1, or 2; or not at all.
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)) {
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)) {
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)) {
269
269
* Remove a bestfree entry from the table.
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 */
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);
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 */
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 */
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);
327
326
* Start by clearing the table.
332
331
* Set up pointers.
334
333
p = (char *)d->u;
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);
341
338
endp = (char *)d + mp->m_dirblksize;
348
345
* If it's a free entry, insert it.
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);
357
354
* For active entries, check their tags and skip them.
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);
392
389
* Get the buffer set up for the block.
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,
401
398
* Initialize the header.
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.
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);
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);
422
418
* Log it and return it.
439
435
xfs_dir2_data_t *d; /* data block pointer */
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) -
457
453
xfs_dir2_data_t *d; /* data block pointer */
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));
475
471
xfs_dir2_data_t *d; /* data block pointer */
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);
481
477
* Log the first part of the unused entry.
487
483
* Log the end (tag) of the unused entry.
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));
520
516
* Figure out where the end of the data area is.
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;
525
521
xfs_dir2_block_tail_t *btp; /* block tail */
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);
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.
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 */
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)
572
568
* since the third bestfree is there, there might be more
575
needscan = d->hdr.bestfree[2].length;
571
needscan = (d->hdr.bestfree[2].length != 0);
577
573
* Fix up the new big freespace.
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);
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);
618
614
* If the previous entry was in the table, the new entry
627
623
* Otherwise we need a scan if the new entry is big enough.
630
needscan = INT_GET(prevdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT);
626
needscan = be16_to_cpu(prevdup->length) >
627
be16_to_cpu(d->hdr.bestfree[2].length);
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);
644
642
* If the following entry was in the table, the new entry
653
651
* Otherwise we need a scan if the new entry is big enough.
656
needscan = INT_GET(newdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT);
654
needscan = be16_to_cpu(newdup->length) >
655
be16_to_cpu(d->hdr.bestfree[2].length);
659
659
* Neither neighbor is free. Make a new entry.
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);
693
693
int oldlen; /* old unused entry's length */
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)));
703
703
* Look up the entry in the bestfree table.
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));
709
709
* Check for alignment with front and back of the entry.
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);
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);
747
747
* If we got inserted at the last slot,
748
748
* that means we don't know if there was a better
758
758
else if (matchback) {
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);
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);
775
774
* If we got inserted at the last slot,
776
775
* that means we don't know if there was a better
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);
800
798
* If the old entry was in the table, we need to scan