2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it would be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "xfs_types.h"
24 #include "xfs_trans.h"
27 #include "xfs_mount.h"
28 #include "xfs_da_btree.h"
29 #include "xfs_bmap_btree.h"
30 #include "xfs_dinode.h"
31 #include "xfs_inode.h"
32 #include "xfs_dir2_format.h"
34 #include "xfs_dir2_priv.h"
35 #include "xfs_error.h"
36 #include "xfs_trace.h"
41 xfs_inode_t *dp, /* incore directory inode */
42 struct dir_context *ctx)
44 int i; /* shortform entry number */
45 xfs_mount_t *mp; /* filesystem mount point */
46 xfs_dir2_dataptr_t off; /* current entry's offset */
47 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
48 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
49 xfs_dir2_dataptr_t dot_offset;
50 xfs_dir2_dataptr_t dotdot_offset;
55 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
57 * Give up if the directory is way too short.
59 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
60 ASSERT(XFS_FORCED_SHUTDOWN(mp));
61 return XFS_ERROR(EIO);
64 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
65 ASSERT(dp->i_df.if_u1.if_data != NULL);
67 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
69 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count));
72 * If the block number in the offset is out of range, we're done.
74 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
78 * Precalculate offsets for . and .. as we will always need them.
80 * XXX(hch): the second argument is sometimes 0 and sometimes
83 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
84 XFS_DIR3_DATA_DOT_OFFSET(mp));
85 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
86 XFS_DIR3_DATA_DOTDOT_OFFSET(mp));
89 * Put . entry unless we're starting past it.
91 if (ctx->pos <= dot_offset) {
92 ctx->pos = dot_offset & 0x7fffffff;
93 if (!dir_emit(ctx, ".", 1, dp->i_ino, DT_DIR))
98 * Put .. entry unless we're starting past it.
100 if (ctx->pos <= dotdot_offset) {
101 ino = xfs_dir2_sf_get_parent_ino(sfp);
102 ctx->pos = dotdot_offset & 0x7fffffff;
103 if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
108 * Loop while there are more entries and put'ing works.
110 sfep = xfs_dir2_sf_firstentry(sfp);
111 for (i = 0; i < sfp->count; i++) {
112 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
113 xfs_dir2_sf_get_offset(sfep));
115 if (ctx->pos > off) {
116 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
120 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
121 ctx->pos = off & 0x7fffffff;
122 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen,
125 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
128 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
134 * Readdir for block directories.
137 xfs_dir2_block_getdents(
138 xfs_inode_t *dp, /* incore inode */
139 struct dir_context *ctx)
141 xfs_dir2_data_hdr_t *hdr; /* block header */
142 struct xfs_buf *bp; /* buffer for block */
143 xfs_dir2_block_tail_t *btp; /* block tail */
144 xfs_dir2_data_entry_t *dep; /* block data entry */
145 xfs_dir2_data_unused_t *dup; /* block unused entry */
146 char *endptr; /* end of the data entries */
147 int error; /* error return value */
148 xfs_mount_t *mp; /* filesystem mount point */
149 char *ptr; /* current data entry */
150 int wantoff; /* starting block offset */
155 * If the block number in the offset is out of range, we're done.
157 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
160 error = xfs_dir3_block_read(NULL, dp, &bp);
165 * Extract the byte offset we start at from the seek pointer.
166 * We'll skip entries before this.
168 wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos);
170 xfs_dir3_data_check(dp, bp);
172 * Set up values for the loop.
174 btp = xfs_dir2_block_tail_p(mp, hdr);
175 ptr = (char *)xfs_dir3_data_entry_p(hdr);
176 endptr = (char *)xfs_dir2_block_leaf_p(btp);
179 * Loop over the data portion of the block.
180 * Each object is a real entry (dep) or an unused one (dup).
182 while (ptr < endptr) {
183 dup = (xfs_dir2_data_unused_t *)ptr;
187 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
188 ptr += be16_to_cpu(dup->length);
192 dep = (xfs_dir2_data_entry_t *)ptr;
195 * Bump pointer for the next iteration.
197 ptr += xfs_dir2_data_entsize(dep->namelen);
199 * The entry is before the desired starting point, skip it.
201 if ((char *)dep - (char *)hdr < wantoff)
204 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
205 (char *)dep - (char *)hdr);
207 ctx->pos = cook & 0x7fffffff;
209 * If it didn't fit, set the final offset to here & return.
211 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
212 be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
213 xfs_trans_brelse(NULL, bp);
219 * Reached the end of the block.
220 * Set the offset to a non-existent block 1 and return.
222 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
224 xfs_trans_brelse(NULL, bp);
228 struct xfs_dir2_leaf_map_info {
229 xfs_extlen_t map_blocks; /* number of fsbs in map */
230 xfs_dablk_t map_off; /* last mapped file offset */
231 int map_size; /* total entries in *map */
232 int map_valid; /* valid entries in *map */
233 int nmap; /* mappings to ask xfs_bmapi */
234 xfs_dir2_db_t curdb; /* db for current block */
235 int ra_current; /* number of read-ahead blks */
236 int ra_index; /* *map index for read-ahead */
237 int ra_offset; /* map entry offset for ra */
238 int ra_want; /* readahead count wanted */
239 struct xfs_bmbt_irec map[]; /* map vector for blocks */
243 xfs_dir2_leaf_readbuf(
244 struct xfs_inode *dp,
246 struct xfs_dir2_leaf_map_info *mip,
247 xfs_dir2_off_t *curoff,
248 struct xfs_buf **bpp)
250 struct xfs_mount *mp = dp->i_mount;
251 struct xfs_buf *bp = *bpp;
252 struct xfs_bmbt_irec *map = mip->map;
253 struct blk_plug plug;
260 * If we have a buffer, we need to release it and
261 * take it out of the mapping.
265 xfs_trans_brelse(NULL, bp);
267 mip->map_blocks -= mp->m_dirblkfsbs;
269 * Loop to get rid of the extents for the
272 for (i = mp->m_dirblkfsbs; i > 0; ) {
273 j = min_t(int, map->br_blockcount, i);
274 map->br_blockcount -= j;
275 map->br_startblock += j;
276 map->br_startoff += j;
278 * If mapping is done, pitch it from
281 if (!map->br_blockcount && --mip->map_valid)
282 memmove(&map[0], &map[1],
283 sizeof(map[0]) * mip->map_valid);
289 * Recalculate the readahead blocks wanted.
291 mip->ra_want = howmany(bufsize + mp->m_dirblksize,
292 mp->m_sb.sb_blocksize) - 1;
293 ASSERT(mip->ra_want >= 0);
296 * If we don't have as many as we want, and we haven't
297 * run out of data blocks, get some more mappings.
299 if (1 + mip->ra_want > mip->map_blocks &&
300 mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) {
302 * Get more bmaps, fill in after the ones
303 * we already have in the table.
305 mip->nmap = mip->map_size - mip->map_valid;
306 error = xfs_bmapi_read(dp, mip->map_off,
307 xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) -
309 &map[mip->map_valid], &mip->nmap, 0);
312 * Don't know if we should ignore this or try to return an
313 * error. The trouble with returning errors is that readdir
314 * will just stop without actually passing the error through.
320 * If we got all the mappings we asked for, set the final map
321 * offset based on the last bmap value received. Otherwise,
322 * we've reached the end.
324 if (mip->nmap == mip->map_size - mip->map_valid) {
325 i = mip->map_valid + mip->nmap - 1;
326 mip->map_off = map[i].br_startoff + map[i].br_blockcount;
328 mip->map_off = xfs_dir2_byte_to_da(mp,
329 XFS_DIR2_LEAF_OFFSET);
332 * Look for holes in the mapping, and eliminate them. Count up
335 for (i = mip->map_valid; i < mip->map_valid + mip->nmap; ) {
336 if (map[i].br_startblock == HOLESTARTBLOCK) {
338 length = mip->map_valid + mip->nmap - i;
340 memmove(&map[i], &map[i + 1],
341 sizeof(map[i]) * length);
343 mip->map_blocks += map[i].br_blockcount;
347 mip->map_valid += mip->nmap;
351 * No valid mappings, so no more data blocks.
353 if (!mip->map_valid) {
354 *curoff = xfs_dir2_da_to_byte(mp, mip->map_off);
359 * Read the directory block starting at the first mapping.
361 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
362 error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
363 map->br_blockcount >= mp->m_dirblkfsbs ?
364 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
367 * Should just skip over the data block instead of giving up.
373 * Adjust the current amount of read-ahead: we just read a block that
377 mip->ra_current -= mp->m_dirblkfsbs;
380 * Do we need more readahead?
382 blk_start_plug(&plug);
383 for (mip->ra_index = mip->ra_offset = i = 0;
384 mip->ra_want > mip->ra_current && i < mip->map_blocks;
385 i += mp->m_dirblkfsbs) {
386 ASSERT(mip->ra_index < mip->map_valid);
388 * Read-ahead a contiguous directory block.
390 if (i > mip->ra_current &&
391 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) {
392 xfs_dir3_data_readahead(NULL, dp,
393 map[mip->ra_index].br_startoff + mip->ra_offset,
395 map[mip->ra_index].br_startblock +
401 * Read-ahead a non-contiguous directory block. This doesn't
402 * use our mapping, but this is a very rare case.
404 else if (i > mip->ra_current) {
405 xfs_dir3_data_readahead(NULL, dp,
406 map[mip->ra_index].br_startoff +
412 * Advance offset through the mapping table.
414 for (j = 0; j < mp->m_dirblkfsbs; j++) {
416 * The rest of this extent but not more than a dir
419 length = min_t(int, mp->m_dirblkfsbs,
420 map[mip->ra_index].br_blockcount -
423 mip->ra_offset += length;
426 * Advance to the next mapping if this one is used up.
428 if (mip->ra_offset == map[mip->ra_index].br_blockcount) {
434 blk_finish_plug(&plug);
442 * Getdents (readdir) for leaf and node directories.
443 * This reads the data blocks only, so is the same for both forms.
446 xfs_dir2_leaf_getdents(
447 xfs_inode_t *dp, /* incore directory inode */
448 struct dir_context *ctx,
451 struct xfs_buf *bp = NULL; /* data block buffer */
452 xfs_dir2_data_hdr_t *hdr; /* data block header */
453 xfs_dir2_data_entry_t *dep; /* data entry */
454 xfs_dir2_data_unused_t *dup; /* unused entry */
455 int error = 0; /* error return value */
456 int length; /* temporary length value */
457 xfs_mount_t *mp; /* filesystem mount point */
458 int byteoff; /* offset in current block */
459 xfs_dir2_off_t curoff; /* current overall offset */
460 xfs_dir2_off_t newoff; /* new curoff after new blk */
461 char *ptr = NULL; /* pointer to current data */
462 struct xfs_dir2_leaf_map_info *map_info;
465 * If the offset is at or past the largest allowed value,
466 * give up right away.
468 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
474 * Set up to bmap a number of blocks based on the caller's
475 * buffer size, the directory block size, and the filesystem
478 length = howmany(bufsize + mp->m_dirblksize,
479 mp->m_sb.sb_blocksize);
480 map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
481 (length * sizeof(struct xfs_bmbt_irec)),
483 map_info->map_size = length;
486 * Inside the loop we keep the main offset value as a byte offset
487 * in the directory file.
489 curoff = xfs_dir2_dataptr_to_byte(mp, ctx->pos);
492 * Force this conversion through db so we truncate the offset
493 * down to get the start of the data block.
495 map_info->map_off = xfs_dir2_db_to_da(mp,
496 xfs_dir2_byte_to_db(mp, curoff));
499 * Loop over directory entries until we reach the end offset.
500 * Get more blocks and readahead as necessary.
502 while (curoff < XFS_DIR2_LEAF_OFFSET) {
504 * If we have no buffer, or we're off the end of the
505 * current buffer, need to get another one.
507 if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) {
509 error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info,
511 if (error || !map_info->map_valid)
515 * Having done a read, we need to set a new offset.
517 newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0);
519 * Start of the current block.
524 * Make sure we're in the right block.
526 else if (curoff > newoff)
527 ASSERT(xfs_dir2_byte_to_db(mp, curoff) ==
530 xfs_dir3_data_check(dp, bp);
532 * Find our position in the block.
534 ptr = (char *)xfs_dir3_data_entry_p(hdr);
535 byteoff = xfs_dir2_byte_to_off(mp, curoff);
537 * Skip past the header.
540 curoff += xfs_dir3_data_entry_offset(hdr);
542 * Skip past entries until we reach our offset.
545 while ((char *)ptr - (char *)hdr < byteoff) {
546 dup = (xfs_dir2_data_unused_t *)ptr;
548 if (be16_to_cpu(dup->freetag)
549 == XFS_DIR2_DATA_FREE_TAG) {
551 length = be16_to_cpu(dup->length);
555 dep = (xfs_dir2_data_entry_t *)ptr;
557 xfs_dir2_data_entsize(dep->namelen);
561 * Now set our real offset.
564 xfs_dir2_db_off_to_byte(mp,
565 xfs_dir2_byte_to_db(mp, curoff),
566 (char *)ptr - (char *)hdr);
567 if (ptr >= (char *)hdr + mp->m_dirblksize) {
573 * We have a pointer to an entry.
576 dup = (xfs_dir2_data_unused_t *)ptr;
578 * No, it's unused, skip over it.
580 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
581 length = be16_to_cpu(dup->length);
587 dep = (xfs_dir2_data_entry_t *)ptr;
588 length = xfs_dir2_data_entsize(dep->namelen);
590 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
591 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
592 be64_to_cpu(dep->inumber), DT_UNKNOWN))
596 * Advance to next entry in the block.
600 /* bufsize may have just been a guess; don't go negative */
601 bufsize = bufsize > length ? bufsize - length : 0;
605 * All done. Set output offset value to current offset.
607 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
608 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
610 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
613 xfs_trans_brelse(NULL, bp);
623 struct dir_context *ctx,
626 int rval; /* return value */
627 int v; /* type-checking value */
629 trace_xfs_readdir(dp);
631 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
632 return XFS_ERROR(EIO);
634 ASSERT(S_ISDIR(dp->i_d.di_mode));
635 XFS_STATS_INC(xs_dir_getdents);
637 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
638 rval = xfs_dir2_sf_getdents(dp, ctx);
639 else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
642 rval = xfs_dir2_block_getdents(dp, ctx);
644 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);