1*30f712c9SDave Chinner /* 2*30f712c9SDave Chinner * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 3*30f712c9SDave Chinner * Copyright (c) 2013 Red Hat, Inc. 4*30f712c9SDave Chinner * All Rights Reserved. 5*30f712c9SDave Chinner * 6*30f712c9SDave Chinner * This program is free software; you can redistribute it and/or 7*30f712c9SDave Chinner * modify it under the terms of the GNU General Public License as 8*30f712c9SDave Chinner * published by the Free Software Foundation. 9*30f712c9SDave Chinner * 10*30f712c9SDave Chinner * This program is distributed in the hope that it would be useful, 11*30f712c9SDave Chinner * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*30f712c9SDave Chinner * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*30f712c9SDave Chinner * GNU General Public License for more details. 14*30f712c9SDave Chinner * 15*30f712c9SDave Chinner * You should have received a copy of the GNU General Public License 16*30f712c9SDave Chinner * along with this program; if not, write the Free Software Foundation, 17*30f712c9SDave Chinner * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18*30f712c9SDave Chinner */ 19*30f712c9SDave Chinner #include "xfs.h" 20*30f712c9SDave Chinner #include "xfs_fs.h" 21*30f712c9SDave Chinner #include "xfs_format.h" 22*30f712c9SDave Chinner #include "xfs_log_format.h" 23*30f712c9SDave Chinner #include "xfs_trans_resv.h" 24*30f712c9SDave Chinner #include "xfs_sb.h" 25*30f712c9SDave Chinner #include "xfs_ag.h" 26*30f712c9SDave Chinner #include "xfs_mount.h" 27*30f712c9SDave Chinner #include "xfs_da_format.h" 28*30f712c9SDave Chinner #include "xfs_da_btree.h" 29*30f712c9SDave Chinner #include "xfs_inode.h" 30*30f712c9SDave Chinner #include "xfs_dir2.h" 31*30f712c9SDave Chinner #include "xfs_dir2_priv.h" 32*30f712c9SDave Chinner #include "xfs_error.h" 33*30f712c9SDave Chinner #include "xfs_trans.h" 34*30f712c9SDave Chinner #include "xfs_buf_item.h" 35*30f712c9SDave Chinner #include "xfs_cksum.h" 36*30f712c9SDave Chinner 37*30f712c9SDave Chinner /* 38*30f712c9SDave Chinner * Check the consistency of the data block. 39*30f712c9SDave Chinner * The input can also be a block-format directory. 40*30f712c9SDave Chinner * Return 0 is the buffer is good, otherwise an error. 41*30f712c9SDave Chinner */ 42*30f712c9SDave Chinner int 43*30f712c9SDave Chinner __xfs_dir3_data_check( 44*30f712c9SDave Chinner struct xfs_inode *dp, /* incore inode pointer */ 45*30f712c9SDave Chinner struct xfs_buf *bp) /* data block's buffer */ 46*30f712c9SDave Chinner { 47*30f712c9SDave Chinner xfs_dir2_dataptr_t addr; /* addr for leaf lookup */ 48*30f712c9SDave Chinner xfs_dir2_data_free_t *bf; /* bestfree table */ 49*30f712c9SDave Chinner xfs_dir2_block_tail_t *btp=NULL; /* block tail */ 50*30f712c9SDave Chinner int count; /* count of entries found */ 51*30f712c9SDave Chinner xfs_dir2_data_hdr_t *hdr; /* data block header */ 52*30f712c9SDave Chinner xfs_dir2_data_entry_t *dep; /* data entry */ 53*30f712c9SDave Chinner xfs_dir2_data_free_t *dfp; /* bestfree entry */ 54*30f712c9SDave Chinner xfs_dir2_data_unused_t *dup; /* unused entry */ 55*30f712c9SDave Chinner char *endp; /* end of useful data */ 56*30f712c9SDave Chinner int freeseen; /* mask of bestfrees seen */ 57*30f712c9SDave Chinner xfs_dahash_t hash; /* hash of current name */ 58*30f712c9SDave Chinner int i; /* leaf index */ 59*30f712c9SDave Chinner int lastfree; /* last entry was unused */ 60*30f712c9SDave Chinner xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */ 61*30f712c9SDave Chinner xfs_mount_t *mp; /* filesystem mount point */ 62*30f712c9SDave Chinner char *p; /* current data position */ 63*30f712c9SDave Chinner int stale; /* count of stale leaves */ 64*30f712c9SDave Chinner struct xfs_name name; 65*30f712c9SDave Chinner const struct xfs_dir_ops *ops; 66*30f712c9SDave Chinner struct xfs_da_geometry *geo; 67*30f712c9SDave Chinner 68*30f712c9SDave Chinner mp = bp->b_target->bt_mount; 69*30f712c9SDave Chinner geo = mp->m_dir_geo; 70*30f712c9SDave Chinner 71*30f712c9SDave Chinner /* 72*30f712c9SDave Chinner * We can be passed a null dp here from a verifier, so we need to go the 73*30f712c9SDave Chinner * hard way to get them. 74*30f712c9SDave Chinner */ 75*30f712c9SDave Chinner ops = xfs_dir_get_ops(mp, dp); 76*30f712c9SDave Chinner 77*30f712c9SDave Chinner hdr = bp->b_addr; 78*30f712c9SDave Chinner p = (char *)ops->data_entry_p(hdr); 79*30f712c9SDave Chinner 80*30f712c9SDave Chinner switch (hdr->magic) { 81*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): 82*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): 83*30f712c9SDave Chinner btp = xfs_dir2_block_tail_p(geo, hdr); 84*30f712c9SDave Chinner lep = xfs_dir2_block_leaf_p(btp); 85*30f712c9SDave Chinner endp = (char *)lep; 86*30f712c9SDave Chinner 87*30f712c9SDave Chinner /* 88*30f712c9SDave Chinner * The number of leaf entries is limited by the size of the 89*30f712c9SDave Chinner * block and the amount of space used by the data entries. 90*30f712c9SDave Chinner * We don't know how much space is used by the data entries yet, 91*30f712c9SDave Chinner * so just ensure that the count falls somewhere inside the 92*30f712c9SDave Chinner * block right now. 93*30f712c9SDave Chinner */ 94*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(be32_to_cpu(btp->count) < 95*30f712c9SDave Chinner ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry)); 96*30f712c9SDave Chinner break; 97*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR3_DATA_MAGIC): 98*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 99*30f712c9SDave Chinner endp = (char *)hdr + geo->blksize; 100*30f712c9SDave Chinner break; 101*30f712c9SDave Chinner default: 102*30f712c9SDave Chinner XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp); 103*30f712c9SDave Chinner return EFSCORRUPTED; 104*30f712c9SDave Chinner } 105*30f712c9SDave Chinner 106*30f712c9SDave Chinner /* 107*30f712c9SDave Chinner * Account for zero bestfree entries. 108*30f712c9SDave Chinner */ 109*30f712c9SDave Chinner bf = ops->data_bestfree_p(hdr); 110*30f712c9SDave Chinner count = lastfree = freeseen = 0; 111*30f712c9SDave Chinner if (!bf[0].length) { 112*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(!bf[0].offset); 113*30f712c9SDave Chinner freeseen |= 1 << 0; 114*30f712c9SDave Chinner } 115*30f712c9SDave Chinner if (!bf[1].length) { 116*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(!bf[1].offset); 117*30f712c9SDave Chinner freeseen |= 1 << 1; 118*30f712c9SDave Chinner } 119*30f712c9SDave Chinner if (!bf[2].length) { 120*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(!bf[2].offset); 121*30f712c9SDave Chinner freeseen |= 1 << 2; 122*30f712c9SDave Chinner } 123*30f712c9SDave Chinner 124*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[0].length) >= 125*30f712c9SDave Chinner be16_to_cpu(bf[1].length)); 126*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[1].length) >= 127*30f712c9SDave Chinner be16_to_cpu(bf[2].length)); 128*30f712c9SDave Chinner /* 129*30f712c9SDave Chinner * Loop over the data/unused entries. 130*30f712c9SDave Chinner */ 131*30f712c9SDave Chinner while (p < endp) { 132*30f712c9SDave Chinner dup = (xfs_dir2_data_unused_t *)p; 133*30f712c9SDave Chinner /* 134*30f712c9SDave Chinner * If it's unused, look for the space in the bestfree table. 135*30f712c9SDave Chinner * If we find it, account for that, else make sure it 136*30f712c9SDave Chinner * doesn't need to be there. 137*30f712c9SDave Chinner */ 138*30f712c9SDave Chinner if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 139*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(lastfree == 0); 140*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 141*30f712c9SDave Chinner be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == 142*30f712c9SDave Chinner (char *)dup - (char *)hdr); 143*30f712c9SDave Chinner dfp = xfs_dir2_data_freefind(hdr, bf, dup); 144*30f712c9SDave Chinner if (dfp) { 145*30f712c9SDave Chinner i = (int)(dfp - bf); 146*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 147*30f712c9SDave Chinner (freeseen & (1 << i)) == 0); 148*30f712c9SDave Chinner freeseen |= 1 << i; 149*30f712c9SDave Chinner } else { 150*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 151*30f712c9SDave Chinner be16_to_cpu(dup->length) <= 152*30f712c9SDave Chinner be16_to_cpu(bf[2].length)); 153*30f712c9SDave Chinner } 154*30f712c9SDave Chinner p += be16_to_cpu(dup->length); 155*30f712c9SDave Chinner lastfree = 1; 156*30f712c9SDave Chinner continue; 157*30f712c9SDave Chinner } 158*30f712c9SDave Chinner /* 159*30f712c9SDave Chinner * It's a real entry. Validate the fields. 160*30f712c9SDave Chinner * If this is a block directory then make sure it's 161*30f712c9SDave Chinner * in the leaf section of the block. 162*30f712c9SDave Chinner * The linear search is crude but this is DEBUG code. 163*30f712c9SDave Chinner */ 164*30f712c9SDave Chinner dep = (xfs_dir2_data_entry_t *)p; 165*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(dep->namelen != 0); 166*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 167*30f712c9SDave Chinner !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))); 168*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 169*30f712c9SDave Chinner be16_to_cpu(*ops->data_entry_tag_p(dep)) == 170*30f712c9SDave Chinner (char *)dep - (char *)hdr); 171*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 172*30f712c9SDave Chinner ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX); 173*30f712c9SDave Chinner count++; 174*30f712c9SDave Chinner lastfree = 0; 175*30f712c9SDave Chinner if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 176*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 177*30f712c9SDave Chinner addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 178*30f712c9SDave Chinner (xfs_dir2_data_aoff_t) 179*30f712c9SDave Chinner ((char *)dep - (char *)hdr)); 180*30f712c9SDave Chinner name.name = dep->name; 181*30f712c9SDave Chinner name.len = dep->namelen; 182*30f712c9SDave Chinner hash = mp->m_dirnameops->hashname(&name); 183*30f712c9SDave Chinner for (i = 0; i < be32_to_cpu(btp->count); i++) { 184*30f712c9SDave Chinner if (be32_to_cpu(lep[i].address) == addr && 185*30f712c9SDave Chinner be32_to_cpu(lep[i].hashval) == hash) 186*30f712c9SDave Chinner break; 187*30f712c9SDave Chinner } 188*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count)); 189*30f712c9SDave Chinner } 190*30f712c9SDave Chinner p += ops->data_entsize(dep->namelen); 191*30f712c9SDave Chinner } 192*30f712c9SDave Chinner /* 193*30f712c9SDave Chinner * Need to have seen all the entries and all the bestfree slots. 194*30f712c9SDave Chinner */ 195*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(freeseen == 7); 196*30f712c9SDave Chinner if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 197*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 198*30f712c9SDave Chinner for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { 199*30f712c9SDave Chinner if (lep[i].address == 200*30f712c9SDave Chinner cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 201*30f712c9SDave Chinner stale++; 202*30f712c9SDave Chinner if (i > 0) 203*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN( 204*30f712c9SDave Chinner be32_to_cpu(lep[i].hashval) >= 205*30f712c9SDave Chinner be32_to_cpu(lep[i - 1].hashval)); 206*30f712c9SDave Chinner } 207*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(count == 208*30f712c9SDave Chinner be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); 209*30f712c9SDave Chinner XFS_WANT_CORRUPTED_RETURN(stale == be32_to_cpu(btp->stale)); 210*30f712c9SDave Chinner } 211*30f712c9SDave Chinner return 0; 212*30f712c9SDave Chinner } 213*30f712c9SDave Chinner 214*30f712c9SDave Chinner static bool 215*30f712c9SDave Chinner xfs_dir3_data_verify( 216*30f712c9SDave Chinner struct xfs_buf *bp) 217*30f712c9SDave Chinner { 218*30f712c9SDave Chinner struct xfs_mount *mp = bp->b_target->bt_mount; 219*30f712c9SDave Chinner struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 220*30f712c9SDave Chinner 221*30f712c9SDave Chinner if (xfs_sb_version_hascrc(&mp->m_sb)) { 222*30f712c9SDave Chinner if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC)) 223*30f712c9SDave Chinner return false; 224*30f712c9SDave Chinner if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) 225*30f712c9SDave Chinner return false; 226*30f712c9SDave Chinner if (be64_to_cpu(hdr3->blkno) != bp->b_bn) 227*30f712c9SDave Chinner return false; 228*30f712c9SDave Chinner } else { 229*30f712c9SDave Chinner if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC)) 230*30f712c9SDave Chinner return false; 231*30f712c9SDave Chinner } 232*30f712c9SDave Chinner if (__xfs_dir3_data_check(NULL, bp)) 233*30f712c9SDave Chinner return false; 234*30f712c9SDave Chinner return true; 235*30f712c9SDave Chinner } 236*30f712c9SDave Chinner 237*30f712c9SDave Chinner /* 238*30f712c9SDave Chinner * Readahead of the first block of the directory when it is opened is completely 239*30f712c9SDave Chinner * oblivious to the format of the directory. Hence we can either get a block 240*30f712c9SDave Chinner * format buffer or a data format buffer on readahead. 241*30f712c9SDave Chinner */ 242*30f712c9SDave Chinner static void 243*30f712c9SDave Chinner xfs_dir3_data_reada_verify( 244*30f712c9SDave Chinner struct xfs_buf *bp) 245*30f712c9SDave Chinner { 246*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr = bp->b_addr; 247*30f712c9SDave Chinner 248*30f712c9SDave Chinner switch (hdr->magic) { 249*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): 250*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): 251*30f712c9SDave Chinner bp->b_ops = &xfs_dir3_block_buf_ops; 252*30f712c9SDave Chinner bp->b_ops->verify_read(bp); 253*30f712c9SDave Chinner return; 254*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 255*30f712c9SDave Chinner case cpu_to_be32(XFS_DIR3_DATA_MAGIC): 256*30f712c9SDave Chinner xfs_dir3_data_verify(bp); 257*30f712c9SDave Chinner return; 258*30f712c9SDave Chinner default: 259*30f712c9SDave Chinner xfs_buf_ioerror(bp, EFSCORRUPTED); 260*30f712c9SDave Chinner xfs_verifier_error(bp); 261*30f712c9SDave Chinner break; 262*30f712c9SDave Chinner } 263*30f712c9SDave Chinner } 264*30f712c9SDave Chinner 265*30f712c9SDave Chinner static void 266*30f712c9SDave Chinner xfs_dir3_data_read_verify( 267*30f712c9SDave Chinner struct xfs_buf *bp) 268*30f712c9SDave Chinner { 269*30f712c9SDave Chinner struct xfs_mount *mp = bp->b_target->bt_mount; 270*30f712c9SDave Chinner 271*30f712c9SDave Chinner if (xfs_sb_version_hascrc(&mp->m_sb) && 272*30f712c9SDave Chinner !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF)) 273*30f712c9SDave Chinner xfs_buf_ioerror(bp, EFSBADCRC); 274*30f712c9SDave Chinner else if (!xfs_dir3_data_verify(bp)) 275*30f712c9SDave Chinner xfs_buf_ioerror(bp, EFSCORRUPTED); 276*30f712c9SDave Chinner 277*30f712c9SDave Chinner if (bp->b_error) 278*30f712c9SDave Chinner xfs_verifier_error(bp); 279*30f712c9SDave Chinner } 280*30f712c9SDave Chinner 281*30f712c9SDave Chinner static void 282*30f712c9SDave Chinner xfs_dir3_data_write_verify( 283*30f712c9SDave Chinner struct xfs_buf *bp) 284*30f712c9SDave Chinner { 285*30f712c9SDave Chinner struct xfs_mount *mp = bp->b_target->bt_mount; 286*30f712c9SDave Chinner struct xfs_buf_log_item *bip = bp->b_fspriv; 287*30f712c9SDave Chinner struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 288*30f712c9SDave Chinner 289*30f712c9SDave Chinner if (!xfs_dir3_data_verify(bp)) { 290*30f712c9SDave Chinner xfs_buf_ioerror(bp, EFSCORRUPTED); 291*30f712c9SDave Chinner xfs_verifier_error(bp); 292*30f712c9SDave Chinner return; 293*30f712c9SDave Chinner } 294*30f712c9SDave Chinner 295*30f712c9SDave Chinner if (!xfs_sb_version_hascrc(&mp->m_sb)) 296*30f712c9SDave Chinner return; 297*30f712c9SDave Chinner 298*30f712c9SDave Chinner if (bip) 299*30f712c9SDave Chinner hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn); 300*30f712c9SDave Chinner 301*30f712c9SDave Chinner xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF); 302*30f712c9SDave Chinner } 303*30f712c9SDave Chinner 304*30f712c9SDave Chinner const struct xfs_buf_ops xfs_dir3_data_buf_ops = { 305*30f712c9SDave Chinner .verify_read = xfs_dir3_data_read_verify, 306*30f712c9SDave Chinner .verify_write = xfs_dir3_data_write_verify, 307*30f712c9SDave Chinner }; 308*30f712c9SDave Chinner 309*30f712c9SDave Chinner static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { 310*30f712c9SDave Chinner .verify_read = xfs_dir3_data_reada_verify, 311*30f712c9SDave Chinner .verify_write = xfs_dir3_data_write_verify, 312*30f712c9SDave Chinner }; 313*30f712c9SDave Chinner 314*30f712c9SDave Chinner 315*30f712c9SDave Chinner int 316*30f712c9SDave Chinner xfs_dir3_data_read( 317*30f712c9SDave Chinner struct xfs_trans *tp, 318*30f712c9SDave Chinner struct xfs_inode *dp, 319*30f712c9SDave Chinner xfs_dablk_t bno, 320*30f712c9SDave Chinner xfs_daddr_t mapped_bno, 321*30f712c9SDave Chinner struct xfs_buf **bpp) 322*30f712c9SDave Chinner { 323*30f712c9SDave Chinner int err; 324*30f712c9SDave Chinner 325*30f712c9SDave Chinner err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, 326*30f712c9SDave Chinner XFS_DATA_FORK, &xfs_dir3_data_buf_ops); 327*30f712c9SDave Chinner if (!err && tp) 328*30f712c9SDave Chinner xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF); 329*30f712c9SDave Chinner return err; 330*30f712c9SDave Chinner } 331*30f712c9SDave Chinner 332*30f712c9SDave Chinner int 333*30f712c9SDave Chinner xfs_dir3_data_readahead( 334*30f712c9SDave Chinner struct xfs_inode *dp, 335*30f712c9SDave Chinner xfs_dablk_t bno, 336*30f712c9SDave Chinner xfs_daddr_t mapped_bno) 337*30f712c9SDave Chinner { 338*30f712c9SDave Chinner return xfs_da_reada_buf(dp, bno, mapped_bno, 339*30f712c9SDave Chinner XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops); 340*30f712c9SDave Chinner } 341*30f712c9SDave Chinner 342*30f712c9SDave Chinner /* 343*30f712c9SDave Chinner * Given a data block and an unused entry from that block, 344*30f712c9SDave Chinner * return the bestfree entry if any that corresponds to it. 345*30f712c9SDave Chinner */ 346*30f712c9SDave Chinner xfs_dir2_data_free_t * 347*30f712c9SDave Chinner xfs_dir2_data_freefind( 348*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr, /* data block header */ 349*30f712c9SDave Chinner struct xfs_dir2_data_free *bf, /* bestfree table pointer */ 350*30f712c9SDave Chinner struct xfs_dir2_data_unused *dup) /* unused space */ 351*30f712c9SDave Chinner { 352*30f712c9SDave Chinner xfs_dir2_data_free_t *dfp; /* bestfree entry */ 353*30f712c9SDave Chinner xfs_dir2_data_aoff_t off; /* offset value needed */ 354*30f712c9SDave Chinner #ifdef DEBUG 355*30f712c9SDave Chinner int matched; /* matched the value */ 356*30f712c9SDave Chinner int seenzero; /* saw a 0 bestfree entry */ 357*30f712c9SDave Chinner #endif 358*30f712c9SDave Chinner 359*30f712c9SDave Chinner off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr); 360*30f712c9SDave Chinner 361*30f712c9SDave Chinner #ifdef DEBUG 362*30f712c9SDave Chinner /* 363*30f712c9SDave Chinner * Validate some consistency in the bestfree table. 364*30f712c9SDave Chinner * Check order, non-overlapping entries, and if we find the 365*30f712c9SDave Chinner * one we're looking for it has to be exact. 366*30f712c9SDave Chinner */ 367*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 368*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 369*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 370*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 371*30f712c9SDave Chinner for (dfp = &bf[0], seenzero = matched = 0; 372*30f712c9SDave Chinner dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; 373*30f712c9SDave Chinner dfp++) { 374*30f712c9SDave Chinner if (!dfp->offset) { 375*30f712c9SDave Chinner ASSERT(!dfp->length); 376*30f712c9SDave Chinner seenzero = 1; 377*30f712c9SDave Chinner continue; 378*30f712c9SDave Chinner } 379*30f712c9SDave Chinner ASSERT(seenzero == 0); 380*30f712c9SDave Chinner if (be16_to_cpu(dfp->offset) == off) { 381*30f712c9SDave Chinner matched = 1; 382*30f712c9SDave Chinner ASSERT(dfp->length == dup->length); 383*30f712c9SDave Chinner } else if (off < be16_to_cpu(dfp->offset)) 384*30f712c9SDave Chinner ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset)); 385*30f712c9SDave Chinner else 386*30f712c9SDave Chinner ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); 387*30f712c9SDave Chinner ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); 388*30f712c9SDave Chinner if (dfp > &bf[0]) 389*30f712c9SDave Chinner ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); 390*30f712c9SDave Chinner } 391*30f712c9SDave Chinner #endif 392*30f712c9SDave Chinner /* 393*30f712c9SDave Chinner * If this is smaller than the smallest bestfree entry, 394*30f712c9SDave Chinner * it can't be there since they're sorted. 395*30f712c9SDave Chinner */ 396*30f712c9SDave Chinner if (be16_to_cpu(dup->length) < 397*30f712c9SDave Chinner be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length)) 398*30f712c9SDave Chinner return NULL; 399*30f712c9SDave Chinner /* 400*30f712c9SDave Chinner * Look at the three bestfree entries for our guy. 401*30f712c9SDave Chinner */ 402*30f712c9SDave Chinner for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { 403*30f712c9SDave Chinner if (!dfp->offset) 404*30f712c9SDave Chinner return NULL; 405*30f712c9SDave Chinner if (be16_to_cpu(dfp->offset) == off) 406*30f712c9SDave Chinner return dfp; 407*30f712c9SDave Chinner } 408*30f712c9SDave Chinner /* 409*30f712c9SDave Chinner * Didn't find it. This only happens if there are duplicate lengths. 410*30f712c9SDave Chinner */ 411*30f712c9SDave Chinner return NULL; 412*30f712c9SDave Chinner } 413*30f712c9SDave Chinner 414*30f712c9SDave Chinner /* 415*30f712c9SDave Chinner * Insert an unused-space entry into the bestfree table. 416*30f712c9SDave Chinner */ 417*30f712c9SDave Chinner xfs_dir2_data_free_t * /* entry inserted */ 418*30f712c9SDave Chinner xfs_dir2_data_freeinsert( 419*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr, /* data block pointer */ 420*30f712c9SDave Chinner struct xfs_dir2_data_free *dfp, /* bestfree table pointer */ 421*30f712c9SDave Chinner struct xfs_dir2_data_unused *dup, /* unused space */ 422*30f712c9SDave Chinner int *loghead) /* log the data header (out) */ 423*30f712c9SDave Chinner { 424*30f712c9SDave Chinner xfs_dir2_data_free_t new; /* new bestfree entry */ 425*30f712c9SDave Chinner 426*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 427*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 428*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 429*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 430*30f712c9SDave Chinner 431*30f712c9SDave Chinner new.length = dup->length; 432*30f712c9SDave Chinner new.offset = cpu_to_be16((char *)dup - (char *)hdr); 433*30f712c9SDave Chinner 434*30f712c9SDave Chinner /* 435*30f712c9SDave Chinner * Insert at position 0, 1, or 2; or not at all. 436*30f712c9SDave Chinner */ 437*30f712c9SDave Chinner if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) { 438*30f712c9SDave Chinner dfp[2] = dfp[1]; 439*30f712c9SDave Chinner dfp[1] = dfp[0]; 440*30f712c9SDave Chinner dfp[0] = new; 441*30f712c9SDave Chinner *loghead = 1; 442*30f712c9SDave Chinner return &dfp[0]; 443*30f712c9SDave Chinner } 444*30f712c9SDave Chinner if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) { 445*30f712c9SDave Chinner dfp[2] = dfp[1]; 446*30f712c9SDave Chinner dfp[1] = new; 447*30f712c9SDave Chinner *loghead = 1; 448*30f712c9SDave Chinner return &dfp[1]; 449*30f712c9SDave Chinner } 450*30f712c9SDave Chinner if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) { 451*30f712c9SDave Chinner dfp[2] = new; 452*30f712c9SDave Chinner *loghead = 1; 453*30f712c9SDave Chinner return &dfp[2]; 454*30f712c9SDave Chinner } 455*30f712c9SDave Chinner return NULL; 456*30f712c9SDave Chinner } 457*30f712c9SDave Chinner 458*30f712c9SDave Chinner /* 459*30f712c9SDave Chinner * Remove a bestfree entry from the table. 460*30f712c9SDave Chinner */ 461*30f712c9SDave Chinner STATIC void 462*30f712c9SDave Chinner xfs_dir2_data_freeremove( 463*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr, /* data block header */ 464*30f712c9SDave Chinner struct xfs_dir2_data_free *bf, /* bestfree table pointer */ 465*30f712c9SDave Chinner struct xfs_dir2_data_free *dfp, /* bestfree entry pointer */ 466*30f712c9SDave Chinner int *loghead) /* out: log data header */ 467*30f712c9SDave Chinner { 468*30f712c9SDave Chinner 469*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 470*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 471*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 472*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 473*30f712c9SDave Chinner 474*30f712c9SDave Chinner /* 475*30f712c9SDave Chinner * It's the first entry, slide the next 2 up. 476*30f712c9SDave Chinner */ 477*30f712c9SDave Chinner if (dfp == &bf[0]) { 478*30f712c9SDave Chinner bf[0] = bf[1]; 479*30f712c9SDave Chinner bf[1] = bf[2]; 480*30f712c9SDave Chinner } 481*30f712c9SDave Chinner /* 482*30f712c9SDave Chinner * It's the second entry, slide the 3rd entry up. 483*30f712c9SDave Chinner */ 484*30f712c9SDave Chinner else if (dfp == &bf[1]) 485*30f712c9SDave Chinner bf[1] = bf[2]; 486*30f712c9SDave Chinner /* 487*30f712c9SDave Chinner * Must be the last entry. 488*30f712c9SDave Chinner */ 489*30f712c9SDave Chinner else 490*30f712c9SDave Chinner ASSERT(dfp == &bf[2]); 491*30f712c9SDave Chinner /* 492*30f712c9SDave Chinner * Clear the 3rd entry, must be zero now. 493*30f712c9SDave Chinner */ 494*30f712c9SDave Chinner bf[2].length = 0; 495*30f712c9SDave Chinner bf[2].offset = 0; 496*30f712c9SDave Chinner *loghead = 1; 497*30f712c9SDave Chinner } 498*30f712c9SDave Chinner 499*30f712c9SDave Chinner /* 500*30f712c9SDave Chinner * Given a data block, reconstruct its bestfree map. 501*30f712c9SDave Chinner */ 502*30f712c9SDave Chinner void 503*30f712c9SDave Chinner xfs_dir2_data_freescan( 504*30f712c9SDave Chinner struct xfs_inode *dp, 505*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr, 506*30f712c9SDave Chinner int *loghead) 507*30f712c9SDave Chinner { 508*30f712c9SDave Chinner xfs_dir2_block_tail_t *btp; /* block tail */ 509*30f712c9SDave Chinner xfs_dir2_data_entry_t *dep; /* active data entry */ 510*30f712c9SDave Chinner xfs_dir2_data_unused_t *dup; /* unused data entry */ 511*30f712c9SDave Chinner struct xfs_dir2_data_free *bf; 512*30f712c9SDave Chinner char *endp; /* end of block's data */ 513*30f712c9SDave Chinner char *p; /* current entry pointer */ 514*30f712c9SDave Chinner struct xfs_da_geometry *geo = dp->i_mount->m_dir_geo; 515*30f712c9SDave Chinner 516*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 517*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 518*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 519*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 520*30f712c9SDave Chinner 521*30f712c9SDave Chinner /* 522*30f712c9SDave Chinner * Start by clearing the table. 523*30f712c9SDave Chinner */ 524*30f712c9SDave Chinner bf = dp->d_ops->data_bestfree_p(hdr); 525*30f712c9SDave Chinner memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT); 526*30f712c9SDave Chinner *loghead = 1; 527*30f712c9SDave Chinner /* 528*30f712c9SDave Chinner * Set up pointers. 529*30f712c9SDave Chinner */ 530*30f712c9SDave Chinner p = (char *)dp->d_ops->data_entry_p(hdr); 531*30f712c9SDave Chinner if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 532*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 533*30f712c9SDave Chinner btp = xfs_dir2_block_tail_p(geo, hdr); 534*30f712c9SDave Chinner endp = (char *)xfs_dir2_block_leaf_p(btp); 535*30f712c9SDave Chinner } else 536*30f712c9SDave Chinner endp = (char *)hdr + geo->blksize; 537*30f712c9SDave Chinner /* 538*30f712c9SDave Chinner * Loop over the block's entries. 539*30f712c9SDave Chinner */ 540*30f712c9SDave Chinner while (p < endp) { 541*30f712c9SDave Chinner dup = (xfs_dir2_data_unused_t *)p; 542*30f712c9SDave Chinner /* 543*30f712c9SDave Chinner * If it's a free entry, insert it. 544*30f712c9SDave Chinner */ 545*30f712c9SDave Chinner if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 546*30f712c9SDave Chinner ASSERT((char *)dup - (char *)hdr == 547*30f712c9SDave Chinner be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); 548*30f712c9SDave Chinner xfs_dir2_data_freeinsert(hdr, bf, dup, loghead); 549*30f712c9SDave Chinner p += be16_to_cpu(dup->length); 550*30f712c9SDave Chinner } 551*30f712c9SDave Chinner /* 552*30f712c9SDave Chinner * For active entries, check their tags and skip them. 553*30f712c9SDave Chinner */ 554*30f712c9SDave Chinner else { 555*30f712c9SDave Chinner dep = (xfs_dir2_data_entry_t *)p; 556*30f712c9SDave Chinner ASSERT((char *)dep - (char *)hdr == 557*30f712c9SDave Chinner be16_to_cpu(*dp->d_ops->data_entry_tag_p(dep))); 558*30f712c9SDave Chinner p += dp->d_ops->data_entsize(dep->namelen); 559*30f712c9SDave Chinner } 560*30f712c9SDave Chinner } 561*30f712c9SDave Chinner } 562*30f712c9SDave Chinner 563*30f712c9SDave Chinner /* 564*30f712c9SDave Chinner * Initialize a data block at the given block number in the directory. 565*30f712c9SDave Chinner * Give back the buffer for the created block. 566*30f712c9SDave Chinner */ 567*30f712c9SDave Chinner int /* error */ 568*30f712c9SDave Chinner xfs_dir3_data_init( 569*30f712c9SDave Chinner xfs_da_args_t *args, /* directory operation args */ 570*30f712c9SDave Chinner xfs_dir2_db_t blkno, /* logical dir block number */ 571*30f712c9SDave Chinner struct xfs_buf **bpp) /* output block buffer */ 572*30f712c9SDave Chinner { 573*30f712c9SDave Chinner struct xfs_buf *bp; /* block buffer */ 574*30f712c9SDave Chinner xfs_dir2_data_hdr_t *hdr; /* data block header */ 575*30f712c9SDave Chinner xfs_inode_t *dp; /* incore directory inode */ 576*30f712c9SDave Chinner xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 577*30f712c9SDave Chinner struct xfs_dir2_data_free *bf; 578*30f712c9SDave Chinner int error; /* error return value */ 579*30f712c9SDave Chinner int i; /* bestfree index */ 580*30f712c9SDave Chinner xfs_mount_t *mp; /* filesystem mount point */ 581*30f712c9SDave Chinner xfs_trans_t *tp; /* transaction pointer */ 582*30f712c9SDave Chinner int t; /* temp */ 583*30f712c9SDave Chinner 584*30f712c9SDave Chinner dp = args->dp; 585*30f712c9SDave Chinner mp = dp->i_mount; 586*30f712c9SDave Chinner tp = args->trans; 587*30f712c9SDave Chinner /* 588*30f712c9SDave Chinner * Get the buffer set up for the block. 589*30f712c9SDave Chinner */ 590*30f712c9SDave Chinner error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno), 591*30f712c9SDave Chinner -1, &bp, XFS_DATA_FORK); 592*30f712c9SDave Chinner if (error) 593*30f712c9SDave Chinner return error; 594*30f712c9SDave Chinner bp->b_ops = &xfs_dir3_data_buf_ops; 595*30f712c9SDave Chinner xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF); 596*30f712c9SDave Chinner 597*30f712c9SDave Chinner /* 598*30f712c9SDave Chinner * Initialize the header. 599*30f712c9SDave Chinner */ 600*30f712c9SDave Chinner hdr = bp->b_addr; 601*30f712c9SDave Chinner if (xfs_sb_version_hascrc(&mp->m_sb)) { 602*30f712c9SDave Chinner struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 603*30f712c9SDave Chinner 604*30f712c9SDave Chinner memset(hdr3, 0, sizeof(*hdr3)); 605*30f712c9SDave Chinner hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); 606*30f712c9SDave Chinner hdr3->blkno = cpu_to_be64(bp->b_bn); 607*30f712c9SDave Chinner hdr3->owner = cpu_to_be64(dp->i_ino); 608*30f712c9SDave Chinner uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); 609*30f712c9SDave Chinner 610*30f712c9SDave Chinner } else 611*30f712c9SDave Chinner hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 612*30f712c9SDave Chinner 613*30f712c9SDave Chinner bf = dp->d_ops->data_bestfree_p(hdr); 614*30f712c9SDave Chinner bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset); 615*30f712c9SDave Chinner for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { 616*30f712c9SDave Chinner bf[i].length = 0; 617*30f712c9SDave Chinner bf[i].offset = 0; 618*30f712c9SDave Chinner } 619*30f712c9SDave Chinner 620*30f712c9SDave Chinner /* 621*30f712c9SDave Chinner * Set up an unused entry for the block's body. 622*30f712c9SDave Chinner */ 623*30f712c9SDave Chinner dup = dp->d_ops->data_unused_p(hdr); 624*30f712c9SDave Chinner dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 625*30f712c9SDave Chinner 626*30f712c9SDave Chinner t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset; 627*30f712c9SDave Chinner bf[0].length = cpu_to_be16(t); 628*30f712c9SDave Chinner dup->length = cpu_to_be16(t); 629*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); 630*30f712c9SDave Chinner /* 631*30f712c9SDave Chinner * Log it and return it. 632*30f712c9SDave Chinner */ 633*30f712c9SDave Chinner xfs_dir2_data_log_header(args, bp); 634*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, dup); 635*30f712c9SDave Chinner *bpp = bp; 636*30f712c9SDave Chinner return 0; 637*30f712c9SDave Chinner } 638*30f712c9SDave Chinner 639*30f712c9SDave Chinner /* 640*30f712c9SDave Chinner * Log an active data entry from the block. 641*30f712c9SDave Chinner */ 642*30f712c9SDave Chinner void 643*30f712c9SDave Chinner xfs_dir2_data_log_entry( 644*30f712c9SDave Chinner struct xfs_da_args *args, 645*30f712c9SDave Chinner struct xfs_buf *bp, 646*30f712c9SDave Chinner xfs_dir2_data_entry_t *dep) /* data entry pointer */ 647*30f712c9SDave Chinner { 648*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr = bp->b_addr; 649*30f712c9SDave Chinner 650*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 651*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 652*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 653*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 654*30f712c9SDave Chinner 655*30f712c9SDave Chinner xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr), 656*30f712c9SDave Chinner (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) - 657*30f712c9SDave Chinner (char *)hdr - 1)); 658*30f712c9SDave Chinner } 659*30f712c9SDave Chinner 660*30f712c9SDave Chinner /* 661*30f712c9SDave Chinner * Log a data block header. 662*30f712c9SDave Chinner */ 663*30f712c9SDave Chinner void 664*30f712c9SDave Chinner xfs_dir2_data_log_header( 665*30f712c9SDave Chinner struct xfs_da_args *args, 666*30f712c9SDave Chinner struct xfs_buf *bp) 667*30f712c9SDave Chinner { 668*30f712c9SDave Chinner #ifdef DEBUG 669*30f712c9SDave Chinner struct xfs_dir2_data_hdr *hdr = bp->b_addr; 670*30f712c9SDave Chinner 671*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 672*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 673*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 674*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 675*30f712c9SDave Chinner #endif 676*30f712c9SDave Chinner 677*30f712c9SDave Chinner xfs_trans_log_buf(args->trans, bp, 0, 678*30f712c9SDave Chinner args->dp->d_ops->data_entry_offset - 1); 679*30f712c9SDave Chinner } 680*30f712c9SDave Chinner 681*30f712c9SDave Chinner /* 682*30f712c9SDave Chinner * Log a data unused entry. 683*30f712c9SDave Chinner */ 684*30f712c9SDave Chinner void 685*30f712c9SDave Chinner xfs_dir2_data_log_unused( 686*30f712c9SDave Chinner struct xfs_da_args *args, 687*30f712c9SDave Chinner struct xfs_buf *bp, 688*30f712c9SDave Chinner xfs_dir2_data_unused_t *dup) /* data unused pointer */ 689*30f712c9SDave Chinner { 690*30f712c9SDave Chinner xfs_dir2_data_hdr_t *hdr = bp->b_addr; 691*30f712c9SDave Chinner 692*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 693*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 694*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 695*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 696*30f712c9SDave Chinner 697*30f712c9SDave Chinner /* 698*30f712c9SDave Chinner * Log the first part of the unused entry. 699*30f712c9SDave Chinner */ 700*30f712c9SDave Chinner xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr), 701*30f712c9SDave Chinner (uint)((char *)&dup->length + sizeof(dup->length) - 702*30f712c9SDave Chinner 1 - (char *)hdr)); 703*30f712c9SDave Chinner /* 704*30f712c9SDave Chinner * Log the end (tag) of the unused entry. 705*30f712c9SDave Chinner */ 706*30f712c9SDave Chinner xfs_trans_log_buf(args->trans, bp, 707*30f712c9SDave Chinner (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), 708*30f712c9SDave Chinner (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + 709*30f712c9SDave Chinner sizeof(xfs_dir2_data_off_t) - 1)); 710*30f712c9SDave Chinner } 711*30f712c9SDave Chinner 712*30f712c9SDave Chinner /* 713*30f712c9SDave Chinner * Make a byte range in the data block unused. 714*30f712c9SDave Chinner * Its current contents are unimportant. 715*30f712c9SDave Chinner */ 716*30f712c9SDave Chinner void 717*30f712c9SDave Chinner xfs_dir2_data_make_free( 718*30f712c9SDave Chinner struct xfs_da_args *args, 719*30f712c9SDave Chinner struct xfs_buf *bp, 720*30f712c9SDave Chinner xfs_dir2_data_aoff_t offset, /* starting byte offset */ 721*30f712c9SDave Chinner xfs_dir2_data_aoff_t len, /* length in bytes */ 722*30f712c9SDave Chinner int *needlogp, /* out: log header */ 723*30f712c9SDave Chinner int *needscanp) /* out: regen bestfree */ 724*30f712c9SDave Chinner { 725*30f712c9SDave Chinner xfs_dir2_data_hdr_t *hdr; /* data block pointer */ 726*30f712c9SDave Chinner xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 727*30f712c9SDave Chinner char *endptr; /* end of data area */ 728*30f712c9SDave Chinner int needscan; /* need to regen bestfree */ 729*30f712c9SDave Chinner xfs_dir2_data_unused_t *newdup; /* new unused entry */ 730*30f712c9SDave Chinner xfs_dir2_data_unused_t *postdup; /* unused entry after us */ 731*30f712c9SDave Chinner xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ 732*30f712c9SDave Chinner struct xfs_dir2_data_free *bf; 733*30f712c9SDave Chinner 734*30f712c9SDave Chinner hdr = bp->b_addr; 735*30f712c9SDave Chinner 736*30f712c9SDave Chinner /* 737*30f712c9SDave Chinner * Figure out where the end of the data area is. 738*30f712c9SDave Chinner */ 739*30f712c9SDave Chinner if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 740*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)) 741*30f712c9SDave Chinner endptr = (char *)hdr + args->geo->blksize; 742*30f712c9SDave Chinner else { 743*30f712c9SDave Chinner xfs_dir2_block_tail_t *btp; /* block tail */ 744*30f712c9SDave Chinner 745*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 746*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 747*30f712c9SDave Chinner btp = xfs_dir2_block_tail_p(args->geo, hdr); 748*30f712c9SDave Chinner endptr = (char *)xfs_dir2_block_leaf_p(btp); 749*30f712c9SDave Chinner } 750*30f712c9SDave Chinner /* 751*30f712c9SDave Chinner * If this isn't the start of the block, then back up to 752*30f712c9SDave Chinner * the previous entry and see if it's free. 753*30f712c9SDave Chinner */ 754*30f712c9SDave Chinner if (offset > args->dp->d_ops->data_entry_offset) { 755*30f712c9SDave Chinner __be16 *tagp; /* tag just before us */ 756*30f712c9SDave Chinner 757*30f712c9SDave Chinner tagp = (__be16 *)((char *)hdr + offset) - 1; 758*30f712c9SDave Chinner prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); 759*30f712c9SDave Chinner if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG) 760*30f712c9SDave Chinner prevdup = NULL; 761*30f712c9SDave Chinner } else 762*30f712c9SDave Chinner prevdup = NULL; 763*30f712c9SDave Chinner /* 764*30f712c9SDave Chinner * If this isn't the end of the block, see if the entry after 765*30f712c9SDave Chinner * us is free. 766*30f712c9SDave Chinner */ 767*30f712c9SDave Chinner if ((char *)hdr + offset + len < endptr) { 768*30f712c9SDave Chinner postdup = 769*30f712c9SDave Chinner (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); 770*30f712c9SDave Chinner if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) 771*30f712c9SDave Chinner postdup = NULL; 772*30f712c9SDave Chinner } else 773*30f712c9SDave Chinner postdup = NULL; 774*30f712c9SDave Chinner ASSERT(*needscanp == 0); 775*30f712c9SDave Chinner needscan = 0; 776*30f712c9SDave Chinner /* 777*30f712c9SDave Chinner * Previous and following entries are both free, 778*30f712c9SDave Chinner * merge everything into a single free entry. 779*30f712c9SDave Chinner */ 780*30f712c9SDave Chinner bf = args->dp->d_ops->data_bestfree_p(hdr); 781*30f712c9SDave Chinner if (prevdup && postdup) { 782*30f712c9SDave Chinner xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ 783*30f712c9SDave Chinner 784*30f712c9SDave Chinner /* 785*30f712c9SDave Chinner * See if prevdup and/or postdup are in bestfree table. 786*30f712c9SDave Chinner */ 787*30f712c9SDave Chinner dfp = xfs_dir2_data_freefind(hdr, bf, prevdup); 788*30f712c9SDave Chinner dfp2 = xfs_dir2_data_freefind(hdr, bf, postdup); 789*30f712c9SDave Chinner /* 790*30f712c9SDave Chinner * We need a rescan unless there are exactly 2 free entries 791*30f712c9SDave Chinner * namely our two. Then we know what's happening, otherwise 792*30f712c9SDave Chinner * since the third bestfree is there, there might be more 793*30f712c9SDave Chinner * entries. 794*30f712c9SDave Chinner */ 795*30f712c9SDave Chinner needscan = (bf[2].length != 0); 796*30f712c9SDave Chinner /* 797*30f712c9SDave Chinner * Fix up the new big freespace. 798*30f712c9SDave Chinner */ 799*30f712c9SDave Chinner be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); 800*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(prevdup) = 801*30f712c9SDave Chinner cpu_to_be16((char *)prevdup - (char *)hdr); 802*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, prevdup); 803*30f712c9SDave Chinner if (!needscan) { 804*30f712c9SDave Chinner /* 805*30f712c9SDave Chinner * Has to be the case that entries 0 and 1 are 806*30f712c9SDave Chinner * dfp and dfp2 (don't know which is which), and 807*30f712c9SDave Chinner * entry 2 is empty. 808*30f712c9SDave Chinner * Remove entry 1 first then entry 0. 809*30f712c9SDave Chinner */ 810*30f712c9SDave Chinner ASSERT(dfp && dfp2); 811*30f712c9SDave Chinner if (dfp == &bf[1]) { 812*30f712c9SDave Chinner dfp = &bf[0]; 813*30f712c9SDave Chinner ASSERT(dfp2 == dfp); 814*30f712c9SDave Chinner dfp2 = &bf[1]; 815*30f712c9SDave Chinner } 816*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp2, needlogp); 817*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp); 818*30f712c9SDave Chinner /* 819*30f712c9SDave Chinner * Now insert the new entry. 820*30f712c9SDave Chinner */ 821*30f712c9SDave Chinner dfp = xfs_dir2_data_freeinsert(hdr, bf, prevdup, 822*30f712c9SDave Chinner needlogp); 823*30f712c9SDave Chinner ASSERT(dfp == &bf[0]); 824*30f712c9SDave Chinner ASSERT(dfp->length == prevdup->length); 825*30f712c9SDave Chinner ASSERT(!dfp[1].length); 826*30f712c9SDave Chinner ASSERT(!dfp[2].length); 827*30f712c9SDave Chinner } 828*30f712c9SDave Chinner } 829*30f712c9SDave Chinner /* 830*30f712c9SDave Chinner * The entry before us is free, merge with it. 831*30f712c9SDave Chinner */ 832*30f712c9SDave Chinner else if (prevdup) { 833*30f712c9SDave Chinner dfp = xfs_dir2_data_freefind(hdr, bf, prevdup); 834*30f712c9SDave Chinner be16_add_cpu(&prevdup->length, len); 835*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(prevdup) = 836*30f712c9SDave Chinner cpu_to_be16((char *)prevdup - (char *)hdr); 837*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, prevdup); 838*30f712c9SDave Chinner /* 839*30f712c9SDave Chinner * If the previous entry was in the table, the new entry 840*30f712c9SDave Chinner * is longer, so it will be in the table too. Remove 841*30f712c9SDave Chinner * the old one and add the new one. 842*30f712c9SDave Chinner */ 843*30f712c9SDave Chinner if (dfp) { 844*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp); 845*30f712c9SDave Chinner xfs_dir2_data_freeinsert(hdr, bf, prevdup, needlogp); 846*30f712c9SDave Chinner } 847*30f712c9SDave Chinner /* 848*30f712c9SDave Chinner * Otherwise we need a scan if the new entry is big enough. 849*30f712c9SDave Chinner */ 850*30f712c9SDave Chinner else { 851*30f712c9SDave Chinner needscan = be16_to_cpu(prevdup->length) > 852*30f712c9SDave Chinner be16_to_cpu(bf[2].length); 853*30f712c9SDave Chinner } 854*30f712c9SDave Chinner } 855*30f712c9SDave Chinner /* 856*30f712c9SDave Chinner * The following entry is free, merge with it. 857*30f712c9SDave Chinner */ 858*30f712c9SDave Chinner else if (postdup) { 859*30f712c9SDave Chinner dfp = xfs_dir2_data_freefind(hdr, bf, postdup); 860*30f712c9SDave Chinner newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); 861*30f712c9SDave Chinner newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 862*30f712c9SDave Chinner newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); 863*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(newdup) = 864*30f712c9SDave Chinner cpu_to_be16((char *)newdup - (char *)hdr); 865*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, newdup); 866*30f712c9SDave Chinner /* 867*30f712c9SDave Chinner * If the following entry was in the table, the new entry 868*30f712c9SDave Chinner * is longer, so it will be in the table too. Remove 869*30f712c9SDave Chinner * the old one and add the new one. 870*30f712c9SDave Chinner */ 871*30f712c9SDave Chinner if (dfp) { 872*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp); 873*30f712c9SDave Chinner xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp); 874*30f712c9SDave Chinner } 875*30f712c9SDave Chinner /* 876*30f712c9SDave Chinner * Otherwise we need a scan if the new entry is big enough. 877*30f712c9SDave Chinner */ 878*30f712c9SDave Chinner else { 879*30f712c9SDave Chinner needscan = be16_to_cpu(newdup->length) > 880*30f712c9SDave Chinner be16_to_cpu(bf[2].length); 881*30f712c9SDave Chinner } 882*30f712c9SDave Chinner } 883*30f712c9SDave Chinner /* 884*30f712c9SDave Chinner * Neither neighbor is free. Make a new entry. 885*30f712c9SDave Chinner */ 886*30f712c9SDave Chinner else { 887*30f712c9SDave Chinner newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); 888*30f712c9SDave Chinner newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 889*30f712c9SDave Chinner newdup->length = cpu_to_be16(len); 890*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(newdup) = 891*30f712c9SDave Chinner cpu_to_be16((char *)newdup - (char *)hdr); 892*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, newdup); 893*30f712c9SDave Chinner xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp); 894*30f712c9SDave Chinner } 895*30f712c9SDave Chinner *needscanp = needscan; 896*30f712c9SDave Chinner } 897*30f712c9SDave Chinner 898*30f712c9SDave Chinner /* 899*30f712c9SDave Chinner * Take a byte range out of an existing unused space and make it un-free. 900*30f712c9SDave Chinner */ 901*30f712c9SDave Chinner void 902*30f712c9SDave Chinner xfs_dir2_data_use_free( 903*30f712c9SDave Chinner struct xfs_da_args *args, 904*30f712c9SDave Chinner struct xfs_buf *bp, 905*30f712c9SDave Chinner xfs_dir2_data_unused_t *dup, /* unused entry */ 906*30f712c9SDave Chinner xfs_dir2_data_aoff_t offset, /* starting offset to use */ 907*30f712c9SDave Chinner xfs_dir2_data_aoff_t len, /* length to use */ 908*30f712c9SDave Chinner int *needlogp, /* out: need to log header */ 909*30f712c9SDave Chinner int *needscanp) /* out: need regen bestfree */ 910*30f712c9SDave Chinner { 911*30f712c9SDave Chinner xfs_dir2_data_hdr_t *hdr; /* data block header */ 912*30f712c9SDave Chinner xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 913*30f712c9SDave Chinner int matchback; /* matches end of freespace */ 914*30f712c9SDave Chinner int matchfront; /* matches start of freespace */ 915*30f712c9SDave Chinner int needscan; /* need to regen bestfree */ 916*30f712c9SDave Chinner xfs_dir2_data_unused_t *newdup; /* new unused entry */ 917*30f712c9SDave Chinner xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ 918*30f712c9SDave Chinner int oldlen; /* old unused entry's length */ 919*30f712c9SDave Chinner struct xfs_dir2_data_free *bf; 920*30f712c9SDave Chinner 921*30f712c9SDave Chinner hdr = bp->b_addr; 922*30f712c9SDave Chinner ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 923*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 924*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 925*30f712c9SDave Chinner hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 926*30f712c9SDave Chinner ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); 927*30f712c9SDave Chinner ASSERT(offset >= (char *)dup - (char *)hdr); 928*30f712c9SDave Chinner ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr); 929*30f712c9SDave Chinner ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); 930*30f712c9SDave Chinner /* 931*30f712c9SDave Chinner * Look up the entry in the bestfree table. 932*30f712c9SDave Chinner */ 933*30f712c9SDave Chinner oldlen = be16_to_cpu(dup->length); 934*30f712c9SDave Chinner bf = args->dp->d_ops->data_bestfree_p(hdr); 935*30f712c9SDave Chinner dfp = xfs_dir2_data_freefind(hdr, bf, dup); 936*30f712c9SDave Chinner ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); 937*30f712c9SDave Chinner /* 938*30f712c9SDave Chinner * Check for alignment with front and back of the entry. 939*30f712c9SDave Chinner */ 940*30f712c9SDave Chinner matchfront = (char *)dup - (char *)hdr == offset; 941*30f712c9SDave Chinner matchback = (char *)dup + oldlen - (char *)hdr == offset + len; 942*30f712c9SDave Chinner ASSERT(*needscanp == 0); 943*30f712c9SDave Chinner needscan = 0; 944*30f712c9SDave Chinner /* 945*30f712c9SDave Chinner * If we matched it exactly we just need to get rid of it from 946*30f712c9SDave Chinner * the bestfree table. 947*30f712c9SDave Chinner */ 948*30f712c9SDave Chinner if (matchfront && matchback) { 949*30f712c9SDave Chinner if (dfp) { 950*30f712c9SDave Chinner needscan = (bf[2].offset != 0); 951*30f712c9SDave Chinner if (!needscan) 952*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, 953*30f712c9SDave Chinner needlogp); 954*30f712c9SDave Chinner } 955*30f712c9SDave Chinner } 956*30f712c9SDave Chinner /* 957*30f712c9SDave Chinner * We match the first part of the entry. 958*30f712c9SDave Chinner * Make a new entry with the remaining freespace. 959*30f712c9SDave Chinner */ 960*30f712c9SDave Chinner else if (matchfront) { 961*30f712c9SDave Chinner newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); 962*30f712c9SDave Chinner newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 963*30f712c9SDave Chinner newdup->length = cpu_to_be16(oldlen - len); 964*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(newdup) = 965*30f712c9SDave Chinner cpu_to_be16((char *)newdup - (char *)hdr); 966*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, newdup); 967*30f712c9SDave Chinner /* 968*30f712c9SDave Chinner * If it was in the table, remove it and add the new one. 969*30f712c9SDave Chinner */ 970*30f712c9SDave Chinner if (dfp) { 971*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp); 972*30f712c9SDave Chinner dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup, 973*30f712c9SDave Chinner needlogp); 974*30f712c9SDave Chinner ASSERT(dfp != NULL); 975*30f712c9SDave Chinner ASSERT(dfp->length == newdup->length); 976*30f712c9SDave Chinner ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr); 977*30f712c9SDave Chinner /* 978*30f712c9SDave Chinner * If we got inserted at the last slot, 979*30f712c9SDave Chinner * that means we don't know if there was a better 980*30f712c9SDave Chinner * choice for the last slot, or not. Rescan. 981*30f712c9SDave Chinner */ 982*30f712c9SDave Chinner needscan = dfp == &bf[2]; 983*30f712c9SDave Chinner } 984*30f712c9SDave Chinner } 985*30f712c9SDave Chinner /* 986*30f712c9SDave Chinner * We match the last part of the entry. 987*30f712c9SDave Chinner * Trim the allocated space off the tail of the entry. 988*30f712c9SDave Chinner */ 989*30f712c9SDave Chinner else if (matchback) { 990*30f712c9SDave Chinner newdup = dup; 991*30f712c9SDave Chinner newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); 992*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(newdup) = 993*30f712c9SDave Chinner cpu_to_be16((char *)newdup - (char *)hdr); 994*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, newdup); 995*30f712c9SDave Chinner /* 996*30f712c9SDave Chinner * If it was in the table, remove it and add the new one. 997*30f712c9SDave Chinner */ 998*30f712c9SDave Chinner if (dfp) { 999*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp); 1000*30f712c9SDave Chinner dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup, 1001*30f712c9SDave Chinner needlogp); 1002*30f712c9SDave Chinner ASSERT(dfp != NULL); 1003*30f712c9SDave Chinner ASSERT(dfp->length == newdup->length); 1004*30f712c9SDave Chinner ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr); 1005*30f712c9SDave Chinner /* 1006*30f712c9SDave Chinner * If we got inserted at the last slot, 1007*30f712c9SDave Chinner * that means we don't know if there was a better 1008*30f712c9SDave Chinner * choice for the last slot, or not. Rescan. 1009*30f712c9SDave Chinner */ 1010*30f712c9SDave Chinner needscan = dfp == &bf[2]; 1011*30f712c9SDave Chinner } 1012*30f712c9SDave Chinner } 1013*30f712c9SDave Chinner /* 1014*30f712c9SDave Chinner * Poking out the middle of an entry. 1015*30f712c9SDave Chinner * Make two new entries. 1016*30f712c9SDave Chinner */ 1017*30f712c9SDave Chinner else { 1018*30f712c9SDave Chinner newdup = dup; 1019*30f712c9SDave Chinner newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); 1020*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(newdup) = 1021*30f712c9SDave Chinner cpu_to_be16((char *)newdup - (char *)hdr); 1022*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, newdup); 1023*30f712c9SDave Chinner newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); 1024*30f712c9SDave Chinner newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 1025*30f712c9SDave Chinner newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); 1026*30f712c9SDave Chinner *xfs_dir2_data_unused_tag_p(newdup2) = 1027*30f712c9SDave Chinner cpu_to_be16((char *)newdup2 - (char *)hdr); 1028*30f712c9SDave Chinner xfs_dir2_data_log_unused(args, bp, newdup2); 1029*30f712c9SDave Chinner /* 1030*30f712c9SDave Chinner * If the old entry was in the table, we need to scan 1031*30f712c9SDave Chinner * if the 3rd entry was valid, since these entries 1032*30f712c9SDave Chinner * are smaller than the old one. 1033*30f712c9SDave Chinner * If we don't need to scan that means there were 1 or 2 1034*30f712c9SDave Chinner * entries in the table, and removing the old and adding 1035*30f712c9SDave Chinner * the 2 new will work. 1036*30f712c9SDave Chinner */ 1037*30f712c9SDave Chinner if (dfp) { 1038*30f712c9SDave Chinner needscan = (bf[2].length != 0); 1039*30f712c9SDave Chinner if (!needscan) { 1040*30f712c9SDave Chinner xfs_dir2_data_freeremove(hdr, bf, dfp, 1041*30f712c9SDave Chinner needlogp); 1042*30f712c9SDave Chinner xfs_dir2_data_freeinsert(hdr, bf, newdup, 1043*30f712c9SDave Chinner needlogp); 1044*30f712c9SDave Chinner xfs_dir2_data_freeinsert(hdr, bf, newdup2, 1045*30f712c9SDave Chinner needlogp); 1046*30f712c9SDave Chinner } 1047*30f712c9SDave Chinner } 1048*30f712c9SDave Chinner } 1049*30f712c9SDave Chinner *needscanp = needscan; 1050*30f712c9SDave Chinner } 1051