]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/xfs/xfs_dir2_readdir.c
xfs: move getdents code into it's own file
[mirror_ubuntu-zesty-kernel.git] / fs / xfs / xfs_dir2_readdir.c
CommitLineData
4a8af273
DC
1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc.
4 * All Rights Reserved.
5 *
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.
9 *
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.
14 *
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
18 */
19#include "xfs.h"
20#include "xfs_fs.h"
21#include "xfs_types.h"
22#include "xfs_bit.h"
23#include "xfs_log.h"
24#include "xfs_trans.h"
25#include "xfs_sb.h"
26#include "xfs_ag.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"
33#include "xfs_dir2_priv.h"
34#include "xfs_error.h"
35#include "xfs_trace.h"
36#include "xfs_bmap.h"
37
38STATIC int
39xfs_dir2_sf_getdents(
40 xfs_inode_t *dp, /* incore directory inode */
41 struct dir_context *ctx)
42{
43 int i; /* shortform entry number */
44 xfs_mount_t *mp; /* filesystem mount point */
45 xfs_dir2_dataptr_t off; /* current entry's offset */
46 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
47 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
48 xfs_dir2_dataptr_t dot_offset;
49 xfs_dir2_dataptr_t dotdot_offset;
50 xfs_ino_t ino;
51
52 mp = dp->i_mount;
53
54 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
55 /*
56 * Give up if the directory is way too short.
57 */
58 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
59 ASSERT(XFS_FORCED_SHUTDOWN(mp));
60 return XFS_ERROR(EIO);
61 }
62
63 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
64 ASSERT(dp->i_df.if_u1.if_data != NULL);
65
66 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
67
68 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count));
69
70 /*
71 * If the block number in the offset is out of range, we're done.
72 */
73 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
74 return 0;
75
76 /*
77 * Precalculate offsets for . and .. as we will always need them.
78 *
79 * XXX(hch): the second argument is sometimes 0 and sometimes
80 * mp->m_dirdatablk.
81 */
82 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
83 XFS_DIR3_DATA_DOT_OFFSET(mp));
84 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
85 XFS_DIR3_DATA_DOTDOT_OFFSET(mp));
86
87 /*
88 * Put . entry unless we're starting past it.
89 */
90 if (ctx->pos <= dot_offset) {
91 ctx->pos = dot_offset & 0x7fffffff;
92 if (!dir_emit(ctx, ".", 1, dp->i_ino, DT_DIR))
93 return 0;
94 }
95
96 /*
97 * Put .. entry unless we're starting past it.
98 */
99 if (ctx->pos <= dotdot_offset) {
100 ino = xfs_dir2_sf_get_parent_ino(sfp);
101 ctx->pos = dotdot_offset & 0x7fffffff;
102 if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
103 return 0;
104 }
105
106 /*
107 * Loop while there are more entries and put'ing works.
108 */
109 sfep = xfs_dir2_sf_firstentry(sfp);
110 for (i = 0; i < sfp->count; i++) {
111 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
112 xfs_dir2_sf_get_offset(sfep));
113
114 if (ctx->pos > off) {
115 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
116 continue;
117 }
118
119 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
120 ctx->pos = off & 0x7fffffff;
121 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen,
122 ino, DT_UNKNOWN))
123 return 0;
124 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
125 }
126
127 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
128 0x7fffffff;
129 return 0;
130}
131
132/*
133 * Readdir for block directories.
134 */
135STATIC int
136xfs_dir2_block_getdents(
137 xfs_inode_t *dp, /* incore inode */
138 struct dir_context *ctx)
139{
140 xfs_dir2_data_hdr_t *hdr; /* block header */
141 struct xfs_buf *bp; /* buffer for block */
142 xfs_dir2_block_tail_t *btp; /* block tail */
143 xfs_dir2_data_entry_t *dep; /* block data entry */
144 xfs_dir2_data_unused_t *dup; /* block unused entry */
145 char *endptr; /* end of the data entries */
146 int error; /* error return value */
147 xfs_mount_t *mp; /* filesystem mount point */
148 char *ptr; /* current data entry */
149 int wantoff; /* starting block offset */
150 xfs_off_t cook;
151
152 mp = dp->i_mount;
153 /*
154 * If the block number in the offset is out of range, we're done.
155 */
156 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
157 return 0;
158
159 error = xfs_dir3_block_read(NULL, dp, &bp);
160 if (error)
161 return error;
162
163 /*
164 * Extract the byte offset we start at from the seek pointer.
165 * We'll skip entries before this.
166 */
167 wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos);
168 hdr = bp->b_addr;
169 xfs_dir3_data_check(dp, bp);
170 /*
171 * Set up values for the loop.
172 */
173 btp = xfs_dir2_block_tail_p(mp, hdr);
174 ptr = (char *)xfs_dir3_data_entry_p(hdr);
175 endptr = (char *)xfs_dir2_block_leaf_p(btp);
176
177 /*
178 * Loop over the data portion of the block.
179 * Each object is a real entry (dep) or an unused one (dup).
180 */
181 while (ptr < endptr) {
182 dup = (xfs_dir2_data_unused_t *)ptr;
183 /*
184 * Unused, skip it.
185 */
186 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
187 ptr += be16_to_cpu(dup->length);
188 continue;
189 }
190
191 dep = (xfs_dir2_data_entry_t *)ptr;
192
193 /*
194 * Bump pointer for the next iteration.
195 */
196 ptr += xfs_dir2_data_entsize(dep->namelen);
197 /*
198 * The entry is before the desired starting point, skip it.
199 */
200 if ((char *)dep - (char *)hdr < wantoff)
201 continue;
202
203 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
204 (char *)dep - (char *)hdr);
205
206 ctx->pos = cook & 0x7fffffff;
207 /*
208 * If it didn't fit, set the final offset to here & return.
209 */
210 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
211 be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
212 xfs_trans_brelse(NULL, bp);
213 return 0;
214 }
215 }
216
217 /*
218 * Reached the end of the block.
219 * Set the offset to a non-existent block 1 and return.
220 */
221 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
222 0x7fffffff;
223 xfs_trans_brelse(NULL, bp);
224 return 0;
225}
226
227struct xfs_dir2_leaf_map_info {
228 xfs_extlen_t map_blocks; /* number of fsbs in map */
229 xfs_dablk_t map_off; /* last mapped file offset */
230 int map_size; /* total entries in *map */
231 int map_valid; /* valid entries in *map */
232 int nmap; /* mappings to ask xfs_bmapi */
233 xfs_dir2_db_t curdb; /* db for current block */
234 int ra_current; /* number of read-ahead blks */
235 int ra_index; /* *map index for read-ahead */
236 int ra_offset; /* map entry offset for ra */
237 int ra_want; /* readahead count wanted */
238 struct xfs_bmbt_irec map[]; /* map vector for blocks */
239};
240
241STATIC int
242xfs_dir2_leaf_readbuf(
243 struct xfs_inode *dp,
244 size_t bufsize,
245 struct xfs_dir2_leaf_map_info *mip,
246 xfs_dir2_off_t *curoff,
247 struct xfs_buf **bpp)
248{
249 struct xfs_mount *mp = dp->i_mount;
250 struct xfs_buf *bp = *bpp;
251 struct xfs_bmbt_irec *map = mip->map;
252 struct blk_plug plug;
253 int error = 0;
254 int length;
255 int i;
256 int j;
257
258 /*
259 * If we have a buffer, we need to release it and
260 * take it out of the mapping.
261 */
262
263 if (bp) {
264 xfs_trans_brelse(NULL, bp);
265 bp = NULL;
266 mip->map_blocks -= mp->m_dirblkfsbs;
267 /*
268 * Loop to get rid of the extents for the
269 * directory block.
270 */
271 for (i = mp->m_dirblkfsbs; i > 0; ) {
272 j = min_t(int, map->br_blockcount, i);
273 map->br_blockcount -= j;
274 map->br_startblock += j;
275 map->br_startoff += j;
276 /*
277 * If mapping is done, pitch it from
278 * the table.
279 */
280 if (!map->br_blockcount && --mip->map_valid)
281 memmove(&map[0], &map[1],
282 sizeof(map[0]) * mip->map_valid);
283 i -= j;
284 }
285 }
286
287 /*
288 * Recalculate the readahead blocks wanted.
289 */
290 mip->ra_want = howmany(bufsize + mp->m_dirblksize,
291 mp->m_sb.sb_blocksize) - 1;
292 ASSERT(mip->ra_want >= 0);
293
294 /*
295 * If we don't have as many as we want, and we haven't
296 * run out of data blocks, get some more mappings.
297 */
298 if (1 + mip->ra_want > mip->map_blocks &&
299 mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) {
300 /*
301 * Get more bmaps, fill in after the ones
302 * we already have in the table.
303 */
304 mip->nmap = mip->map_size - mip->map_valid;
305 error = xfs_bmapi_read(dp, mip->map_off,
306 xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) -
307 mip->map_off,
308 &map[mip->map_valid], &mip->nmap, 0);
309
310 /*
311 * Don't know if we should ignore this or try to return an
312 * error. The trouble with returning errors is that readdir
313 * will just stop without actually passing the error through.
314 */
315 if (error)
316 goto out; /* XXX */
317
318 /*
319 * If we got all the mappings we asked for, set the final map
320 * offset based on the last bmap value received. Otherwise,
321 * we've reached the end.
322 */
323 if (mip->nmap == mip->map_size - mip->map_valid) {
324 i = mip->map_valid + mip->nmap - 1;
325 mip->map_off = map[i].br_startoff + map[i].br_blockcount;
326 } else
327 mip->map_off = xfs_dir2_byte_to_da(mp,
328 XFS_DIR2_LEAF_OFFSET);
329
330 /*
331 * Look for holes in the mapping, and eliminate them. Count up
332 * the valid blocks.
333 */
334 for (i = mip->map_valid; i < mip->map_valid + mip->nmap; ) {
335 if (map[i].br_startblock == HOLESTARTBLOCK) {
336 mip->nmap--;
337 length = mip->map_valid + mip->nmap - i;
338 if (length)
339 memmove(&map[i], &map[i + 1],
340 sizeof(map[i]) * length);
341 } else {
342 mip->map_blocks += map[i].br_blockcount;
343 i++;
344 }
345 }
346 mip->map_valid += mip->nmap;
347 }
348
349 /*
350 * No valid mappings, so no more data blocks.
351 */
352 if (!mip->map_valid) {
353 *curoff = xfs_dir2_da_to_byte(mp, mip->map_off);
354 goto out;
355 }
356
357 /*
358 * Read the directory block starting at the first mapping.
359 */
360 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
361 error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
362 map->br_blockcount >= mp->m_dirblkfsbs ?
363 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
364
365 /*
366 * Should just skip over the data block instead of giving up.
367 */
368 if (error)
369 goto out; /* XXX */
370
371 /*
372 * Adjust the current amount of read-ahead: we just read a block that
373 * was previously ra.
374 */
375 if (mip->ra_current)
376 mip->ra_current -= mp->m_dirblkfsbs;
377
378 /*
379 * Do we need more readahead?
380 */
381 blk_start_plug(&plug);
382 for (mip->ra_index = mip->ra_offset = i = 0;
383 mip->ra_want > mip->ra_current && i < mip->map_blocks;
384 i += mp->m_dirblkfsbs) {
385 ASSERT(mip->ra_index < mip->map_valid);
386 /*
387 * Read-ahead a contiguous directory block.
388 */
389 if (i > mip->ra_current &&
390 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) {
391 xfs_dir3_data_readahead(NULL, dp,
392 map[mip->ra_index].br_startoff + mip->ra_offset,
393 XFS_FSB_TO_DADDR(mp,
394 map[mip->ra_index].br_startblock +
395 mip->ra_offset));
396 mip->ra_current = i;
397 }
398
399 /*
400 * Read-ahead a non-contiguous directory block. This doesn't
401 * use our mapping, but this is a very rare case.
402 */
403 else if (i > mip->ra_current) {
404 xfs_dir3_data_readahead(NULL, dp,
405 map[mip->ra_index].br_startoff +
406 mip->ra_offset, -1);
407 mip->ra_current = i;
408 }
409
410 /*
411 * Advance offset through the mapping table.
412 */
413 for (j = 0; j < mp->m_dirblkfsbs; j++) {
414 /*
415 * The rest of this extent but not more than a dir
416 * block.
417 */
418 length = min_t(int, mp->m_dirblkfsbs,
419 map[mip->ra_index].br_blockcount -
420 mip->ra_offset);
421 j += length;
422 mip->ra_offset += length;
423
424 /*
425 * Advance to the next mapping if this one is used up.
426 */
427 if (mip->ra_offset == map[mip->ra_index].br_blockcount) {
428 mip->ra_offset = 0;
429 mip->ra_index++;
430 }
431 }
432 }
433 blk_finish_plug(&plug);
434
435out:
436 *bpp = bp;
437 return error;
438}
439
440/*
441 * Getdents (readdir) for leaf and node directories.
442 * This reads the data blocks only, so is the same for both forms.
443 */
444STATIC int
445xfs_dir2_leaf_getdents(
446 xfs_inode_t *dp, /* incore directory inode */
447 struct dir_context *ctx,
448 size_t bufsize)
449{
450 struct xfs_buf *bp = NULL; /* data block buffer */
451 xfs_dir2_data_hdr_t *hdr; /* data block header */
452 xfs_dir2_data_entry_t *dep; /* data entry */
453 xfs_dir2_data_unused_t *dup; /* unused entry */
454 int error = 0; /* error return value */
455 int length; /* temporary length value */
456 xfs_mount_t *mp; /* filesystem mount point */
457 int byteoff; /* offset in current block */
458 xfs_dir2_off_t curoff; /* current overall offset */
459 xfs_dir2_off_t newoff; /* new curoff after new blk */
460 char *ptr = NULL; /* pointer to current data */
461 struct xfs_dir2_leaf_map_info *map_info;
462
463 /*
464 * If the offset is at or past the largest allowed value,
465 * give up right away.
466 */
467 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
468 return 0;
469
470 mp = dp->i_mount;
471
472 /*
473 * Set up to bmap a number of blocks based on the caller's
474 * buffer size, the directory block size, and the filesystem
475 * block size.
476 */
477 length = howmany(bufsize + mp->m_dirblksize,
478 mp->m_sb.sb_blocksize);
479 map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
480 (length * sizeof(struct xfs_bmbt_irec)),
481 KM_SLEEP | KM_NOFS);
482 map_info->map_size = length;
483
484 /*
485 * Inside the loop we keep the main offset value as a byte offset
486 * in the directory file.
487 */
488 curoff = xfs_dir2_dataptr_to_byte(mp, ctx->pos);
489
490 /*
491 * Force this conversion through db so we truncate the offset
492 * down to get the start of the data block.
493 */
494 map_info->map_off = xfs_dir2_db_to_da(mp,
495 xfs_dir2_byte_to_db(mp, curoff));
496
497 /*
498 * Loop over directory entries until we reach the end offset.
499 * Get more blocks and readahead as necessary.
500 */
501 while (curoff < XFS_DIR2_LEAF_OFFSET) {
502 /*
503 * If we have no buffer, or we're off the end of the
504 * current buffer, need to get another one.
505 */
506 if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) {
507
508 error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info,
509 &curoff, &bp);
510 if (error || !map_info->map_valid)
511 break;
512
513 /*
514 * Having done a read, we need to set a new offset.
515 */
516 newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0);
517 /*
518 * Start of the current block.
519 */
520 if (curoff < newoff)
521 curoff = newoff;
522 /*
523 * Make sure we're in the right block.
524 */
525 else if (curoff > newoff)
526 ASSERT(xfs_dir2_byte_to_db(mp, curoff) ==
527 map_info->curdb);
528 hdr = bp->b_addr;
529 xfs_dir3_data_check(dp, bp);
530 /*
531 * Find our position in the block.
532 */
533 ptr = (char *)xfs_dir3_data_entry_p(hdr);
534 byteoff = xfs_dir2_byte_to_off(mp, curoff);
535 /*
536 * Skip past the header.
537 */
538 if (byteoff == 0)
539 curoff += xfs_dir3_data_entry_offset(hdr);
540 /*
541 * Skip past entries until we reach our offset.
542 */
543 else {
544 while ((char *)ptr - (char *)hdr < byteoff) {
545 dup = (xfs_dir2_data_unused_t *)ptr;
546
547 if (be16_to_cpu(dup->freetag)
548 == XFS_DIR2_DATA_FREE_TAG) {
549
550 length = be16_to_cpu(dup->length);
551 ptr += length;
552 continue;
553 }
554 dep = (xfs_dir2_data_entry_t *)ptr;
555 length =
556 xfs_dir2_data_entsize(dep->namelen);
557 ptr += length;
558 }
559 /*
560 * Now set our real offset.
561 */
562 curoff =
563 xfs_dir2_db_off_to_byte(mp,
564 xfs_dir2_byte_to_db(mp, curoff),
565 (char *)ptr - (char *)hdr);
566 if (ptr >= (char *)hdr + mp->m_dirblksize) {
567 continue;
568 }
569 }
570 }
571 /*
572 * We have a pointer to an entry.
573 * Is it a live one?
574 */
575 dup = (xfs_dir2_data_unused_t *)ptr;
576 /*
577 * No, it's unused, skip over it.
578 */
579 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
580 length = be16_to_cpu(dup->length);
581 ptr += length;
582 curoff += length;
583 continue;
584 }
585
586 dep = (xfs_dir2_data_entry_t *)ptr;
587 length = xfs_dir2_data_entsize(dep->namelen);
588
589 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
590 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
591 be64_to_cpu(dep->inumber), DT_UNKNOWN))
592 break;
593
594 /*
595 * Advance to next entry in the block.
596 */
597 ptr += length;
598 curoff += length;
599 /* bufsize may have just been a guess; don't go negative */
600 bufsize = bufsize > length ? bufsize - length : 0;
601 }
602
603 /*
604 * All done. Set output offset value to current offset.
605 */
606 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
607 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
608 else
609 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
610 kmem_free(map_info);
611 if (bp)
612 xfs_trans_brelse(NULL, bp);
613 return error;
614}
615
616/*
617 * Read a directory.
618 */
619int
620xfs_readdir(
621 xfs_inode_t *dp,
622 struct dir_context *ctx,
623 size_t bufsize)
624{
625 int rval; /* return value */
626 int v; /* type-checking value */
627
628 trace_xfs_readdir(dp);
629
630 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
631 return XFS_ERROR(EIO);
632
633 ASSERT(S_ISDIR(dp->i_d.di_mode));
634 XFS_STATS_INC(xs_dir_getdents);
635
636 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
637 rval = xfs_dir2_sf_getdents(dp, ctx);
638 else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
639 ;
640 else if (v)
641 rval = xfs_dir2_block_getdents(dp, ctx);
642 else
643 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
644 return rval;
645}