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_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
25 #include "xfs_mount.h"
26 #include "xfs_da_format.h"
27 #include "xfs_da_btree.h"
28 #include "xfs_inode.h"
30 #include "xfs_dir2_priv.h"
31 #include "xfs_error.h"
32 #include "xfs_trace.h"
34 #include "xfs_trans.h"
37 * Directory file type support functions
39 static unsigned char xfs_dir3_filetype_table
[] = {
40 DT_UNKNOWN
, DT_REG
, DT_DIR
, DT_CHR
, DT_BLK
,
41 DT_FIFO
, DT_SOCK
, DT_LNK
, DT_WHT
,
49 if (!xfs_sb_version_hasftype(&mp
->m_sb
))
52 if (filetype
>= XFS_DIR3_FT_MAX
)
55 return xfs_dir3_filetype_table
[filetype
];
60 struct xfs_da_args
*args
,
61 struct dir_context
*ctx
)
63 int i
; /* shortform entry number */
64 struct xfs_inode
*dp
= args
->dp
; /* incore directory inode */
65 xfs_dir2_dataptr_t off
; /* current entry's offset */
66 xfs_dir2_sf_entry_t
*sfep
; /* shortform directory entry */
67 xfs_dir2_sf_hdr_t
*sfp
; /* shortform structure */
68 xfs_dir2_dataptr_t dot_offset
;
69 xfs_dir2_dataptr_t dotdot_offset
;
71 struct xfs_da_geometry
*geo
= args
->geo
;
73 ASSERT(dp
->i_df
.if_flags
& XFS_IFINLINE
);
74 ASSERT(dp
->i_df
.if_bytes
== dp
->i_d
.di_size
);
75 ASSERT(dp
->i_df
.if_u1
.if_data
!= NULL
);
77 sfp
= (xfs_dir2_sf_hdr_t
*)dp
->i_df
.if_u1
.if_data
;
80 * If the block number in the offset is out of range, we're done.
82 if (xfs_dir2_dataptr_to_db(geo
, ctx
->pos
) > geo
->datablk
)
86 * Precalculate offsets for . and .. as we will always need them.
88 * XXX(hch): the second argument is sometimes 0 and sometimes
91 dot_offset
= xfs_dir2_db_off_to_dataptr(geo
, geo
->datablk
,
92 dp
->d_ops
->data_dot_offset
);
93 dotdot_offset
= xfs_dir2_db_off_to_dataptr(geo
, geo
->datablk
,
94 dp
->d_ops
->data_dotdot_offset
);
97 * Put . entry unless we're starting past it.
99 if (ctx
->pos
<= dot_offset
) {
100 ctx
->pos
= dot_offset
& 0x7fffffff;
101 if (!dir_emit(ctx
, ".", 1, dp
->i_ino
, DT_DIR
))
106 * Put .. entry unless we're starting past it.
108 if (ctx
->pos
<= dotdot_offset
) {
109 ino
= dp
->d_ops
->sf_get_parent_ino(sfp
);
110 ctx
->pos
= dotdot_offset
& 0x7fffffff;
111 if (!dir_emit(ctx
, "..", 2, ino
, DT_DIR
))
116 * Loop while there are more entries and put'ing works.
118 sfep
= xfs_dir2_sf_firstentry(sfp
);
119 for (i
= 0; i
< sfp
->count
; i
++) {
122 off
= xfs_dir2_db_off_to_dataptr(geo
, geo
->datablk
,
123 xfs_dir2_sf_get_offset(sfep
));
125 if (ctx
->pos
> off
) {
126 sfep
= dp
->d_ops
->sf_nextentry(sfp
, sfep
);
130 ino
= dp
->d_ops
->sf_get_ino(sfp
, sfep
);
131 filetype
= dp
->d_ops
->sf_get_ftype(sfep
);
132 ctx
->pos
= off
& 0x7fffffff;
133 if (!dir_emit(ctx
, (char *)sfep
->name
, sfep
->namelen
, ino
,
134 xfs_dir3_get_dtype(dp
->i_mount
, filetype
)))
136 sfep
= dp
->d_ops
->sf_nextentry(sfp
, sfep
);
139 ctx
->pos
= xfs_dir2_db_off_to_dataptr(geo
, geo
->datablk
+ 1, 0) &
145 * Readdir for block directories.
148 xfs_dir2_block_getdents(
149 struct xfs_da_args
*args
,
150 struct dir_context
*ctx
)
152 struct xfs_inode
*dp
= args
->dp
; /* incore directory inode */
153 xfs_dir2_data_hdr_t
*hdr
; /* block header */
154 struct xfs_buf
*bp
; /* buffer for block */
155 xfs_dir2_data_entry_t
*dep
; /* block data entry */
156 xfs_dir2_data_unused_t
*dup
; /* block unused entry */
157 char *endptr
; /* end of the data entries */
158 int error
; /* error return value */
159 char *ptr
; /* current data entry */
160 int wantoff
; /* starting block offset */
162 struct xfs_da_geometry
*geo
= args
->geo
;
166 * If the block number in the offset is out of range, we're done.
168 if (xfs_dir2_dataptr_to_db(geo
, ctx
->pos
) > geo
->datablk
)
171 lock_mode
= xfs_ilock_data_map_shared(dp
);
172 error
= xfs_dir3_block_read(args
->trans
, dp
, &bp
);
173 xfs_iunlock(dp
, lock_mode
);
178 * Extract the byte offset we start at from the seek pointer.
179 * We'll skip entries before this.
181 wantoff
= xfs_dir2_dataptr_to_off(geo
, ctx
->pos
);
183 xfs_dir3_data_check(dp
, bp
);
185 * Set up values for the loop.
187 ptr
= (char *)dp
->d_ops
->data_entry_p(hdr
);
188 endptr
= xfs_dir3_data_endp(geo
, hdr
);
191 * Loop over the data portion of the block.
192 * Each object is a real entry (dep) or an unused one (dup).
194 while (ptr
< endptr
) {
197 dup
= (xfs_dir2_data_unused_t
*)ptr
;
201 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
202 ptr
+= be16_to_cpu(dup
->length
);
206 dep
= (xfs_dir2_data_entry_t
*)ptr
;
209 * Bump pointer for the next iteration.
211 ptr
+= dp
->d_ops
->data_entsize(dep
->namelen
);
213 * The entry is before the desired starting point, skip it.
215 if ((char *)dep
- (char *)hdr
< wantoff
)
218 cook
= xfs_dir2_db_off_to_dataptr(geo
, geo
->datablk
,
219 (char *)dep
- (char *)hdr
);
221 ctx
->pos
= cook
& 0x7fffffff;
222 filetype
= dp
->d_ops
->data_get_ftype(dep
);
224 * If it didn't fit, set the final offset to here & return.
226 if (!dir_emit(ctx
, (char *)dep
->name
, dep
->namelen
,
227 be64_to_cpu(dep
->inumber
),
228 xfs_dir3_get_dtype(dp
->i_mount
, filetype
))) {
229 xfs_trans_brelse(args
->trans
, bp
);
235 * Reached the end of the block.
236 * Set the offset to a non-existent block 1 and return.
238 ctx
->pos
= xfs_dir2_db_off_to_dataptr(geo
, geo
->datablk
+ 1, 0) &
240 xfs_trans_brelse(args
->trans
, bp
);
245 * Read a directory block and initiate readahead for blocks beyond that.
246 * We maintain a sliding readahead window of the remaining space in the
247 * buffer rounded up to the nearest block.
250 xfs_dir2_leaf_readbuf(
251 struct xfs_da_args
*args
,
253 xfs_dir2_off_t
*cur_off
,
255 struct xfs_buf
**bpp
)
257 struct xfs_inode
*dp
= args
->dp
;
258 struct xfs_buf
*bp
= NULL
;
259 struct xfs_da_geometry
*geo
= args
->geo
;
260 struct xfs_ifork
*ifp
= XFS_IFORK_PTR(dp
, XFS_DATA_FORK
);
261 struct xfs_bmbt_irec map
;
262 struct blk_plug plug
;
263 xfs_dir2_off_t new_off
;
267 struct xfs_iext_cursor icur
;
271 if (!(ifp
->if_flags
& XFS_IFEXTENTS
)) {
272 error
= xfs_iread_extents(args
->trans
, dp
, XFS_DATA_FORK
);
278 * Look for mapped directory blocks at or above the current offset.
279 * Truncate down to the nearest directory block to start the scanning
282 last_da
= xfs_dir2_byte_to_da(geo
, XFS_DIR2_LEAF_OFFSET
);
283 map_off
= xfs_dir2_db_to_da(geo
, xfs_dir2_byte_to_db(geo
, *cur_off
));
284 if (!xfs_iext_lookup_extent(dp
, ifp
, map_off
, &icur
, &map
))
286 if (map
.br_startoff
>= last_da
)
288 xfs_trim_extent(&map
, map_off
, last_da
- map_off
);
290 /* Read the directory block of that first mapping. */
291 new_off
= xfs_dir2_da_to_byte(geo
, map
.br_startoff
);
292 if (new_off
> *cur_off
)
294 error
= xfs_dir3_data_read(args
->trans
, dp
, map
.br_startoff
, -1, &bp
);
299 * Start readahead for the next bufsize's worth of dir data blocks.
300 * We may have already issued readahead for some of that range;
301 * ra_blk tracks the last block we tried to read(ahead).
303 ra_want
= howmany(bufsize
+ geo
->blksize
, (1 << geo
->fsblog
));
304 if (*ra_blk
>= last_da
)
306 else if (*ra_blk
== 0)
307 *ra_blk
= map
.br_startoff
;
308 next_ra
= map
.br_startoff
+ geo
->fsbcount
;
309 if (next_ra
>= last_da
)
311 if (map
.br_blockcount
< geo
->fsbcount
&&
312 !xfs_iext_next_extent(ifp
, &icur
, &map
))
314 if (map
.br_startoff
>= last_da
)
316 xfs_trim_extent(&map
, next_ra
, last_da
- next_ra
);
318 /* Start ra for each dir (not fs) block that has a mapping. */
319 blk_start_plug(&plug
);
320 while (ra_want
> 0) {
321 next_ra
= roundup((xfs_dablk_t
)map
.br_startoff
, geo
->fsbcount
);
322 while (ra_want
> 0 &&
323 next_ra
< map
.br_startoff
+ map
.br_blockcount
) {
324 if (next_ra
>= last_da
) {
328 if (next_ra
> *ra_blk
) {
329 xfs_dir3_data_readahead(dp
, next_ra
, -2);
332 ra_want
-= geo
->fsbcount
;
333 next_ra
+= geo
->fsbcount
;
335 if (!xfs_iext_next_extent(ifp
, &icur
, &map
)) {
340 blk_finish_plug(&plug
);
351 * Getdents (readdir) for leaf and node directories.
352 * This reads the data blocks only, so is the same for both forms.
355 xfs_dir2_leaf_getdents(
356 struct xfs_da_args
*args
,
357 struct dir_context
*ctx
,
360 struct xfs_inode
*dp
= args
->dp
;
361 struct xfs_buf
*bp
= NULL
; /* data block buffer */
362 xfs_dir2_data_hdr_t
*hdr
; /* data block header */
363 xfs_dir2_data_entry_t
*dep
; /* data entry */
364 xfs_dir2_data_unused_t
*dup
; /* unused entry */
365 char *ptr
= NULL
; /* pointer to current data */
366 struct xfs_da_geometry
*geo
= args
->geo
;
367 xfs_dablk_t rablk
= 0; /* current readahead block */
368 xfs_dir2_off_t curoff
; /* current overall offset */
369 int length
; /* temporary length value */
370 int byteoff
; /* offset in current block */
372 int error
= 0; /* error return value */
375 * If the offset is at or past the largest allowed value,
376 * give up right away.
378 if (ctx
->pos
>= XFS_DIR2_MAX_DATAPTR
)
382 * Inside the loop we keep the main offset value as a byte offset
383 * in the directory file.
385 curoff
= xfs_dir2_dataptr_to_byte(ctx
->pos
);
388 * Loop over directory entries until we reach the end offset.
389 * Get more blocks and readahead as necessary.
391 while (curoff
< XFS_DIR2_LEAF_OFFSET
) {
395 * If we have no buffer, or we're off the end of the
396 * current buffer, need to get another one.
398 if (!bp
|| ptr
>= (char *)bp
->b_addr
+ geo
->blksize
) {
400 xfs_trans_brelse(args
->trans
, bp
);
404 lock_mode
= xfs_ilock_data_map_shared(dp
);
405 error
= xfs_dir2_leaf_readbuf(args
, bufsize
, &curoff
,
407 xfs_iunlock(dp
, lock_mode
);
412 xfs_dir3_data_check(dp
, bp
);
414 * Find our position in the block.
416 ptr
= (char *)dp
->d_ops
->data_entry_p(hdr
);
417 byteoff
= xfs_dir2_byte_to_off(geo
, curoff
);
419 * Skip past the header.
422 curoff
+= dp
->d_ops
->data_entry_offset
;
424 * Skip past entries until we reach our offset.
427 while ((char *)ptr
- (char *)hdr
< byteoff
) {
428 dup
= (xfs_dir2_data_unused_t
*)ptr
;
430 if (be16_to_cpu(dup
->freetag
)
431 == XFS_DIR2_DATA_FREE_TAG
) {
433 length
= be16_to_cpu(dup
->length
);
437 dep
= (xfs_dir2_data_entry_t
*)ptr
;
439 dp
->d_ops
->data_entsize(dep
->namelen
);
443 * Now set our real offset.
446 xfs_dir2_db_off_to_byte(geo
,
447 xfs_dir2_byte_to_db(geo
, curoff
),
448 (char *)ptr
- (char *)hdr
);
449 if (ptr
>= (char *)hdr
+ geo
->blksize
) {
455 * We have a pointer to an entry.
458 dup
= (xfs_dir2_data_unused_t
*)ptr
;
460 * No, it's unused, skip over it.
462 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
463 length
= be16_to_cpu(dup
->length
);
469 dep
= (xfs_dir2_data_entry_t
*)ptr
;
470 length
= dp
->d_ops
->data_entsize(dep
->namelen
);
471 filetype
= dp
->d_ops
->data_get_ftype(dep
);
473 ctx
->pos
= xfs_dir2_byte_to_dataptr(curoff
) & 0x7fffffff;
474 if (!dir_emit(ctx
, (char *)dep
->name
, dep
->namelen
,
475 be64_to_cpu(dep
->inumber
),
476 xfs_dir3_get_dtype(dp
->i_mount
, filetype
)))
480 * Advance to next entry in the block.
484 /* bufsize may have just been a guess; don't go negative */
485 bufsize
= bufsize
> length
? bufsize
- length
: 0;
489 * All done. Set output offset value to current offset.
491 if (curoff
> xfs_dir2_dataptr_to_byte(XFS_DIR2_MAX_DATAPTR
))
492 ctx
->pos
= XFS_DIR2_MAX_DATAPTR
& 0x7fffffff;
494 ctx
->pos
= xfs_dir2_byte_to_dataptr(curoff
) & 0x7fffffff;
496 xfs_trans_brelse(args
->trans
, bp
);
503 * If supplied, the transaction collects locked dir buffers to avoid
504 * nested buffer deadlocks. This function does not dirty the
505 * transaction. The caller should ensure that the inode is locked
506 * before calling this function.
510 struct xfs_trans
*tp
,
511 struct xfs_inode
*dp
,
512 struct dir_context
*ctx
,
515 struct xfs_da_args args
= { NULL
};
519 trace_xfs_readdir(dp
);
521 if (XFS_FORCED_SHUTDOWN(dp
->i_mount
))
524 ASSERT(S_ISDIR(VFS_I(dp
)->i_mode
));
525 XFS_STATS_INC(dp
->i_mount
, xs_dir_getdents
);
528 args
.geo
= dp
->i_mount
->m_dir_geo
;
531 if (dp
->i_d
.di_format
== XFS_DINODE_FMT_LOCAL
)
532 rval
= xfs_dir2_sf_getdents(&args
, ctx
);
533 else if ((rval
= xfs_dir2_isblock(&args
, &v
)))
536 rval
= xfs_dir2_block_getdents(&args
, ctx
);
538 rval
= xfs_dir2_leaf_getdents(&args
, ctx
, bufsize
);