1153323Srodrigc/* 2159451Srodrigc * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 3159451Srodrigc * All Rights Reserved. 4153323Srodrigc * 5159451Srodrigc * This program is free software; you can redistribute it and/or 6159451Srodrigc * modify it under the terms of the GNU General Public License as 7153323Srodrigc * published by the Free Software Foundation. 8153323Srodrigc * 9159451Srodrigc * This program is distributed in the hope that it would be useful, 10159451Srodrigc * but WITHOUT ANY WARRANTY; without even the implied warranty of 11159451Srodrigc * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12159451Srodrigc * GNU General Public License for more details. 13153323Srodrigc * 14159451Srodrigc * You should have received a copy of the GNU General Public License 15159451Srodrigc * along with this program; if not, write the Free Software Foundation, 16159451Srodrigc * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17153323Srodrigc */ 18153323Srodrigc#include "xfs.h" 19159451Srodrigc#include "xfs_fs.h" 20153323Srodrigc#include "xfs_types.h" 21159451Srodrigc#include "xfs_bit.h" 22159451Srodrigc#include "xfs_log.h" 23153323Srodrigc#include "xfs_inum.h" 24153323Srodrigc#include "xfs_trans.h" 25153323Srodrigc#include "xfs_sb.h" 26153323Srodrigc#include "xfs_ag.h" 27153323Srodrigc#include "xfs_dir.h" 28153323Srodrigc#include "xfs_dir2.h" 29153323Srodrigc#include "xfs_dmapi.h" 30153323Srodrigc#include "xfs_mount.h" 31159451Srodrigc#include "xfs_da_btree.h" 32153323Srodrigc#include "xfs_bmap_btree.h" 33153323Srodrigc#include "xfs_attr_sf.h" 34153323Srodrigc#include "xfs_dir_sf.h" 35153323Srodrigc#include "xfs_dir2_sf.h" 36153323Srodrigc#include "xfs_dinode.h" 37153323Srodrigc#include "xfs_inode.h" 38153323Srodrigc#include "xfs_bmap.h" 39153323Srodrigc#include "xfs_dir2_data.h" 40153323Srodrigc#include "xfs_dir2_leaf.h" 41153323Srodrigc#include "xfs_dir2_block.h" 42153323Srodrigc#include "xfs_dir2_node.h" 43153323Srodrigc#include "xfs_dir2_trace.h" 44153323Srodrigc#include "xfs_error.h" 45153323Srodrigc 46153323Srodrigc/* 47153323Srodrigc * Local function declarations. 48153323Srodrigc */ 49153323Srodrigc#ifdef DEBUG 50153323Srodrigcstatic void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); 51153323Srodrigc#else 52153323Srodrigc#define xfs_dir2_leaf_check(dp, bp) 53153323Srodrigc#endif 54153323Srodrigcstatic int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, 55153323Srodrigc int *indexp, xfs_dabuf_t **dbpp); 56159451Srodrigcstatic void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, 57159451Srodrigc int first, int last); 58159451Srodrigcstatic void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); 59153323Srodrigc 60159451Srodrigc 61153323Srodrigc/* 62153323Srodrigc * Convert a block form directory to a leaf form directory. 63153323Srodrigc */ 64153323Srodrigcint /* error */ 65153323Srodrigcxfs_dir2_block_to_leaf( 66153323Srodrigc xfs_da_args_t *args, /* operation arguments */ 67153323Srodrigc xfs_dabuf_t *dbp) /* input block's buffer */ 68153323Srodrigc{ 69159451Srodrigc __be16 *bestsp; /* leaf's bestsp entries */ 70153323Srodrigc xfs_dablk_t blkno; /* leaf block's bno */ 71153323Srodrigc xfs_dir2_block_t *block; /* block structure */ 72153323Srodrigc xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ 73153323Srodrigc xfs_dir2_block_tail_t *btp; /* block's tail */ 74153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 75153323Srodrigc int error; /* error return code */ 76153323Srodrigc xfs_dabuf_t *lbp; /* leaf block's buffer */ 77153323Srodrigc xfs_dir2_db_t ldb; /* leaf block's bno */ 78153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 79153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */ 80153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 81153323Srodrigc int needlog; /* need to log block header */ 82153323Srodrigc int needscan; /* need to rescan bestfree */ 83153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 84153323Srodrigc 85153323Srodrigc xfs_dir2_trace_args_b("block_to_leaf", args, dbp); 86153323Srodrigc dp = args->dp; 87153323Srodrigc mp = dp->i_mount; 88153323Srodrigc tp = args->trans; 89153323Srodrigc /* 90153323Srodrigc * Add the leaf block to the inode. 91153323Srodrigc * This interface will only put blocks in the leaf/node range. 92153323Srodrigc * Since that's empty now, we'll get the root (block 0 in range). 93153323Srodrigc */ 94153323Srodrigc if ((error = xfs_da_grow_inode(args, &blkno))) { 95153323Srodrigc return error; 96153323Srodrigc } 97153323Srodrigc ldb = XFS_DIR2_DA_TO_DB(mp, blkno); 98153323Srodrigc ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); 99153323Srodrigc /* 100153323Srodrigc * Initialize the leaf block, get a buffer for it. 101153323Srodrigc */ 102153323Srodrigc if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) { 103153323Srodrigc return error; 104153323Srodrigc } 105153323Srodrigc ASSERT(lbp != NULL); 106153323Srodrigc leaf = lbp->data; 107153323Srodrigc block = dbp->data; 108153323Srodrigc xfs_dir2_data_check(dp, dbp); 109153323Srodrigc btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 110159451Srodrigc blp = XFS_DIR2_BLOCK_LEAF_P(btp); 111153323Srodrigc /* 112153323Srodrigc * Set the counts in the leaf header. 113153323Srodrigc */ 114159451Srodrigc leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count)); 115159451Srodrigc leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale)); 116153323Srodrigc /* 117153323Srodrigc * Could compact these but I think we always do the conversion 118153323Srodrigc * after squeezing out stale entries. 119153323Srodrigc */ 120159451Srodrigc memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); 121159451Srodrigc xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1); 122153323Srodrigc needscan = 0; 123153323Srodrigc needlog = 1; 124153323Srodrigc /* 125153323Srodrigc * Make the space formerly occupied by the leaf entries and block 126153323Srodrigc * tail be free. 127153323Srodrigc */ 128153323Srodrigc xfs_dir2_data_make_free(tp, dbp, 129153323Srodrigc (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), 130153323Srodrigc (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize - 131153323Srodrigc (char *)blp), 132153323Srodrigc &needlog, &needscan); 133153323Srodrigc /* 134153323Srodrigc * Fix up the block header, make it a data block. 135153323Srodrigc */ 136159451Srodrigc block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 137153323Srodrigc if (needscan) 138153323Srodrigc xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 139153323Srodrigc NULL); 140153323Srodrigc /* 141153323Srodrigc * Set up leaf tail and bests table. 142153323Srodrigc */ 143153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 144159451Srodrigc ltp->bestcount = cpu_to_be32(1); 145159451Srodrigc bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 146159451Srodrigc bestsp[0] = block->hdr.bestfree[0].length; 147153323Srodrigc /* 148153323Srodrigc * Log the data header and leaf bests table. 149153323Srodrigc */ 150153323Srodrigc if (needlog) 151153323Srodrigc xfs_dir2_data_log_header(tp, dbp); 152153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 153153323Srodrigc xfs_dir2_data_check(dp, dbp); 154153323Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); 155153323Srodrigc xfs_da_buf_done(lbp); 156153323Srodrigc return 0; 157153323Srodrigc} 158153323Srodrigc 159153323Srodrigc/* 160153323Srodrigc * Add an entry to a leaf form directory. 161153323Srodrigc */ 162153323Srodrigcint /* error */ 163153323Srodrigcxfs_dir2_leaf_addname( 164153323Srodrigc xfs_da_args_t *args) /* operation arguments */ 165153323Srodrigc{ 166159451Srodrigc __be16 *bestsp; /* freespace table in leaf */ 167153323Srodrigc int compact; /* need to compact leaves */ 168153323Srodrigc xfs_dir2_data_t *data; /* data block structure */ 169153323Srodrigc xfs_dabuf_t *dbp; /* data block buffer */ 170153323Srodrigc xfs_dir2_data_entry_t *dep; /* data block entry */ 171153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 172153323Srodrigc xfs_dir2_data_unused_t *dup; /* data unused entry */ 173153323Srodrigc int error; /* error return value */ 174153323Srodrigc int grown; /* allocated new data block */ 175153323Srodrigc int highstale; /* index of next stale leaf */ 176153323Srodrigc int i; /* temporary, index */ 177153323Srodrigc int index; /* leaf table position */ 178153323Srodrigc xfs_dabuf_t *lbp; /* leaf's buffer */ 179153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 180153323Srodrigc int length; /* length of new entry */ 181153323Srodrigc xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ 182153323Srodrigc int lfloglow; /* low leaf logging index */ 183153323Srodrigc int lfloghigh; /* high leaf logging index */ 184153323Srodrigc int lowstale; /* index of prev stale leaf */ 185153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ 186153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 187153323Srodrigc int needbytes; /* leaf block bytes needed */ 188153323Srodrigc int needlog; /* need to log data header */ 189153323Srodrigc int needscan; /* need to rescan data free */ 190159451Srodrigc __be16 *tagp; /* end of data entry */ 191153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 192153323Srodrigc xfs_dir2_db_t use_block; /* data block number */ 193153323Srodrigc 194153323Srodrigc xfs_dir2_trace_args("leaf_addname", args); 195153323Srodrigc dp = args->dp; 196153323Srodrigc tp = args->trans; 197153323Srodrigc mp = dp->i_mount; 198153323Srodrigc /* 199153323Srodrigc * Read the leaf block. 200153323Srodrigc */ 201153323Srodrigc error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, 202153323Srodrigc XFS_DATA_FORK); 203153323Srodrigc if (error) { 204153323Srodrigc return error; 205153323Srodrigc } 206153323Srodrigc ASSERT(lbp != NULL); 207153323Srodrigc /* 208153323Srodrigc * Look up the entry by hash value and name. 209153323Srodrigc * We know it's not there, our caller has already done a lookup. 210153323Srodrigc * So the index is of the entry to insert in front of. 211153323Srodrigc * But if there are dup hash values the index is of the first of those. 212153323Srodrigc */ 213153323Srodrigc index = xfs_dir2_leaf_search_hash(args, lbp); 214153323Srodrigc leaf = lbp->data; 215153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 216159451Srodrigc bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 217153323Srodrigc length = XFS_DIR2_DATA_ENTSIZE(args->namelen); 218153323Srodrigc /* 219153323Srodrigc * See if there are any entries with the same hash value 220153323Srodrigc * and space in their block for the new entry. 221153323Srodrigc * This is good because it puts multiple same-hash value entries 222153323Srodrigc * in a data block, improving the lookup of those entries. 223153323Srodrigc */ 224153323Srodrigc for (use_block = -1, lep = &leaf->ents[index]; 225159451Srodrigc index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; 226153323Srodrigc index++, lep++) { 227159451Srodrigc if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 228153323Srodrigc continue; 229159451Srodrigc i = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); 230159451Srodrigc ASSERT(i < be32_to_cpu(ltp->bestcount)); 231159451Srodrigc ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); 232159451Srodrigc if (be16_to_cpu(bestsp[i]) >= length) { 233153323Srodrigc use_block = i; 234153323Srodrigc break; 235153323Srodrigc } 236153323Srodrigc } 237153323Srodrigc /* 238153323Srodrigc * Didn't find a block yet, linear search all the data blocks. 239153323Srodrigc */ 240153323Srodrigc if (use_block == -1) { 241159451Srodrigc for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) { 242153323Srodrigc /* 243153323Srodrigc * Remember a block we see that's missing. 244153323Srodrigc */ 245159451Srodrigc if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1) 246153323Srodrigc use_block = i; 247159451Srodrigc else if (be16_to_cpu(bestsp[i]) >= length) { 248153323Srodrigc use_block = i; 249153323Srodrigc break; 250153323Srodrigc } 251153323Srodrigc } 252153323Srodrigc } 253153323Srodrigc /* 254153323Srodrigc * How many bytes do we need in the leaf block? 255153323Srodrigc */ 256153323Srodrigc needbytes = 257159451Srodrigc (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + 258153323Srodrigc (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); 259153323Srodrigc /* 260153323Srodrigc * Now kill use_block if it refers to a missing block, so we 261153323Srodrigc * can use it as an indication of allocation needed. 262153323Srodrigc */ 263159451Srodrigc if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF) 264153323Srodrigc use_block = -1; 265153323Srodrigc /* 266153323Srodrigc * If we don't have enough free bytes but we can make enough 267153323Srodrigc * by compacting out stale entries, we'll do that. 268153323Srodrigc */ 269159451Srodrigc if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < needbytes && 270159451Srodrigc be16_to_cpu(leaf->hdr.stale) > 1) { 271153323Srodrigc compact = 1; 272153323Srodrigc } 273153323Srodrigc /* 274153323Srodrigc * Otherwise if we don't have enough free bytes we need to 275153323Srodrigc * convert to node form. 276153323Srodrigc */ 277159451Srodrigc else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < 278153323Srodrigc needbytes) { 279153323Srodrigc /* 280153323Srodrigc * Just checking or no space reservation, give up. 281153323Srodrigc */ 282153323Srodrigc if (args->justcheck || args->total == 0) { 283153323Srodrigc xfs_da_brelse(tp, lbp); 284153323Srodrigc return XFS_ERROR(ENOSPC); 285153323Srodrigc } 286153323Srodrigc /* 287153323Srodrigc * Convert to node form. 288153323Srodrigc */ 289153323Srodrigc error = xfs_dir2_leaf_to_node(args, lbp); 290153323Srodrigc xfs_da_buf_done(lbp); 291153323Srodrigc if (error) 292153323Srodrigc return error; 293153323Srodrigc /* 294153323Srodrigc * Then add the new entry. 295153323Srodrigc */ 296153323Srodrigc return xfs_dir2_node_addname(args); 297153323Srodrigc } 298153323Srodrigc /* 299153323Srodrigc * Otherwise it will fit without compaction. 300153323Srodrigc */ 301153323Srodrigc else 302153323Srodrigc compact = 0; 303153323Srodrigc /* 304153323Srodrigc * If just checking, then it will fit unless we needed to allocate 305153323Srodrigc * a new data block. 306153323Srodrigc */ 307153323Srodrigc if (args->justcheck) { 308153323Srodrigc xfs_da_brelse(tp, lbp); 309153323Srodrigc return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; 310153323Srodrigc } 311153323Srodrigc /* 312153323Srodrigc * If no allocations are allowed, return now before we've 313153323Srodrigc * changed anything. 314153323Srodrigc */ 315153323Srodrigc if (args->total == 0 && use_block == -1) { 316153323Srodrigc xfs_da_brelse(tp, lbp); 317153323Srodrigc return XFS_ERROR(ENOSPC); 318153323Srodrigc } 319153323Srodrigc /* 320153323Srodrigc * Need to compact the leaf entries, removing stale ones. 321153323Srodrigc * Leave one stale entry behind - the one closest to our 322153323Srodrigc * insertion index - and we'll shift that one to our insertion 323153323Srodrigc * point later. 324153323Srodrigc */ 325153323Srodrigc if (compact) { 326153323Srodrigc xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale, 327153323Srodrigc &lfloglow, &lfloghigh); 328153323Srodrigc } 329153323Srodrigc /* 330153323Srodrigc * There are stale entries, so we'll need log-low and log-high 331153323Srodrigc * impossibly bad values later. 332153323Srodrigc */ 333159451Srodrigc else if (be16_to_cpu(leaf->hdr.stale)) { 334159451Srodrigc lfloglow = be16_to_cpu(leaf->hdr.count); 335153323Srodrigc lfloghigh = -1; 336153323Srodrigc } 337153323Srodrigc /* 338153323Srodrigc * If there was no data block space found, we need to allocate 339153323Srodrigc * a new one. 340153323Srodrigc */ 341153323Srodrigc if (use_block == -1) { 342153323Srodrigc /* 343153323Srodrigc * Add the new data block. 344153323Srodrigc */ 345153323Srodrigc if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, 346153323Srodrigc &use_block))) { 347153323Srodrigc xfs_da_brelse(tp, lbp); 348153323Srodrigc return error; 349153323Srodrigc } 350153323Srodrigc /* 351153323Srodrigc * Initialize the block. 352153323Srodrigc */ 353153323Srodrigc if ((error = xfs_dir2_data_init(args, use_block, &dbp))) { 354153323Srodrigc xfs_da_brelse(tp, lbp); 355153323Srodrigc return error; 356153323Srodrigc } 357153323Srodrigc /* 358153323Srodrigc * If we're adding a new data block on the end we need to 359153323Srodrigc * extend the bests table. Copy it up one entry. 360153323Srodrigc */ 361159451Srodrigc if (use_block >= be32_to_cpu(ltp->bestcount)) { 362153323Srodrigc bestsp--; 363153323Srodrigc memmove(&bestsp[0], &bestsp[1], 364159451Srodrigc be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); 365159451Srodrigc be32_add(<p->bestcount, 1); 366153323Srodrigc xfs_dir2_leaf_log_tail(tp, lbp); 367159451Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 368153323Srodrigc } 369153323Srodrigc /* 370153323Srodrigc * If we're filling in a previously empty block just log it. 371153323Srodrigc */ 372153323Srodrigc else 373153323Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 374153323Srodrigc data = dbp->data; 375159451Srodrigc bestsp[use_block] = data->hdr.bestfree[0].length; 376153323Srodrigc grown = 1; 377153323Srodrigc } 378153323Srodrigc /* 379153323Srodrigc * Already had space in some data block. 380153323Srodrigc * Just read that one in. 381153323Srodrigc */ 382153323Srodrigc else { 383153323Srodrigc if ((error = 384153323Srodrigc xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block), 385153323Srodrigc -1, &dbp, XFS_DATA_FORK))) { 386153323Srodrigc xfs_da_brelse(tp, lbp); 387153323Srodrigc return error; 388153323Srodrigc } 389153323Srodrigc data = dbp->data; 390153323Srodrigc grown = 0; 391153323Srodrigc } 392153323Srodrigc xfs_dir2_data_check(dp, dbp); 393153323Srodrigc /* 394153323Srodrigc * Point to the biggest freespace in our data block. 395153323Srodrigc */ 396153323Srodrigc dup = (xfs_dir2_data_unused_t *) 397159451Srodrigc ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); 398159451Srodrigc ASSERT(be16_to_cpu(dup->length) >= length); 399153323Srodrigc needscan = needlog = 0; 400153323Srodrigc /* 401153323Srodrigc * Mark the initial part of our freespace in use for the new entry. 402153323Srodrigc */ 403153323Srodrigc xfs_dir2_data_use_free(tp, dbp, dup, 404153323Srodrigc (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, 405153323Srodrigc &needlog, &needscan); 406153323Srodrigc /* 407153323Srodrigc * Initialize our new entry (at last). 408153323Srodrigc */ 409153323Srodrigc dep = (xfs_dir2_data_entry_t *)dup; 410153323Srodrigc INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 411153323Srodrigc dep->namelen = args->namelen; 412153323Srodrigc memcpy(dep->name, args->name, dep->namelen); 413153323Srodrigc tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 414159451Srodrigc *tagp = cpu_to_be16((char *)dep - (char *)data); 415153323Srodrigc /* 416153323Srodrigc * Need to scan fix up the bestfree table. 417153323Srodrigc */ 418153323Srodrigc if (needscan) 419153323Srodrigc xfs_dir2_data_freescan(mp, data, &needlog, NULL); 420153323Srodrigc /* 421153323Srodrigc * Need to log the data block's header. 422153323Srodrigc */ 423153323Srodrigc if (needlog) 424153323Srodrigc xfs_dir2_data_log_header(tp, dbp); 425153323Srodrigc xfs_dir2_data_log_entry(tp, dbp, dep); 426153323Srodrigc /* 427153323Srodrigc * If the bests table needs to be changed, do it. 428153323Srodrigc * Log the change unless we've already done that. 429153323Srodrigc */ 430159451Srodrigc if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) { 431159451Srodrigc bestsp[use_block] = data->hdr.bestfree[0].length; 432153323Srodrigc if (!grown) 433153323Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 434153323Srodrigc } 435153323Srodrigc /* 436153323Srodrigc * Now we need to make room to insert the leaf entry. 437153323Srodrigc * If there are no stale entries, we just insert a hole at index. 438153323Srodrigc */ 439159451Srodrigc if (!leaf->hdr.stale) { 440153323Srodrigc /* 441153323Srodrigc * lep is still good as the index leaf entry. 442153323Srodrigc */ 443159451Srodrigc if (index < be16_to_cpu(leaf->hdr.count)) 444153323Srodrigc memmove(lep + 1, lep, 445159451Srodrigc (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); 446153323Srodrigc /* 447153323Srodrigc * Record low and high logging indices for the leaf. 448153323Srodrigc */ 449153323Srodrigc lfloglow = index; 450159451Srodrigc lfloghigh = be16_to_cpu(leaf->hdr.count); 451159451Srodrigc be16_add(&leaf->hdr.count, 1); 452153323Srodrigc } 453153323Srodrigc /* 454153323Srodrigc * There are stale entries. 455153323Srodrigc * We will use one of them for the new entry. 456153323Srodrigc * It's probably not at the right location, so we'll have to 457153323Srodrigc * shift some up or down first. 458153323Srodrigc */ 459153323Srodrigc else { 460153323Srodrigc /* 461153323Srodrigc * If we didn't compact before, we need to find the nearest 462153323Srodrigc * stale entries before and after our insertion point. 463153323Srodrigc */ 464153323Srodrigc if (compact == 0) { 465153323Srodrigc /* 466153323Srodrigc * Find the first stale entry before the insertion 467153323Srodrigc * point, if any. 468153323Srodrigc */ 469153323Srodrigc for (lowstale = index - 1; 470153323Srodrigc lowstale >= 0 && 471159451Srodrigc be32_to_cpu(leaf->ents[lowstale].address) != 472153323Srodrigc XFS_DIR2_NULL_DATAPTR; 473153323Srodrigc lowstale--) 474153323Srodrigc continue; 475153323Srodrigc /* 476153323Srodrigc * Find the next stale entry at or after the insertion 477153323Srodrigc * point, if any. Stop if we go so far that the 478153323Srodrigc * lowstale entry would be better. 479153323Srodrigc */ 480153323Srodrigc for (highstale = index; 481159451Srodrigc highstale < be16_to_cpu(leaf->hdr.count) && 482159451Srodrigc be32_to_cpu(leaf->ents[highstale].address) != 483153323Srodrigc XFS_DIR2_NULL_DATAPTR && 484153323Srodrigc (lowstale < 0 || 485153323Srodrigc index - lowstale - 1 >= highstale - index); 486153323Srodrigc highstale++) 487153323Srodrigc continue; 488153323Srodrigc } 489153323Srodrigc /* 490153323Srodrigc * If the low one is better, use it. 491153323Srodrigc */ 492153323Srodrigc if (lowstale >= 0 && 493159451Srodrigc (highstale == be16_to_cpu(leaf->hdr.count) || 494153323Srodrigc index - lowstale - 1 < highstale - index)) { 495153323Srodrigc ASSERT(index - lowstale - 1 >= 0); 496159451Srodrigc ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == 497153323Srodrigc XFS_DIR2_NULL_DATAPTR); 498153323Srodrigc /* 499153323Srodrigc * Copy entries up to cover the stale entry 500153323Srodrigc * and make room for the new entry. 501153323Srodrigc */ 502153323Srodrigc if (index - lowstale - 1 > 0) 503153323Srodrigc memmove(&leaf->ents[lowstale], 504153323Srodrigc &leaf->ents[lowstale + 1], 505153323Srodrigc (index - lowstale - 1) * sizeof(*lep)); 506153323Srodrigc lep = &leaf->ents[index - 1]; 507153323Srodrigc lfloglow = MIN(lowstale, lfloglow); 508153323Srodrigc lfloghigh = MAX(index - 1, lfloghigh); 509153323Srodrigc } 510153323Srodrigc /* 511153323Srodrigc * The high one is better, so use that one. 512153323Srodrigc */ 513153323Srodrigc else { 514153323Srodrigc ASSERT(highstale - index >= 0); 515159451Srodrigc ASSERT(be32_to_cpu(leaf->ents[highstale].address) == 516153323Srodrigc XFS_DIR2_NULL_DATAPTR); 517153323Srodrigc /* 518159451Srodrigc * Copy entries down to cover the stale entry 519153323Srodrigc * and make room for the new entry. 520153323Srodrigc */ 521153323Srodrigc if (highstale - index > 0) 522153323Srodrigc memmove(&leaf->ents[index + 1], 523153323Srodrigc &leaf->ents[index], 524153323Srodrigc (highstale - index) * sizeof(*lep)); 525153323Srodrigc lep = &leaf->ents[index]; 526153323Srodrigc lfloglow = MIN(index, lfloglow); 527153323Srodrigc lfloghigh = MAX(highstale, lfloghigh); 528153323Srodrigc } 529159451Srodrigc be16_add(&leaf->hdr.stale, -1); 530153323Srodrigc } 531153323Srodrigc /* 532153323Srodrigc * Fill in the new leaf entry. 533153323Srodrigc */ 534159451Srodrigc lep->hashval = cpu_to_be32(args->hashval); 535159451Srodrigc lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, 536159451Srodrigc be16_to_cpu(*tagp))); 537153323Srodrigc /* 538153323Srodrigc * Log the leaf fields and give up the buffers. 539153323Srodrigc */ 540153323Srodrigc xfs_dir2_leaf_log_header(tp, lbp); 541153323Srodrigc xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); 542153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 543153323Srodrigc xfs_da_buf_done(lbp); 544153323Srodrigc xfs_dir2_data_check(dp, dbp); 545153323Srodrigc xfs_da_buf_done(dbp); 546153323Srodrigc return 0; 547153323Srodrigc} 548153323Srodrigc 549153323Srodrigc#ifdef DEBUG 550153323Srodrigc/* 551153323Srodrigc * Check the internal consistency of a leaf1 block. 552153323Srodrigc * Pop an assert if something is wrong. 553153323Srodrigc */ 554153323Srodrigcvoid 555153323Srodrigcxfs_dir2_leaf_check( 556153323Srodrigc xfs_inode_t *dp, /* incore directory inode */ 557153323Srodrigc xfs_dabuf_t *bp) /* leaf's buffer */ 558153323Srodrigc{ 559153323Srodrigc int i; /* leaf index */ 560153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 561153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ 562153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 563153323Srodrigc int stale; /* count of stale leaves */ 564153323Srodrigc 565153323Srodrigc leaf = bp->data; 566153323Srodrigc mp = dp->i_mount; 567159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 568153323Srodrigc /* 569153323Srodrigc * This value is not restrictive enough. 570153323Srodrigc * Should factor in the size of the bests table as well. 571153323Srodrigc * We can deduce a value for that from di_size. 572153323Srodrigc */ 573159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); 574153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 575153323Srodrigc /* 576153323Srodrigc * Leaves and bests don't overlap. 577153323Srodrigc */ 578159451Srodrigc ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <= 579159451Srodrigc (char *)XFS_DIR2_LEAF_BESTS_P(ltp)); 580153323Srodrigc /* 581153323Srodrigc * Check hash value order, count stale entries. 582153323Srodrigc */ 583159451Srodrigc for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { 584159451Srodrigc if (i + 1 < be16_to_cpu(leaf->hdr.count)) 585159451Srodrigc ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= 586159451Srodrigc be32_to_cpu(leaf->ents[i + 1].hashval)); 587159451Srodrigc if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) 588153323Srodrigc stale++; 589153323Srodrigc } 590159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); 591153323Srodrigc} 592153323Srodrigc#endif /* DEBUG */ 593153323Srodrigc 594153323Srodrigc/* 595153323Srodrigc * Compact out any stale entries in the leaf. 596153323Srodrigc * Log the header and changed leaf entries, if any. 597153323Srodrigc */ 598153323Srodrigcvoid 599153323Srodrigcxfs_dir2_leaf_compact( 600153323Srodrigc xfs_da_args_t *args, /* operation arguments */ 601153323Srodrigc xfs_dabuf_t *bp) /* leaf buffer */ 602153323Srodrigc{ 603153323Srodrigc int from; /* source leaf index */ 604153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 605153323Srodrigc int loglow; /* first leaf entry to log */ 606153323Srodrigc int to; /* target leaf index */ 607153323Srodrigc 608153323Srodrigc leaf = bp->data; 609159451Srodrigc if (!leaf->hdr.stale) { 610153323Srodrigc return; 611153323Srodrigc } 612153323Srodrigc /* 613153323Srodrigc * Compress out the stale entries in place. 614153323Srodrigc */ 615159451Srodrigc for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) { 616159451Srodrigc if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) 617153323Srodrigc continue; 618153323Srodrigc /* 619153323Srodrigc * Only actually copy the entries that are different. 620153323Srodrigc */ 621153323Srodrigc if (from > to) { 622153323Srodrigc if (loglow == -1) 623153323Srodrigc loglow = to; 624153323Srodrigc leaf->ents[to] = leaf->ents[from]; 625153323Srodrigc } 626153323Srodrigc to++; 627153323Srodrigc } 628153323Srodrigc /* 629153323Srodrigc * Update and log the header, log the leaf entries. 630153323Srodrigc */ 631159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); 632159451Srodrigc be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); 633159451Srodrigc leaf->hdr.stale = 0; 634153323Srodrigc xfs_dir2_leaf_log_header(args->trans, bp); 635153323Srodrigc if (loglow != -1) 636153323Srodrigc xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1); 637153323Srodrigc} 638153323Srodrigc 639153323Srodrigc/* 640153323Srodrigc * Compact the leaf entries, removing stale ones. 641153323Srodrigc * Leave one stale entry behind - the one closest to our 642153323Srodrigc * insertion index - and the caller will shift that one to our insertion 643153323Srodrigc * point later. 644153323Srodrigc * Return new insertion index, where the remaining stale entry is, 645153323Srodrigc * and leaf logging indices. 646153323Srodrigc */ 647153323Srodrigcvoid 648153323Srodrigcxfs_dir2_leaf_compact_x1( 649153323Srodrigc xfs_dabuf_t *bp, /* leaf buffer */ 650153323Srodrigc int *indexp, /* insertion index */ 651153323Srodrigc int *lowstalep, /* out: stale entry before us */ 652153323Srodrigc int *highstalep, /* out: stale entry after us */ 653153323Srodrigc int *lowlogp, /* out: low log index */ 654153323Srodrigc int *highlogp) /* out: high log index */ 655153323Srodrigc{ 656153323Srodrigc int from; /* source copy index */ 657153323Srodrigc int highstale; /* stale entry at/after index */ 658153323Srodrigc int index; /* insertion index */ 659153323Srodrigc int keepstale; /* source index of kept stale */ 660153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 661153323Srodrigc int lowstale; /* stale entry before index */ 662153323Srodrigc int newindex=0; /* new insertion index */ 663153323Srodrigc int to; /* destination copy index */ 664153323Srodrigc 665153323Srodrigc leaf = bp->data; 666159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); 667153323Srodrigc index = *indexp; 668153323Srodrigc /* 669153323Srodrigc * Find the first stale entry before our index, if any. 670153323Srodrigc */ 671153323Srodrigc for (lowstale = index - 1; 672153323Srodrigc lowstale >= 0 && 673159451Srodrigc be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; 674153323Srodrigc lowstale--) 675153323Srodrigc continue; 676153323Srodrigc /* 677153323Srodrigc * Find the first stale entry at or after our index, if any. 678153323Srodrigc * Stop if the answer would be worse than lowstale. 679153323Srodrigc */ 680153323Srodrigc for (highstale = index; 681159451Srodrigc highstale < be16_to_cpu(leaf->hdr.count) && 682159451Srodrigc be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && 683153323Srodrigc (lowstale < 0 || index - lowstale > highstale - index); 684153323Srodrigc highstale++) 685153323Srodrigc continue; 686153323Srodrigc /* 687153323Srodrigc * Pick the better of lowstale and highstale. 688153323Srodrigc */ 689153323Srodrigc if (lowstale >= 0 && 690159451Srodrigc (highstale == be16_to_cpu(leaf->hdr.count) || 691153323Srodrigc index - lowstale <= highstale - index)) 692153323Srodrigc keepstale = lowstale; 693153323Srodrigc else 694153323Srodrigc keepstale = highstale; 695153323Srodrigc /* 696153323Srodrigc * Copy the entries in place, removing all the stale entries 697153323Srodrigc * except keepstale. 698153323Srodrigc */ 699159451Srodrigc for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { 700153323Srodrigc /* 701153323Srodrigc * Notice the new value of index. 702153323Srodrigc */ 703153323Srodrigc if (index == from) 704153323Srodrigc newindex = to; 705153323Srodrigc if (from != keepstale && 706159451Srodrigc be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) { 707153323Srodrigc if (from == to) 708153323Srodrigc *lowlogp = to; 709153323Srodrigc continue; 710153323Srodrigc } 711153323Srodrigc /* 712153323Srodrigc * Record the new keepstale value for the insertion. 713153323Srodrigc */ 714153323Srodrigc if (from == keepstale) 715153323Srodrigc lowstale = highstale = to; 716153323Srodrigc /* 717153323Srodrigc * Copy only the entries that have moved. 718153323Srodrigc */ 719153323Srodrigc if (from > to) 720153323Srodrigc leaf->ents[to] = leaf->ents[from]; 721153323Srodrigc to++; 722153323Srodrigc } 723153323Srodrigc ASSERT(from > to); 724153323Srodrigc /* 725153323Srodrigc * If the insertion point was past the last entry, 726153323Srodrigc * set the new insertion point accordingly. 727153323Srodrigc */ 728153323Srodrigc if (index == from) 729153323Srodrigc newindex = to; 730153323Srodrigc *indexp = newindex; 731153323Srodrigc /* 732153323Srodrigc * Adjust the leaf header values. 733153323Srodrigc */ 734159451Srodrigc be16_add(&leaf->hdr.count, -(from - to)); 735159451Srodrigc leaf->hdr.stale = cpu_to_be16(1); 736153323Srodrigc /* 737153323Srodrigc * Remember the low/high stale value only in the "right" 738153323Srodrigc * direction. 739153323Srodrigc */ 740153323Srodrigc if (lowstale >= newindex) 741153323Srodrigc lowstale = -1; 742153323Srodrigc else 743159451Srodrigc highstale = be16_to_cpu(leaf->hdr.count); 744159451Srodrigc *highlogp = be16_to_cpu(leaf->hdr.count) - 1; 745153323Srodrigc *lowstalep = lowstale; 746153323Srodrigc *highstalep = highstale; 747153323Srodrigc} 748153323Srodrigc 749153323Srodrigc/* 750153323Srodrigc * Getdents (readdir) for leaf and node directories. 751153323Srodrigc * This reads the data blocks only, so is the same for both forms. 752153323Srodrigc */ 753153323Srodrigcint /* error */ 754153323Srodrigcxfs_dir2_leaf_getdents( 755153323Srodrigc xfs_trans_t *tp, /* transaction pointer */ 756153323Srodrigc xfs_inode_t *dp, /* incore directory inode */ 757153323Srodrigc uio_t *uio, /* I/O control & vectors */ 758153323Srodrigc int *eofp, /* out: reached end of dir */ 759153323Srodrigc xfs_dirent_t *dbp, /* caller's buffer */ 760153323Srodrigc xfs_dir2_put_t put) /* ABI formatting routine */ 761153323Srodrigc{ 762153323Srodrigc xfs_dabuf_t *bp; /* data block buffer */ 763153323Srodrigc int byteoff; /* offset in current block */ 764153323Srodrigc xfs_dir2_db_t curdb; /* db for current block */ 765153323Srodrigc xfs_dir2_off_t curoff; /* current overall offset */ 766153323Srodrigc xfs_dir2_data_t *data; /* data block structure */ 767153323Srodrigc xfs_dir2_data_entry_t *dep; /* data entry */ 768153323Srodrigc xfs_dir2_data_unused_t *dup; /* unused entry */ 769153323Srodrigc int eof; /* reached end of directory */ 770159451Srodrigc int error = 0; /* error return value */ 771153323Srodrigc int i; /* temporary loop index */ 772153323Srodrigc int j; /* temporary loop index */ 773153323Srodrigc int length; /* temporary length value */ 774153323Srodrigc xfs_bmbt_irec_t *map; /* map vector for blocks */ 775153323Srodrigc xfs_extlen_t map_blocks; /* number of fsbs in map */ 776153323Srodrigc xfs_dablk_t map_off; /* last mapped file offset */ 777153323Srodrigc int map_size; /* total entries in *map */ 778153323Srodrigc int map_valid; /* valid entries in *map */ 779153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 780153323Srodrigc xfs_dir2_off_t newoff; /* new curoff after new blk */ 781153323Srodrigc int nmap; /* mappings to ask xfs_bmapi */ 782159451Srodrigc xfs_dir2_put_args_t *p; /* formatting arg bundle */ 783159451Srodrigc char *ptr = NULL; /* pointer to current data */ 784153323Srodrigc int ra_current; /* number of read-ahead blks */ 785153323Srodrigc int ra_index; /* *map index for read-ahead */ 786153323Srodrigc int ra_offset; /* map entry offset for ra */ 787153323Srodrigc int ra_want; /* readahead count wanted */ 788153323Srodrigc 789153323Srodrigc /* 790153323Srodrigc * If the offset is at or past the largest allowed value, 791153323Srodrigc * give up right away, return eof. 792153323Srodrigc */ 793153323Srodrigc if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) { 794153323Srodrigc *eofp = 1; 795153323Srodrigc return 0; 796153323Srodrigc } 797153323Srodrigc mp = dp->i_mount; 798153323Srodrigc /* 799153323Srodrigc * Setup formatting arguments. 800153323Srodrigc */ 801159451Srodrigc p = kmem_alloc(sizeof(*p), KM_SLEEP); 802159451Srodrigc p->dbp = dbp; 803159451Srodrigc p->put = put; 804159451Srodrigc p->uio = uio; 805153323Srodrigc /* 806153323Srodrigc * Set up to bmap a number of blocks based on the caller's 807153323Srodrigc * buffer size, the directory block size, and the filesystem 808153323Srodrigc * block size. 809153323Srodrigc */ 810153323Srodrigc map_size = 811153323Srodrigc howmany(uio->uio_resid + mp->m_dirblksize, 812153323Srodrigc mp->m_sb.sb_blocksize); 813153323Srodrigc map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); 814153323Srodrigc map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; 815153323Srodrigc bp = NULL; 816153323Srodrigc eof = 1; 817153323Srodrigc /* 818153323Srodrigc * Inside the loop we keep the main offset value as a byte offset 819153323Srodrigc * in the directory file. 820153323Srodrigc */ 821153323Srodrigc curoff = XFS_DIR2_DATAPTR_TO_BYTE(mp, uio->uio_offset); 822153323Srodrigc /* 823153323Srodrigc * Force this conversion through db so we truncate the offset 824153323Srodrigc * down to get the start of the data block. 825153323Srodrigc */ 826153323Srodrigc map_off = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, curoff)); 827153323Srodrigc /* 828153323Srodrigc * Loop over directory entries until we reach the end offset. 829153323Srodrigc * Get more blocks and readahead as necessary. 830153323Srodrigc */ 831153323Srodrigc while (curoff < XFS_DIR2_LEAF_OFFSET) { 832153323Srodrigc /* 833153323Srodrigc * If we have no buffer, or we're off the end of the 834153323Srodrigc * current buffer, need to get another one. 835153323Srodrigc */ 836153323Srodrigc if (!bp || ptr >= (char *)bp->data + mp->m_dirblksize) { 837153323Srodrigc /* 838153323Srodrigc * If we have a buffer, we need to release it and 839153323Srodrigc * take it out of the mapping. 840153323Srodrigc */ 841153323Srodrigc if (bp) { 842153323Srodrigc xfs_da_brelse(tp, bp); 843153323Srodrigc bp = NULL; 844153323Srodrigc map_blocks -= mp->m_dirblkfsbs; 845153323Srodrigc /* 846153323Srodrigc * Loop to get rid of the extents for the 847153323Srodrigc * directory block. 848153323Srodrigc */ 849153323Srodrigc for (i = mp->m_dirblkfsbs; i > 0; ) { 850153323Srodrigc j = MIN((int)map->br_blockcount, i); 851153323Srodrigc map->br_blockcount -= j; 852153323Srodrigc map->br_startblock += j; 853153323Srodrigc map->br_startoff += j; 854153323Srodrigc /* 855153323Srodrigc * If mapping is done, pitch it from 856153323Srodrigc * the table. 857153323Srodrigc */ 858153323Srodrigc if (!map->br_blockcount && --map_valid) 859153323Srodrigc memmove(&map[0], &map[1], 860153323Srodrigc sizeof(map[0]) * 861153323Srodrigc map_valid); 862153323Srodrigc i -= j; 863153323Srodrigc } 864153323Srodrigc } 865153323Srodrigc /* 866153323Srodrigc * Recalculate the readahead blocks wanted. 867153323Srodrigc */ 868153323Srodrigc ra_want = howmany(uio->uio_resid + mp->m_dirblksize, 869153323Srodrigc mp->m_sb.sb_blocksize) - 1; 870153323Srodrigc /* 871153323Srodrigc * If we don't have as many as we want, and we haven't 872153323Srodrigc * run out of data blocks, get some more mappings. 873153323Srodrigc */ 874153323Srodrigc if (1 + ra_want > map_blocks && 875153323Srodrigc map_off < 876153323Srodrigc XFS_DIR2_BYTE_TO_DA(mp, XFS_DIR2_LEAF_OFFSET)) { 877153323Srodrigc /* 878153323Srodrigc * Get more bmaps, fill in after the ones 879153323Srodrigc * we already have in the table. 880153323Srodrigc */ 881153323Srodrigc nmap = map_size - map_valid; 882153323Srodrigc error = xfs_bmapi(tp, dp, 883153323Srodrigc map_off, 884153323Srodrigc XFS_DIR2_BYTE_TO_DA(mp, 885153323Srodrigc XFS_DIR2_LEAF_OFFSET) - map_off, 886153323Srodrigc XFS_BMAPI_METADATA, NULL, 0, 887159451Srodrigc &map[map_valid], &nmap, NULL, NULL); 888153323Srodrigc /* 889153323Srodrigc * Don't know if we should ignore this or 890153323Srodrigc * try to return an error. 891153323Srodrigc * The trouble with returning errors 892153323Srodrigc * is that readdir will just stop without 893153323Srodrigc * actually passing the error through. 894153323Srodrigc */ 895153323Srodrigc if (error) 896153323Srodrigc break; /* XXX */ 897153323Srodrigc /* 898153323Srodrigc * If we got all the mappings we asked for, 899153323Srodrigc * set the final map offset based on the 900153323Srodrigc * last bmap value received. 901153323Srodrigc * Otherwise, we've reached the end. 902153323Srodrigc */ 903153323Srodrigc if (nmap == map_size - map_valid) 904153323Srodrigc map_off = 905153323Srodrigc map[map_valid + nmap - 1].br_startoff + 906153323Srodrigc map[map_valid + nmap - 1].br_blockcount; 907153323Srodrigc else 908153323Srodrigc map_off = 909153323Srodrigc XFS_DIR2_BYTE_TO_DA(mp, 910153323Srodrigc XFS_DIR2_LEAF_OFFSET); 911153323Srodrigc /* 912153323Srodrigc * Look for holes in the mapping, and 913153323Srodrigc * eliminate them. Count up the valid blocks. 914153323Srodrigc */ 915153323Srodrigc for (i = map_valid; i < map_valid + nmap; ) { 916153323Srodrigc if (map[i].br_startblock == 917153323Srodrigc HOLESTARTBLOCK) { 918153323Srodrigc nmap--; 919153323Srodrigc length = map_valid + nmap - i; 920153323Srodrigc if (length) 921153323Srodrigc memmove(&map[i], 922153323Srodrigc &map[i + 1], 923153323Srodrigc sizeof(map[i]) * 924153323Srodrigc length); 925153323Srodrigc } else { 926153323Srodrigc map_blocks += 927153323Srodrigc map[i].br_blockcount; 928153323Srodrigc i++; 929153323Srodrigc } 930153323Srodrigc } 931153323Srodrigc map_valid += nmap; 932153323Srodrigc } 933153323Srodrigc /* 934153323Srodrigc * No valid mappings, so no more data blocks. 935153323Srodrigc */ 936153323Srodrigc if (!map_valid) { 937153323Srodrigc curoff = XFS_DIR2_DA_TO_BYTE(mp, map_off); 938153323Srodrigc break; 939153323Srodrigc } 940153323Srodrigc /* 941153323Srodrigc * Read the directory block starting at the first 942153323Srodrigc * mapping. 943153323Srodrigc */ 944153323Srodrigc curdb = XFS_DIR2_DA_TO_DB(mp, map->br_startoff); 945153323Srodrigc error = xfs_da_read_buf(tp, dp, map->br_startoff, 946153323Srodrigc map->br_blockcount >= mp->m_dirblkfsbs ? 947153323Srodrigc XFS_FSB_TO_DADDR(mp, map->br_startblock) : 948153323Srodrigc -1, 949153323Srodrigc &bp, XFS_DATA_FORK); 950153323Srodrigc /* 951153323Srodrigc * Should just skip over the data block instead 952153323Srodrigc * of giving up. 953153323Srodrigc */ 954153323Srodrigc if (error) 955153323Srodrigc break; /* XXX */ 956153323Srodrigc /* 957153323Srodrigc * Adjust the current amount of read-ahead: we just 958153323Srodrigc * read a block that was previously ra. 959153323Srodrigc */ 960153323Srodrigc if (ra_current) 961153323Srodrigc ra_current -= mp->m_dirblkfsbs; 962153323Srodrigc /* 963153323Srodrigc * Do we need more readahead? 964153323Srodrigc */ 965153323Srodrigc for (ra_index = ra_offset = i = 0; 966153323Srodrigc ra_want > ra_current && i < map_blocks; 967153323Srodrigc i += mp->m_dirblkfsbs) { 968153323Srodrigc ASSERT(ra_index < map_valid); 969153323Srodrigc /* 970153323Srodrigc * Read-ahead a contiguous directory block. 971153323Srodrigc */ 972153323Srodrigc if (i > ra_current && 973153323Srodrigc map[ra_index].br_blockcount >= 974153323Srodrigc mp->m_dirblkfsbs) { 975153323Srodrigc xfs_baread(mp->m_ddev_targp, 976153323Srodrigc XFS_FSB_TO_DADDR(mp, 977153323Srodrigc map[ra_index].br_startblock + 978153323Srodrigc ra_offset), 979153323Srodrigc (int)BTOBB(mp->m_dirblksize)); 980153323Srodrigc ra_current = i; 981153323Srodrigc } 982153323Srodrigc /* 983153323Srodrigc * Read-ahead a non-contiguous directory block. 984153323Srodrigc * This doesn't use our mapping, but this 985153323Srodrigc * is a very rare case. 986153323Srodrigc */ 987153323Srodrigc else if (i > ra_current) { 988153323Srodrigc (void)xfs_da_reada_buf(tp, dp, 989153323Srodrigc map[ra_index].br_startoff + 990153323Srodrigc ra_offset, XFS_DATA_FORK); 991153323Srodrigc ra_current = i; 992153323Srodrigc } 993153323Srodrigc /* 994153323Srodrigc * Advance offset through the mapping table. 995153323Srodrigc */ 996153323Srodrigc for (j = 0; j < mp->m_dirblkfsbs; j++) { 997153323Srodrigc /* 998153323Srodrigc * The rest of this extent but not 999153323Srodrigc * more than a dir block. 1000153323Srodrigc */ 1001153323Srodrigc length = MIN(mp->m_dirblkfsbs, 1002153323Srodrigc (int)(map[ra_index].br_blockcount - 1003153323Srodrigc ra_offset)); 1004153323Srodrigc j += length; 1005153323Srodrigc ra_offset += length; 1006153323Srodrigc /* 1007153323Srodrigc * Advance to the next mapping if 1008153323Srodrigc * this one is used up. 1009153323Srodrigc */ 1010153323Srodrigc if (ra_offset == 1011153323Srodrigc map[ra_index].br_blockcount) { 1012153323Srodrigc ra_offset = 0; 1013153323Srodrigc ra_index++; 1014153323Srodrigc } 1015153323Srodrigc } 1016153323Srodrigc } 1017153323Srodrigc /* 1018153323Srodrigc * Having done a read, we need to set a new offset. 1019153323Srodrigc */ 1020153323Srodrigc newoff = XFS_DIR2_DB_OFF_TO_BYTE(mp, curdb, 0); 1021153323Srodrigc /* 1022153323Srodrigc * Start of the current block. 1023153323Srodrigc */ 1024153323Srodrigc if (curoff < newoff) 1025153323Srodrigc curoff = newoff; 1026153323Srodrigc /* 1027153323Srodrigc * Make sure we're in the right block. 1028153323Srodrigc */ 1029153323Srodrigc else if (curoff > newoff) 1030153323Srodrigc ASSERT(XFS_DIR2_BYTE_TO_DB(mp, curoff) == 1031153323Srodrigc curdb); 1032153323Srodrigc data = bp->data; 1033153323Srodrigc xfs_dir2_data_check(dp, bp); 1034153323Srodrigc /* 1035153323Srodrigc * Find our position in the block. 1036153323Srodrigc */ 1037153323Srodrigc ptr = (char *)&data->u; 1038153323Srodrigc byteoff = XFS_DIR2_BYTE_TO_OFF(mp, curoff); 1039153323Srodrigc /* 1040153323Srodrigc * Skip past the header. 1041153323Srodrigc */ 1042153323Srodrigc if (byteoff == 0) 1043153323Srodrigc curoff += (uint)sizeof(data->hdr); 1044153323Srodrigc /* 1045153323Srodrigc * Skip past entries until we reach our offset. 1046153323Srodrigc */ 1047153323Srodrigc else { 1048153323Srodrigc while ((char *)ptr - (char *)data < byteoff) { 1049153323Srodrigc dup = (xfs_dir2_data_unused_t *)ptr; 1050153323Srodrigc 1051159451Srodrigc if (be16_to_cpu(dup->freetag) 1052153323Srodrigc == XFS_DIR2_DATA_FREE_TAG) { 1053153323Srodrigc 1054159451Srodrigc length = be16_to_cpu(dup->length); 1055153323Srodrigc ptr += length; 1056153323Srodrigc continue; 1057153323Srodrigc } 1058153323Srodrigc dep = (xfs_dir2_data_entry_t *)ptr; 1059153323Srodrigc length = 1060153323Srodrigc XFS_DIR2_DATA_ENTSIZE(dep->namelen); 1061153323Srodrigc ptr += length; 1062153323Srodrigc } 1063153323Srodrigc /* 1064153323Srodrigc * Now set our real offset. 1065153323Srodrigc */ 1066153323Srodrigc curoff = 1067153323Srodrigc XFS_DIR2_DB_OFF_TO_BYTE(mp, 1068153323Srodrigc XFS_DIR2_BYTE_TO_DB(mp, curoff), 1069153323Srodrigc (char *)ptr - (char *)data); 1070153323Srodrigc if (ptr >= (char *)data + mp->m_dirblksize) { 1071153323Srodrigc continue; 1072153323Srodrigc } 1073153323Srodrigc } 1074153323Srodrigc } 1075153323Srodrigc /* 1076153323Srodrigc * We have a pointer to an entry. 1077153323Srodrigc * Is it a live one? 1078153323Srodrigc */ 1079153323Srodrigc dup = (xfs_dir2_data_unused_t *)ptr; 1080153323Srodrigc /* 1081153323Srodrigc * No, it's unused, skip over it. 1082153323Srodrigc */ 1083159451Srodrigc if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 1084159451Srodrigc length = be16_to_cpu(dup->length); 1085153323Srodrigc ptr += length; 1086153323Srodrigc curoff += length; 1087153323Srodrigc continue; 1088153323Srodrigc } 1089153323Srodrigc 1090153323Srodrigc /* 1091153323Srodrigc * Copy the entry into the putargs, and try formatting it. 1092153323Srodrigc */ 1093153323Srodrigc dep = (xfs_dir2_data_entry_t *)ptr; 1094153323Srodrigc 1095159451Srodrigc p->namelen = dep->namelen; 1096153323Srodrigc 1097159451Srodrigc length = XFS_DIR2_DATA_ENTSIZE(p->namelen); 1098153323Srodrigc 1099159451Srodrigc p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); 1100153323Srodrigc 1101159451Srodrigc p->ino = INT_GET(dep->inumber, ARCH_CONVERT); 1102153323Srodrigc#if XFS_BIG_INUMS 1103159451Srodrigc p->ino += mp->m_inoadd; 1104153323Srodrigc#endif 1105159451Srodrigc p->name = (char *)dep->name; 1106153323Srodrigc 1107159451Srodrigc error = p->put(p); 1108153323Srodrigc 1109153323Srodrigc /* 1110153323Srodrigc * Won't fit. Return to caller. 1111153323Srodrigc */ 1112159451Srodrigc if (!p->done) { 1113153323Srodrigc eof = 0; 1114153323Srodrigc break; 1115153323Srodrigc } 1116153323Srodrigc /* 1117153323Srodrigc * Advance to next entry in the block. 1118153323Srodrigc */ 1119153323Srodrigc ptr += length; 1120153323Srodrigc curoff += length; 1121153323Srodrigc } 1122153323Srodrigc 1123153323Srodrigc /* 1124153323Srodrigc * All done. Set output offset value to current offset. 1125153323Srodrigc */ 1126153323Srodrigc *eofp = eof; 1127153323Srodrigc if (curoff > XFS_DIR2_DATAPTR_TO_BYTE(mp, XFS_DIR2_MAX_DATAPTR)) 1128153323Srodrigc uio->uio_offset = XFS_DIR2_MAX_DATAPTR; 1129153323Srodrigc else 1130153323Srodrigc uio->uio_offset = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff); 1131153323Srodrigc kmem_free(map, map_size * sizeof(*map)); 1132159451Srodrigc kmem_free(p, sizeof(*p)); 1133153323Srodrigc if (bp) 1134153323Srodrigc xfs_da_brelse(tp, bp); 1135153323Srodrigc return error; 1136153323Srodrigc} 1137153323Srodrigc 1138153323Srodrigc/* 1139153323Srodrigc * Initialize a new leaf block, leaf1 or leafn magic accepted. 1140153323Srodrigc */ 1141153323Srodrigcint 1142153323Srodrigcxfs_dir2_leaf_init( 1143153323Srodrigc xfs_da_args_t *args, /* operation arguments */ 1144153323Srodrigc xfs_dir2_db_t bno, /* directory block number */ 1145153323Srodrigc xfs_dabuf_t **bpp, /* out: leaf buffer */ 1146153323Srodrigc int magic) /* magic number for block */ 1147153323Srodrigc{ 1148153323Srodrigc xfs_dabuf_t *bp; /* leaf buffer */ 1149153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1150153323Srodrigc int error; /* error return code */ 1151153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1152153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1153153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 1154153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1155153323Srodrigc 1156153323Srodrigc dp = args->dp; 1157153323Srodrigc ASSERT(dp != NULL); 1158153323Srodrigc tp = args->trans; 1159153323Srodrigc mp = dp->i_mount; 1160153323Srodrigc ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && 1161153323Srodrigc bno < XFS_DIR2_FREE_FIRSTDB(mp)); 1162153323Srodrigc /* 1163153323Srodrigc * Get the buffer for the block. 1164153323Srodrigc */ 1165153323Srodrigc error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp, 1166153323Srodrigc XFS_DATA_FORK); 1167153323Srodrigc if (error) { 1168153323Srodrigc return error; 1169153323Srodrigc } 1170153323Srodrigc ASSERT(bp != NULL); 1171153323Srodrigc leaf = bp->data; 1172153323Srodrigc /* 1173153323Srodrigc * Initialize the header. 1174153323Srodrigc */ 1175159451Srodrigc leaf->hdr.info.magic = cpu_to_be16(magic); 1176159451Srodrigc leaf->hdr.info.forw = 0; 1177159451Srodrigc leaf->hdr.info.back = 0; 1178159451Srodrigc leaf->hdr.count = 0; 1179159451Srodrigc leaf->hdr.stale = 0; 1180153323Srodrigc xfs_dir2_leaf_log_header(tp, bp); 1181153323Srodrigc /* 1182153323Srodrigc * If it's a leaf-format directory initialize the tail. 1183153323Srodrigc * In this case our caller has the real bests table to copy into 1184153323Srodrigc * the block. 1185153323Srodrigc */ 1186153323Srodrigc if (magic == XFS_DIR2_LEAF1_MAGIC) { 1187153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1188159451Srodrigc ltp->bestcount = 0; 1189153323Srodrigc xfs_dir2_leaf_log_tail(tp, bp); 1190153323Srodrigc } 1191153323Srodrigc *bpp = bp; 1192153323Srodrigc return 0; 1193153323Srodrigc} 1194153323Srodrigc 1195153323Srodrigc/* 1196153323Srodrigc * Log the bests entries indicated from a leaf1 block. 1197153323Srodrigc */ 1198159451Srodrigcstatic void 1199153323Srodrigcxfs_dir2_leaf_log_bests( 1200153323Srodrigc xfs_trans_t *tp, /* transaction pointer */ 1201153323Srodrigc xfs_dabuf_t *bp, /* leaf buffer */ 1202153323Srodrigc int first, /* first entry to log */ 1203153323Srodrigc int last) /* last entry to log */ 1204153323Srodrigc{ 1205159451Srodrigc __be16 *firstb; /* pointer to first entry */ 1206159451Srodrigc __be16 *lastb; /* pointer to last entry */ 1207153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1208153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1209153323Srodrigc 1210153323Srodrigc leaf = bp->data; 1211159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 1212153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf); 1213159451Srodrigc firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first; 1214159451Srodrigc lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last; 1215153323Srodrigc xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), 1216153323Srodrigc (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); 1217153323Srodrigc} 1218153323Srodrigc 1219153323Srodrigc/* 1220153323Srodrigc * Log the leaf entries indicated from a leaf1 or leafn block. 1221153323Srodrigc */ 1222153323Srodrigcvoid 1223153323Srodrigcxfs_dir2_leaf_log_ents( 1224153323Srodrigc xfs_trans_t *tp, /* transaction pointer */ 1225153323Srodrigc xfs_dabuf_t *bp, /* leaf buffer */ 1226153323Srodrigc int first, /* first entry to log */ 1227153323Srodrigc int last) /* last entry to log */ 1228153323Srodrigc{ 1229153323Srodrigc xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ 1230153323Srodrigc xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ 1231153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1232153323Srodrigc 1233153323Srodrigc leaf = bp->data; 1234159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || 1235159451Srodrigc be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1236153323Srodrigc firstlep = &leaf->ents[first]; 1237153323Srodrigc lastlep = &leaf->ents[last]; 1238153323Srodrigc xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), 1239153323Srodrigc (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); 1240153323Srodrigc} 1241153323Srodrigc 1242153323Srodrigc/* 1243153323Srodrigc * Log the header of the leaf1 or leafn block. 1244153323Srodrigc */ 1245153323Srodrigcvoid 1246153323Srodrigcxfs_dir2_leaf_log_header( 1247153323Srodrigc xfs_trans_t *tp, /* transaction pointer */ 1248153323Srodrigc xfs_dabuf_t *bp) /* leaf buffer */ 1249153323Srodrigc{ 1250153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1251153323Srodrigc 1252153323Srodrigc leaf = bp->data; 1253159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || 1254159451Srodrigc be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1255153323Srodrigc xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), 1256153323Srodrigc (uint)(sizeof(leaf->hdr) - 1)); 1257153323Srodrigc} 1258153323Srodrigc 1259153323Srodrigc/* 1260153323Srodrigc * Log the tail of the leaf1 block. 1261153323Srodrigc */ 1262159451SrodrigcSTATIC void 1263153323Srodrigcxfs_dir2_leaf_log_tail( 1264153323Srodrigc xfs_trans_t *tp, /* transaction pointer */ 1265153323Srodrigc xfs_dabuf_t *bp) /* leaf buffer */ 1266153323Srodrigc{ 1267153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1268153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1269153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 1270153323Srodrigc 1271153323Srodrigc mp = tp->t_mountp; 1272153323Srodrigc leaf = bp->data; 1273159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 1274153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1275153323Srodrigc xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), 1276153323Srodrigc (uint)(mp->m_dirblksize - 1)); 1277153323Srodrigc} 1278153323Srodrigc 1279153323Srodrigc/* 1280153323Srodrigc * Look up the entry referred to by args in the leaf format directory. 1281153323Srodrigc * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which 1282153323Srodrigc * is also used by the node-format code. 1283153323Srodrigc */ 1284153323Srodrigcint 1285153323Srodrigcxfs_dir2_leaf_lookup( 1286153323Srodrigc xfs_da_args_t *args) /* operation arguments */ 1287153323Srodrigc{ 1288153323Srodrigc xfs_dabuf_t *dbp; /* data block buffer */ 1289153323Srodrigc xfs_dir2_data_entry_t *dep; /* data block entry */ 1290153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1291153323Srodrigc int error; /* error return code */ 1292153323Srodrigc int index; /* found entry index */ 1293153323Srodrigc xfs_dabuf_t *lbp; /* leaf buffer */ 1294153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1295153323Srodrigc xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1296153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1297153323Srodrigc 1298153323Srodrigc xfs_dir2_trace_args("leaf_lookup", args); 1299153323Srodrigc /* 1300153323Srodrigc * Look up name in the leaf block, returning both buffers and index. 1301153323Srodrigc */ 1302153323Srodrigc if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1303153323Srodrigc return error; 1304153323Srodrigc } 1305153323Srodrigc tp = args->trans; 1306153323Srodrigc dp = args->dp; 1307153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 1308153323Srodrigc leaf = lbp->data; 1309153323Srodrigc /* 1310153323Srodrigc * Get to the leaf entry and contained data entry address. 1311153323Srodrigc */ 1312153323Srodrigc lep = &leaf->ents[index]; 1313153323Srodrigc /* 1314153323Srodrigc * Point to the data entry. 1315153323Srodrigc */ 1316153323Srodrigc dep = (xfs_dir2_data_entry_t *) 1317153323Srodrigc ((char *)dbp->data + 1318159451Srodrigc XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); 1319153323Srodrigc /* 1320153323Srodrigc * Return the found inode number. 1321153323Srodrigc */ 1322153323Srodrigc args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 1323153323Srodrigc xfs_da_brelse(tp, dbp); 1324153323Srodrigc xfs_da_brelse(tp, lbp); 1325153323Srodrigc return XFS_ERROR(EEXIST); 1326153323Srodrigc} 1327153323Srodrigc 1328153323Srodrigc/* 1329153323Srodrigc * Look up name/hash in the leaf block. 1330153323Srodrigc * Fill in indexp with the found index, and dbpp with the data buffer. 1331153323Srodrigc * If not found dbpp will be NULL, and ENOENT comes back. 1332153323Srodrigc * lbpp will always be filled in with the leaf buffer unless there's an error. 1333153323Srodrigc */ 1334153323Srodrigcstatic int /* error */ 1335153323Srodrigcxfs_dir2_leaf_lookup_int( 1336153323Srodrigc xfs_da_args_t *args, /* operation arguments */ 1337153323Srodrigc xfs_dabuf_t **lbpp, /* out: leaf buffer */ 1338153323Srodrigc int *indexp, /* out: index in leaf block */ 1339153323Srodrigc xfs_dabuf_t **dbpp) /* out: data buffer */ 1340153323Srodrigc{ 1341153323Srodrigc xfs_dir2_db_t curdb; /* current data block number */ 1342153323Srodrigc xfs_dabuf_t *dbp; /* data buffer */ 1343153323Srodrigc xfs_dir2_data_entry_t *dep; /* data entry */ 1344153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1345153323Srodrigc int error; /* error return code */ 1346153323Srodrigc int index; /* index in leaf block */ 1347153323Srodrigc xfs_dabuf_t *lbp; /* leaf buffer */ 1348153323Srodrigc xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1349153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1350153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 1351153323Srodrigc xfs_dir2_db_t newdb; /* new data block number */ 1352153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1353153323Srodrigc 1354153323Srodrigc dp = args->dp; 1355153323Srodrigc tp = args->trans; 1356153323Srodrigc mp = dp->i_mount; 1357153323Srodrigc /* 1358153323Srodrigc * Read the leaf block into the buffer. 1359153323Srodrigc */ 1360153323Srodrigc if ((error = 1361153323Srodrigc xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, 1362153323Srodrigc XFS_DATA_FORK))) { 1363153323Srodrigc return error; 1364153323Srodrigc } 1365153323Srodrigc *lbpp = lbp; 1366153323Srodrigc leaf = lbp->data; 1367153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 1368153323Srodrigc /* 1369153323Srodrigc * Look for the first leaf entry with our hash value. 1370153323Srodrigc */ 1371153323Srodrigc index = xfs_dir2_leaf_search_hash(args, lbp); 1372153323Srodrigc /* 1373153323Srodrigc * Loop over all the entries with the right hash value 1374153323Srodrigc * looking to match the name. 1375153323Srodrigc */ 1376153323Srodrigc for (lep = &leaf->ents[index], dbp = NULL, curdb = -1; 1377159451Srodrigc index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; 1378153323Srodrigc lep++, index++) { 1379153323Srodrigc /* 1380153323Srodrigc * Skip over stale leaf entries. 1381153323Srodrigc */ 1382159451Srodrigc if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 1383153323Srodrigc continue; 1384153323Srodrigc /* 1385153323Srodrigc * Get the new data block number. 1386153323Srodrigc */ 1387159451Srodrigc newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); 1388153323Srodrigc /* 1389153323Srodrigc * If it's not the same as the old data block number, 1390153323Srodrigc * need to pitch the old one and read the new one. 1391153323Srodrigc */ 1392153323Srodrigc if (newdb != curdb) { 1393153323Srodrigc if (dbp) 1394153323Srodrigc xfs_da_brelse(tp, dbp); 1395153323Srodrigc if ((error = 1396153323Srodrigc xfs_da_read_buf(tp, dp, 1397153323Srodrigc XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp, 1398153323Srodrigc XFS_DATA_FORK))) { 1399153323Srodrigc xfs_da_brelse(tp, lbp); 1400153323Srodrigc return error; 1401153323Srodrigc } 1402153323Srodrigc xfs_dir2_data_check(dp, dbp); 1403153323Srodrigc curdb = newdb; 1404153323Srodrigc } 1405153323Srodrigc /* 1406153323Srodrigc * Point to the data entry. 1407153323Srodrigc */ 1408153323Srodrigc dep = (xfs_dir2_data_entry_t *) 1409153323Srodrigc ((char *)dbp->data + 1410159451Srodrigc XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address))); 1411153323Srodrigc /* 1412153323Srodrigc * If it matches then return it. 1413153323Srodrigc */ 1414153323Srodrigc if (dep->namelen == args->namelen && 1415153323Srodrigc dep->name[0] == args->name[0] && 1416153323Srodrigc memcmp(dep->name, args->name, args->namelen) == 0) { 1417153323Srodrigc *dbpp = dbp; 1418153323Srodrigc *indexp = index; 1419153323Srodrigc return 0; 1420153323Srodrigc } 1421153323Srodrigc } 1422153323Srodrigc /* 1423153323Srodrigc * No match found, return ENOENT. 1424153323Srodrigc */ 1425153323Srodrigc ASSERT(args->oknoent); 1426153323Srodrigc if (dbp) 1427153323Srodrigc xfs_da_brelse(tp, dbp); 1428153323Srodrigc xfs_da_brelse(tp, lbp); 1429153323Srodrigc return XFS_ERROR(ENOENT); 1430153323Srodrigc} 1431153323Srodrigc 1432153323Srodrigc/* 1433153323Srodrigc * Remove an entry from a leaf format directory. 1434153323Srodrigc */ 1435153323Srodrigcint /* error */ 1436153323Srodrigcxfs_dir2_leaf_removename( 1437153323Srodrigc xfs_da_args_t *args) /* operation arguments */ 1438153323Srodrigc{ 1439159451Srodrigc __be16 *bestsp; /* leaf block best freespace */ 1440153323Srodrigc xfs_dir2_data_t *data; /* data block structure */ 1441153323Srodrigc xfs_dir2_db_t db; /* data block number */ 1442153323Srodrigc xfs_dabuf_t *dbp; /* data block buffer */ 1443153323Srodrigc xfs_dir2_data_entry_t *dep; /* data entry structure */ 1444153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1445153323Srodrigc int error; /* error return code */ 1446153323Srodrigc xfs_dir2_db_t i; /* temporary data block # */ 1447153323Srodrigc int index; /* index into leaf entries */ 1448153323Srodrigc xfs_dabuf_t *lbp; /* leaf buffer */ 1449153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1450153323Srodrigc xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1451153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1452153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 1453153323Srodrigc int needlog; /* need to log data header */ 1454153323Srodrigc int needscan; /* need to rescan data frees */ 1455153323Srodrigc xfs_dir2_data_off_t oldbest; /* old value of best free */ 1456153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1457153323Srodrigc 1458153323Srodrigc xfs_dir2_trace_args("leaf_removename", args); 1459153323Srodrigc /* 1460153323Srodrigc * Lookup the leaf entry, get the leaf and data blocks read in. 1461153323Srodrigc */ 1462153323Srodrigc if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1463153323Srodrigc return error; 1464153323Srodrigc } 1465153323Srodrigc dp = args->dp; 1466153323Srodrigc tp = args->trans; 1467153323Srodrigc mp = dp->i_mount; 1468153323Srodrigc leaf = lbp->data; 1469153323Srodrigc data = dbp->data; 1470153323Srodrigc xfs_dir2_data_check(dp, dbp); 1471153323Srodrigc /* 1472153323Srodrigc * Point to the leaf entry, use that to point to the data entry. 1473153323Srodrigc */ 1474153323Srodrigc lep = &leaf->ents[index]; 1475159451Srodrigc db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); 1476153323Srodrigc dep = (xfs_dir2_data_entry_t *) 1477159451Srodrigc ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address))); 1478153323Srodrigc needscan = needlog = 0; 1479159451Srodrigc oldbest = be16_to_cpu(data->hdr.bestfree[0].length); 1480153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1481159451Srodrigc bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 1482159451Srodrigc ASSERT(be16_to_cpu(bestsp[db]) == oldbest); 1483153323Srodrigc /* 1484153323Srodrigc * Mark the former data entry unused. 1485153323Srodrigc */ 1486153323Srodrigc xfs_dir2_data_make_free(tp, dbp, 1487153323Srodrigc (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), 1488153323Srodrigc XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); 1489153323Srodrigc /* 1490153323Srodrigc * We just mark the leaf entry stale by putting a null in it. 1491153323Srodrigc */ 1492159451Srodrigc be16_add(&leaf->hdr.stale, 1); 1493153323Srodrigc xfs_dir2_leaf_log_header(tp, lbp); 1494159451Srodrigc lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1495153323Srodrigc xfs_dir2_leaf_log_ents(tp, lbp, index, index); 1496153323Srodrigc /* 1497153323Srodrigc * Scan the freespace in the data block again if necessary, 1498153323Srodrigc * log the data block header if necessary. 1499153323Srodrigc */ 1500153323Srodrigc if (needscan) 1501153323Srodrigc xfs_dir2_data_freescan(mp, data, &needlog, NULL); 1502153323Srodrigc if (needlog) 1503153323Srodrigc xfs_dir2_data_log_header(tp, dbp); 1504153323Srodrigc /* 1505153323Srodrigc * If the longest freespace in the data block has changed, 1506153323Srodrigc * put the new value in the bests table and log that. 1507153323Srodrigc */ 1508159451Srodrigc if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) { 1509159451Srodrigc bestsp[db] = data->hdr.bestfree[0].length; 1510153323Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, db, db); 1511153323Srodrigc } 1512153323Srodrigc xfs_dir2_data_check(dp, dbp); 1513153323Srodrigc /* 1514153323Srodrigc * If the data block is now empty then get rid of the data block. 1515153323Srodrigc */ 1516159451Srodrigc if (be16_to_cpu(data->hdr.bestfree[0].length) == 1517153323Srodrigc mp->m_dirblksize - (uint)sizeof(data->hdr)) { 1518153323Srodrigc ASSERT(db != mp->m_dirdatablk); 1519153323Srodrigc if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1520153323Srodrigc /* 1521153323Srodrigc * Nope, can't get rid of it because it caused 1522153323Srodrigc * allocation of a bmap btree block to do so. 1523153323Srodrigc * Just go on, returning success, leaving the 1524153323Srodrigc * empty block in place. 1525153323Srodrigc */ 1526153323Srodrigc if (error == ENOSPC && args->total == 0) { 1527153323Srodrigc xfs_da_buf_done(dbp); 1528153323Srodrigc error = 0; 1529153323Srodrigc } 1530153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 1531153323Srodrigc xfs_da_buf_done(lbp); 1532153323Srodrigc return error; 1533153323Srodrigc } 1534153323Srodrigc dbp = NULL; 1535153323Srodrigc /* 1536153323Srodrigc * If this is the last data block then compact the 1537153323Srodrigc * bests table by getting rid of entries. 1538153323Srodrigc */ 1539159451Srodrigc if (db == be32_to_cpu(ltp->bestcount) - 1) { 1540153323Srodrigc /* 1541153323Srodrigc * Look for the last active entry (i). 1542153323Srodrigc */ 1543153323Srodrigc for (i = db - 1; i > 0; i--) { 1544159451Srodrigc if (be16_to_cpu(bestsp[i]) != NULLDATAOFF) 1545153323Srodrigc break; 1546153323Srodrigc } 1547153323Srodrigc /* 1548153323Srodrigc * Copy the table down so inactive entries at the 1549153323Srodrigc * end are removed. 1550153323Srodrigc */ 1551153323Srodrigc memmove(&bestsp[db - i], bestsp, 1552159451Srodrigc (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); 1553159451Srodrigc be32_add(<p->bestcount, -(db - i)); 1554153323Srodrigc xfs_dir2_leaf_log_tail(tp, lbp); 1555159451Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1556153323Srodrigc } else 1557159451Srodrigc bestsp[db] = cpu_to_be16(NULLDATAOFF); 1558153323Srodrigc } 1559153323Srodrigc /* 1560153323Srodrigc * If the data block was not the first one, drop it. 1561153323Srodrigc */ 1562153323Srodrigc else if (db != mp->m_dirdatablk && dbp != NULL) { 1563153323Srodrigc xfs_da_buf_done(dbp); 1564153323Srodrigc dbp = NULL; 1565153323Srodrigc } 1566153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 1567153323Srodrigc /* 1568153323Srodrigc * See if we can convert to block form. 1569153323Srodrigc */ 1570153323Srodrigc return xfs_dir2_leaf_to_block(args, lbp, dbp); 1571153323Srodrigc} 1572153323Srodrigc 1573153323Srodrigc/* 1574153323Srodrigc * Replace the inode number in a leaf format directory entry. 1575153323Srodrigc */ 1576153323Srodrigcint /* error */ 1577153323Srodrigcxfs_dir2_leaf_replace( 1578153323Srodrigc xfs_da_args_t *args) /* operation arguments */ 1579153323Srodrigc{ 1580153323Srodrigc xfs_dabuf_t *dbp; /* data block buffer */ 1581153323Srodrigc xfs_dir2_data_entry_t *dep; /* data block entry */ 1582153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1583153323Srodrigc int error; /* error return code */ 1584153323Srodrigc int index; /* index of leaf entry */ 1585153323Srodrigc xfs_dabuf_t *lbp; /* leaf buffer */ 1586153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1587153323Srodrigc xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1588153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1589153323Srodrigc 1590153323Srodrigc xfs_dir2_trace_args("leaf_replace", args); 1591153323Srodrigc /* 1592153323Srodrigc * Look up the entry. 1593153323Srodrigc */ 1594153323Srodrigc if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1595153323Srodrigc return error; 1596153323Srodrigc } 1597153323Srodrigc dp = args->dp; 1598153323Srodrigc leaf = lbp->data; 1599153323Srodrigc /* 1600153323Srodrigc * Point to the leaf entry, get data address from it. 1601153323Srodrigc */ 1602153323Srodrigc lep = &leaf->ents[index]; 1603153323Srodrigc /* 1604153323Srodrigc * Point to the data entry. 1605153323Srodrigc */ 1606153323Srodrigc dep = (xfs_dir2_data_entry_t *) 1607153323Srodrigc ((char *)dbp->data + 1608159451Srodrigc XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); 1609153323Srodrigc ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); 1610153323Srodrigc /* 1611153323Srodrigc * Put the new inode number in, log it. 1612153323Srodrigc */ 1613153323Srodrigc INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1614153323Srodrigc tp = args->trans; 1615153323Srodrigc xfs_dir2_data_log_entry(tp, dbp, dep); 1616153323Srodrigc xfs_da_buf_done(dbp); 1617153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 1618153323Srodrigc xfs_da_brelse(tp, lbp); 1619153323Srodrigc return 0; 1620153323Srodrigc} 1621153323Srodrigc 1622153323Srodrigc/* 1623153323Srodrigc * Return index in the leaf block (lbp) which is either the first 1624153323Srodrigc * one with this hash value, or if there are none, the insert point 1625153323Srodrigc * for that hash value. 1626153323Srodrigc */ 1627153323Srodrigcint /* index value */ 1628153323Srodrigcxfs_dir2_leaf_search_hash( 1629153323Srodrigc xfs_da_args_t *args, /* operation arguments */ 1630153323Srodrigc xfs_dabuf_t *lbp) /* leaf buffer */ 1631153323Srodrigc{ 1632153323Srodrigc xfs_dahash_t hash=0; /* hash from this entry */ 1633153323Srodrigc xfs_dahash_t hashwant; /* hash value looking for */ 1634153323Srodrigc int high; /* high leaf index */ 1635153323Srodrigc int low; /* low leaf index */ 1636153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1637153323Srodrigc xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1638153323Srodrigc int mid=0; /* current leaf index */ 1639153323Srodrigc 1640153323Srodrigc leaf = lbp->data; 1641153323Srodrigc#ifndef __KERNEL__ 1642159451Srodrigc if (!leaf->hdr.count) 1643153323Srodrigc return 0; 1644153323Srodrigc#endif 1645153323Srodrigc /* 1646153323Srodrigc * Note, the table cannot be empty, so we have to go through the loop. 1647153323Srodrigc * Binary search the leaf entries looking for our hash value. 1648153323Srodrigc */ 1649159451Srodrigc for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1, 1650153323Srodrigc hashwant = args->hashval; 1651153323Srodrigc low <= high; ) { 1652153323Srodrigc mid = (low + high) >> 1; 1653159451Srodrigc if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant) 1654153323Srodrigc break; 1655153323Srodrigc if (hash < hashwant) 1656153323Srodrigc low = mid + 1; 1657153323Srodrigc else 1658153323Srodrigc high = mid - 1; 1659153323Srodrigc } 1660153323Srodrigc /* 1661153323Srodrigc * Found one, back up through all the equal hash values. 1662153323Srodrigc */ 1663153323Srodrigc if (hash == hashwant) { 1664159451Srodrigc while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) { 1665153323Srodrigc mid--; 1666153323Srodrigc } 1667153323Srodrigc } 1668153323Srodrigc /* 1669153323Srodrigc * Need to point to an entry higher than ours. 1670153323Srodrigc */ 1671153323Srodrigc else if (hash < hashwant) 1672153323Srodrigc mid++; 1673153323Srodrigc return mid; 1674153323Srodrigc} 1675153323Srodrigc 1676153323Srodrigc/* 1677153323Srodrigc * Trim off a trailing data block. We know it's empty since the leaf 1678153323Srodrigc * freespace table says so. 1679153323Srodrigc */ 1680153323Srodrigcint /* error */ 1681153323Srodrigcxfs_dir2_leaf_trim_data( 1682153323Srodrigc xfs_da_args_t *args, /* operation arguments */ 1683153323Srodrigc xfs_dabuf_t *lbp, /* leaf buffer */ 1684153323Srodrigc xfs_dir2_db_t db) /* data block number */ 1685153323Srodrigc{ 1686159451Srodrigc __be16 *bestsp; /* leaf bests table */ 1687153323Srodrigc#ifdef DEBUG 1688153323Srodrigc xfs_dir2_data_t *data; /* data block structure */ 1689153323Srodrigc#endif 1690153323Srodrigc xfs_dabuf_t *dbp; /* data block buffer */ 1691153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1692153323Srodrigc int error; /* error return value */ 1693153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1694153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1695153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 1696153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1697153323Srodrigc 1698153323Srodrigc dp = args->dp; 1699153323Srodrigc mp = dp->i_mount; 1700153323Srodrigc tp = args->trans; 1701153323Srodrigc /* 1702153323Srodrigc * Read the offending data block. We need its buffer. 1703153323Srodrigc */ 1704153323Srodrigc if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp, 1705153323Srodrigc XFS_DATA_FORK))) { 1706153323Srodrigc return error; 1707153323Srodrigc } 1708153323Srodrigc#ifdef DEBUG 1709153323Srodrigc data = dbp->data; 1710159451Srodrigc ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); 1711153323Srodrigc#endif 1712153323Srodrigc /* this seems to be an error 1713153323Srodrigc * data is only valid if DEBUG is defined? 1714153323Srodrigc * RMC 09/08/1999 1715153323Srodrigc */ 1716153323Srodrigc 1717153323Srodrigc leaf = lbp->data; 1718153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1719159451Srodrigc ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == 1720153323Srodrigc mp->m_dirblksize - (uint)sizeof(data->hdr)); 1721159451Srodrigc ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); 1722153323Srodrigc /* 1723153323Srodrigc * Get rid of the data block. 1724153323Srodrigc */ 1725153323Srodrigc if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1726153323Srodrigc ASSERT(error != ENOSPC); 1727153323Srodrigc xfs_da_brelse(tp, dbp); 1728153323Srodrigc return error; 1729153323Srodrigc } 1730153323Srodrigc /* 1731153323Srodrigc * Eliminate the last bests entry from the table. 1732153323Srodrigc */ 1733159451Srodrigc bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 1734159451Srodrigc be32_add(<p->bestcount, -1); 1735159451Srodrigc memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); 1736153323Srodrigc xfs_dir2_leaf_log_tail(tp, lbp); 1737159451Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1738153323Srodrigc return 0; 1739153323Srodrigc} 1740153323Srodrigc 1741153323Srodrigc/* 1742153323Srodrigc * Convert node form directory to leaf form directory. 1743153323Srodrigc * The root of the node form dir needs to already be a LEAFN block. 1744153323Srodrigc * Just return if we can't do anything. 1745153323Srodrigc */ 1746153323Srodrigcint /* error */ 1747153323Srodrigcxfs_dir2_node_to_leaf( 1748153323Srodrigc xfs_da_state_t *state) /* directory operation state */ 1749153323Srodrigc{ 1750153323Srodrigc xfs_da_args_t *args; /* operation arguments */ 1751153323Srodrigc xfs_inode_t *dp; /* incore directory inode */ 1752153323Srodrigc int error; /* error return code */ 1753153323Srodrigc xfs_dabuf_t *fbp; /* buffer for freespace block */ 1754153323Srodrigc xfs_fileoff_t fo; /* freespace file offset */ 1755153323Srodrigc xfs_dir2_free_t *free; /* freespace structure */ 1756153323Srodrigc xfs_dabuf_t *lbp; /* buffer for leaf block */ 1757153323Srodrigc xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ 1758153323Srodrigc xfs_dir2_leaf_t *leaf; /* leaf structure */ 1759153323Srodrigc xfs_mount_t *mp; /* filesystem mount point */ 1760153323Srodrigc int rval; /* successful free trim? */ 1761153323Srodrigc xfs_trans_t *tp; /* transaction pointer */ 1762153323Srodrigc 1763153323Srodrigc /* 1764153323Srodrigc * There's more than a leaf level in the btree, so there must 1765153323Srodrigc * be multiple leafn blocks. Give up. 1766153323Srodrigc */ 1767153323Srodrigc if (state->path.active > 1) 1768153323Srodrigc return 0; 1769153323Srodrigc args = state->args; 1770153323Srodrigc xfs_dir2_trace_args("node_to_leaf", args); 1771153323Srodrigc mp = state->mp; 1772153323Srodrigc dp = args->dp; 1773153323Srodrigc tp = args->trans; 1774153323Srodrigc /* 1775153323Srodrigc * Get the last offset in the file. 1776153323Srodrigc */ 1777153323Srodrigc if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) { 1778153323Srodrigc return error; 1779153323Srodrigc } 1780153323Srodrigc fo -= mp->m_dirblkfsbs; 1781153323Srodrigc /* 1782153323Srodrigc * If there are freespace blocks other than the first one, 1783153323Srodrigc * take this opportunity to remove trailing empty freespace blocks 1784153323Srodrigc * that may have been left behind during no-space-reservation 1785153323Srodrigc * operations. 1786153323Srodrigc */ 1787153323Srodrigc while (fo > mp->m_dirfreeblk) { 1788153323Srodrigc if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) { 1789153323Srodrigc return error; 1790153323Srodrigc } 1791153323Srodrigc if (rval) 1792153323Srodrigc fo -= mp->m_dirblkfsbs; 1793153323Srodrigc else 1794153323Srodrigc return 0; 1795153323Srodrigc } 1796153323Srodrigc /* 1797153323Srodrigc * Now find the block just before the freespace block. 1798153323Srodrigc */ 1799153323Srodrigc if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) { 1800153323Srodrigc return error; 1801153323Srodrigc } 1802153323Srodrigc /* 1803153323Srodrigc * If it's not the single leaf block, give up. 1804153323Srodrigc */ 1805153323Srodrigc if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) 1806153323Srodrigc return 0; 1807153323Srodrigc lbp = state->path.blk[0].bp; 1808153323Srodrigc leaf = lbp->data; 1809159451Srodrigc ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1810153323Srodrigc /* 1811153323Srodrigc * Read the freespace block. 1812153323Srodrigc */ 1813153323Srodrigc if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp, 1814153323Srodrigc XFS_DATA_FORK))) { 1815153323Srodrigc return error; 1816153323Srodrigc } 1817153323Srodrigc free = fbp->data; 1818159451Srodrigc ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1819159451Srodrigc ASSERT(!free->hdr.firstdb); 1820153323Srodrigc /* 1821153323Srodrigc * Now see if the leafn and free data will fit in a leaf1. 1822153323Srodrigc * If not, release the buffer and give up. 1823153323Srodrigc */ 1824153323Srodrigc if ((uint)sizeof(leaf->hdr) + 1825159451Srodrigc (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + 1826159451Srodrigc be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) + 1827153323Srodrigc (uint)sizeof(leaf->tail) > 1828153323Srodrigc mp->m_dirblksize) { 1829153323Srodrigc xfs_da_brelse(tp, fbp); 1830153323Srodrigc return 0; 1831153323Srodrigc } 1832153323Srodrigc /* 1833153323Srodrigc * If the leaf has any stale entries in it, compress them out. 1834153323Srodrigc * The compact routine will log the header. 1835153323Srodrigc */ 1836159451Srodrigc if (be16_to_cpu(leaf->hdr.stale)) 1837153323Srodrigc xfs_dir2_leaf_compact(args, lbp); 1838153323Srodrigc else 1839153323Srodrigc xfs_dir2_leaf_log_header(tp, lbp); 1840159451Srodrigc leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); 1841153323Srodrigc /* 1842153323Srodrigc * Set up the leaf tail from the freespace block. 1843153323Srodrigc */ 1844153323Srodrigc ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1845159451Srodrigc ltp->bestcount = free->hdr.nvalid; 1846153323Srodrigc /* 1847153323Srodrigc * Set up the leaf bests table. 1848153323Srodrigc */ 1849159451Srodrigc memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests, 1850159451Srodrigc be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); 1851159451Srodrigc xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1852153323Srodrigc xfs_dir2_leaf_log_tail(tp, lbp); 1853153323Srodrigc xfs_dir2_leaf_check(dp, lbp); 1854153323Srodrigc /* 1855153323Srodrigc * Get rid of the freespace block. 1856153323Srodrigc */ 1857153323Srodrigc error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp); 1858153323Srodrigc if (error) { 1859153323Srodrigc /* 1860153323Srodrigc * This can't fail here because it can only happen when 1861153323Srodrigc * punching out the middle of an extent, and this is an 1862153323Srodrigc * isolated block. 1863153323Srodrigc */ 1864153323Srodrigc ASSERT(error != ENOSPC); 1865153323Srodrigc return error; 1866153323Srodrigc } 1867153323Srodrigc fbp = NULL; 1868153323Srodrigc /* 1869153323Srodrigc * Now see if we can convert the single-leaf directory 1870153323Srodrigc * down to a block form directory. 1871153323Srodrigc * This routine always kills the dabuf for the leaf, so 1872153323Srodrigc * eliminate it from the path. 1873153323Srodrigc */ 1874153323Srodrigc error = xfs_dir2_leaf_to_block(args, lbp, NULL); 1875153323Srodrigc state->path.blk[0].bp = NULL; 1876153323Srodrigc return error; 1877153323Srodrigc} 1878