xfs: fix data corruption w/ unaligned reflink ranges
[sfrench/cifs-2.6.git] / fs / xfs / xfs_dir2_readdir.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4  * Copyright (c) 2013 Red Hat, Inc.
5  * All Rights Reserved.
6  */
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_bit.h"
13 #include "xfs_mount.h"
14 #include "xfs_da_format.h"
15 #include "xfs_da_btree.h"
16 #include "xfs_inode.h"
17 #include "xfs_dir2.h"
18 #include "xfs_dir2_priv.h"
19 #include "xfs_error.h"
20 #include "xfs_trace.h"
21 #include "xfs_bmap.h"
22 #include "xfs_trans.h"
23
24 /*
25  * Directory file type support functions
26  */
27 static unsigned char xfs_dir3_filetype_table[] = {
28         DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK,
29         DT_FIFO, DT_SOCK, DT_LNK, DT_WHT,
30 };
31
32 unsigned char
33 xfs_dir3_get_dtype(
34         struct xfs_mount        *mp,
35         uint8_t                 filetype)
36 {
37         if (!xfs_sb_version_hasftype(&mp->m_sb))
38                 return DT_UNKNOWN;
39
40         if (filetype >= XFS_DIR3_FT_MAX)
41                 return DT_UNKNOWN;
42
43         return xfs_dir3_filetype_table[filetype];
44 }
45
46 STATIC int
47 xfs_dir2_sf_getdents(
48         struct xfs_da_args      *args,
49         struct dir_context      *ctx)
50 {
51         int                     i;              /* shortform entry number */
52         struct xfs_inode        *dp = args->dp; /* incore directory inode */
53         xfs_dir2_dataptr_t      off;            /* current entry's offset */
54         xfs_dir2_sf_entry_t     *sfep;          /* shortform directory entry */
55         xfs_dir2_sf_hdr_t       *sfp;           /* shortform structure */
56         xfs_dir2_dataptr_t      dot_offset;
57         xfs_dir2_dataptr_t      dotdot_offset;
58         xfs_ino_t               ino;
59         struct xfs_da_geometry  *geo = args->geo;
60
61         ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
62         ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
63         ASSERT(dp->i_df.if_u1.if_data != NULL);
64
65         sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
66
67         /*
68          * If the block number in the offset is out of range, we're done.
69          */
70         if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
71                 return 0;
72
73         /*
74          * Precalculate offsets for . and .. as we will always need them.
75          *
76          * XXX(hch): the second argument is sometimes 0 and sometimes
77          * geo->datablk
78          */
79         dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
80                                                 dp->d_ops->data_dot_offset);
81         dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
82                                                 dp->d_ops->data_dotdot_offset);
83
84         /*
85          * Put . entry unless we're starting past it.
86          */
87         if (ctx->pos <= dot_offset) {
88                 ctx->pos = dot_offset & 0x7fffffff;
89                 if (!dir_emit(ctx, ".", 1, dp->i_ino, DT_DIR))
90                         return 0;
91         }
92
93         /*
94          * Put .. entry unless we're starting past it.
95          */
96         if (ctx->pos <= dotdot_offset) {
97                 ino = dp->d_ops->sf_get_parent_ino(sfp);
98                 ctx->pos = dotdot_offset & 0x7fffffff;
99                 if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
100                         return 0;
101         }
102
103         /*
104          * Loop while there are more entries and put'ing works.
105          */
106         sfep = xfs_dir2_sf_firstentry(sfp);
107         for (i = 0; i < sfp->count; i++) {
108                 uint8_t filetype;
109
110                 off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
111                                 xfs_dir2_sf_get_offset(sfep));
112
113                 if (ctx->pos > off) {
114                         sfep = dp->d_ops->sf_nextentry(sfp, sfep);
115                         continue;
116                 }
117
118                 ino = dp->d_ops->sf_get_ino(sfp, sfep);
119                 filetype = dp->d_ops->sf_get_ftype(sfep);
120                 ctx->pos = off & 0x7fffffff;
121                 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
122                             xfs_dir3_get_dtype(dp->i_mount, filetype)))
123                         return 0;
124                 sfep = dp->d_ops->sf_nextentry(sfp, sfep);
125         }
126
127         ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
128                                                                 0x7fffffff;
129         return 0;
130 }
131
132 /*
133  * Readdir for block directories.
134  */
135 STATIC int
136 xfs_dir2_block_getdents(
137         struct xfs_da_args      *args,
138         struct dir_context      *ctx)
139 {
140         struct xfs_inode        *dp = args->dp; /* incore directory inode */
141         xfs_dir2_data_hdr_t     *hdr;           /* block header */
142         struct xfs_buf          *bp;            /* buffer for block */
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         char                    *ptr;           /* current data entry */
148         int                     wantoff;        /* starting block offset */
149         xfs_off_t               cook;
150         struct xfs_da_geometry  *geo = args->geo;
151         int                     lock_mode;
152
153         /*
154          * If the block number in the offset is out of range, we're done.
155          */
156         if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
157                 return 0;
158
159         lock_mode = xfs_ilock_data_map_shared(dp);
160         error = xfs_dir3_block_read(args->trans, dp, &bp);
161         xfs_iunlock(dp, lock_mode);
162         if (error)
163                 return error;
164
165         /*
166          * Extract the byte offset we start at from the seek pointer.
167          * We'll skip entries before this.
168          */
169         wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
170         hdr = bp->b_addr;
171         xfs_dir3_data_check(dp, bp);
172         /*
173          * Set up values for the loop.
174          */
175         ptr = (char *)dp->d_ops->data_entry_p(hdr);
176         endptr = xfs_dir3_data_endp(geo, hdr);
177
178         /*
179          * Loop over the data portion of the block.
180          * Each object is a real entry (dep) or an unused one (dup).
181          */
182         while (ptr < endptr) {
183                 uint8_t filetype;
184
185                 dup = (xfs_dir2_data_unused_t *)ptr;
186                 /*
187                  * Unused, skip it.
188                  */
189                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
190                         ptr += be16_to_cpu(dup->length);
191                         continue;
192                 }
193
194                 dep = (xfs_dir2_data_entry_t *)ptr;
195
196                 /*
197                  * Bump pointer for the next iteration.
198                  */
199                 ptr += dp->d_ops->data_entsize(dep->namelen);
200                 /*
201                  * The entry is before the desired starting point, skip it.
202                  */
203                 if ((char *)dep - (char *)hdr < wantoff)
204                         continue;
205
206                 cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
207                                             (char *)dep - (char *)hdr);
208
209                 ctx->pos = cook & 0x7fffffff;
210                 filetype = dp->d_ops->data_get_ftype(dep);
211                 /*
212                  * If it didn't fit, set the final offset to here & return.
213                  */
214                 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
215                             be64_to_cpu(dep->inumber),
216                             xfs_dir3_get_dtype(dp->i_mount, filetype))) {
217                         xfs_trans_brelse(args->trans, bp);
218                         return 0;
219                 }
220         }
221
222         /*
223          * Reached the end of the block.
224          * Set the offset to a non-existent block 1 and return.
225          */
226         ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
227                                                                 0x7fffffff;
228         xfs_trans_brelse(args->trans, bp);
229         return 0;
230 }
231
232 /*
233  * Read a directory block and initiate readahead for blocks beyond that.
234  * We maintain a sliding readahead window of the remaining space in the
235  * buffer rounded up to the nearest block.
236  */
237 STATIC int
238 xfs_dir2_leaf_readbuf(
239         struct xfs_da_args      *args,
240         size_t                  bufsize,
241         xfs_dir2_off_t          *cur_off,
242         xfs_dablk_t             *ra_blk,
243         struct xfs_buf          **bpp)
244 {
245         struct xfs_inode        *dp = args->dp;
246         struct xfs_buf          *bp = NULL;
247         struct xfs_da_geometry  *geo = args->geo;
248         struct xfs_ifork        *ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
249         struct xfs_bmbt_irec    map;
250         struct blk_plug         plug;
251         xfs_dir2_off_t          new_off;
252         xfs_dablk_t             next_ra;
253         xfs_dablk_t             map_off;
254         xfs_dablk_t             last_da;
255         struct xfs_iext_cursor  icur;
256         int                     ra_want;
257         int                     error = 0;
258
259         if (!(ifp->if_flags & XFS_IFEXTENTS)) {
260                 error = xfs_iread_extents(args->trans, dp, XFS_DATA_FORK);
261                 if (error)
262                         goto out;
263         }
264
265         /*
266          * Look for mapped directory blocks at or above the current offset.
267          * Truncate down to the nearest directory block to start the scanning
268          * operation.
269          */
270         last_da = xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET);
271         map_off = xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, *cur_off));
272         if (!xfs_iext_lookup_extent(dp, ifp, map_off, &icur, &map))
273                 goto out;
274         if (map.br_startoff >= last_da)
275                 goto out;
276         xfs_trim_extent(&map, map_off, last_da - map_off);
277
278         /* Read the directory block of that first mapping. */
279         new_off = xfs_dir2_da_to_byte(geo, map.br_startoff);
280         if (new_off > *cur_off)
281                 *cur_off = new_off;
282         error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, -1, &bp);
283         if (error)
284                 goto out;
285
286         /*
287          * Start readahead for the next bufsize's worth of dir data blocks.
288          * We may have already issued readahead for some of that range;
289          * ra_blk tracks the last block we tried to read(ahead).
290          */
291         ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog));
292         if (*ra_blk >= last_da)
293                 goto out;
294         else if (*ra_blk == 0)
295                 *ra_blk = map.br_startoff;
296         next_ra = map.br_startoff + geo->fsbcount;
297         if (next_ra >= last_da)
298                 goto out_no_ra;
299         if (map.br_blockcount < geo->fsbcount &&
300             !xfs_iext_next_extent(ifp, &icur, &map))
301                 goto out_no_ra;
302         if (map.br_startoff >= last_da)
303                 goto out_no_ra;
304         xfs_trim_extent(&map, next_ra, last_da - next_ra);
305
306         /* Start ra for each dir (not fs) block that has a mapping. */
307         blk_start_plug(&plug);
308         while (ra_want > 0) {
309                 next_ra = roundup((xfs_dablk_t)map.br_startoff, geo->fsbcount);
310                 while (ra_want > 0 &&
311                        next_ra < map.br_startoff + map.br_blockcount) {
312                         if (next_ra >= last_da) {
313                                 *ra_blk = last_da;
314                                 break;
315                         }
316                         if (next_ra > *ra_blk) {
317                                 xfs_dir3_data_readahead(dp, next_ra, -2);
318                                 *ra_blk = next_ra;
319                         }
320                         ra_want -= geo->fsbcount;
321                         next_ra += geo->fsbcount;
322                 }
323                 if (!xfs_iext_next_extent(ifp, &icur, &map)) {
324                         *ra_blk = last_da;
325                         break;
326                 }
327         }
328         blk_finish_plug(&plug);
329
330 out:
331         *bpp = bp;
332         return error;
333 out_no_ra:
334         *ra_blk = last_da;
335         goto out;
336 }
337
338 /*
339  * Getdents (readdir) for leaf and node directories.
340  * This reads the data blocks only, so is the same for both forms.
341  */
342 STATIC int
343 xfs_dir2_leaf_getdents(
344         struct xfs_da_args      *args,
345         struct dir_context      *ctx,
346         size_t                  bufsize)
347 {
348         struct xfs_inode        *dp = args->dp;
349         struct xfs_buf          *bp = NULL;     /* data block buffer */
350         xfs_dir2_data_hdr_t     *hdr;           /* data block header */
351         xfs_dir2_data_entry_t   *dep;           /* data entry */
352         xfs_dir2_data_unused_t  *dup;           /* unused entry */
353         char                    *ptr = NULL;    /* pointer to current data */
354         struct xfs_da_geometry  *geo = args->geo;
355         xfs_dablk_t             rablk = 0;      /* current readahead block */
356         xfs_dir2_off_t          curoff;         /* current overall offset */
357         int                     length;         /* temporary length value */
358         int                     byteoff;        /* offset in current block */
359         int                     lock_mode;
360         int                     error = 0;      /* error return value */
361
362         /*
363          * If the offset is at or past the largest allowed value,
364          * give up right away.
365          */
366         if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
367                 return 0;
368
369         /*
370          * Inside the loop we keep the main offset value as a byte offset
371          * in the directory file.
372          */
373         curoff = xfs_dir2_dataptr_to_byte(ctx->pos);
374
375         /*
376          * Loop over directory entries until we reach the end offset.
377          * Get more blocks and readahead as necessary.
378          */
379         while (curoff < XFS_DIR2_LEAF_OFFSET) {
380                 uint8_t filetype;
381
382                 /*
383                  * If we have no buffer, or we're off the end of the
384                  * current buffer, need to get another one.
385                  */
386                 if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
387                         if (bp) {
388                                 xfs_trans_brelse(args->trans, bp);
389                                 bp = NULL;
390                         }
391
392                         lock_mode = xfs_ilock_data_map_shared(dp);
393                         error = xfs_dir2_leaf_readbuf(args, bufsize, &curoff,
394                                         &rablk, &bp);
395                         xfs_iunlock(dp, lock_mode);
396                         if (error || !bp)
397                                 break;
398
399                         hdr = bp->b_addr;
400                         xfs_dir3_data_check(dp, bp);
401                         /*
402                          * Find our position in the block.
403                          */
404                         ptr = (char *)dp->d_ops->data_entry_p(hdr);
405                         byteoff = xfs_dir2_byte_to_off(geo, curoff);
406                         /*
407                          * Skip past the header.
408                          */
409                         if (byteoff == 0)
410                                 curoff += dp->d_ops->data_entry_offset;
411                         /*
412                          * Skip past entries until we reach our offset.
413                          */
414                         else {
415                                 while ((char *)ptr - (char *)hdr < byteoff) {
416                                         dup = (xfs_dir2_data_unused_t *)ptr;
417
418                                         if (be16_to_cpu(dup->freetag)
419                                                   == XFS_DIR2_DATA_FREE_TAG) {
420
421                                                 length = be16_to_cpu(dup->length);
422                                                 ptr += length;
423                                                 continue;
424                                         }
425                                         dep = (xfs_dir2_data_entry_t *)ptr;
426                                         length =
427                                            dp->d_ops->data_entsize(dep->namelen);
428                                         ptr += length;
429                                 }
430                                 /*
431                                  * Now set our real offset.
432                                  */
433                                 curoff =
434                                         xfs_dir2_db_off_to_byte(geo,
435                                             xfs_dir2_byte_to_db(geo, curoff),
436                                             (char *)ptr - (char *)hdr);
437                                 if (ptr >= (char *)hdr + geo->blksize) {
438                                         continue;
439                                 }
440                         }
441                 }
442                 /*
443                  * We have a pointer to an entry.
444                  * Is it a live one?
445                  */
446                 dup = (xfs_dir2_data_unused_t *)ptr;
447                 /*
448                  * No, it's unused, skip over it.
449                  */
450                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
451                         length = be16_to_cpu(dup->length);
452                         ptr += length;
453                         curoff += length;
454                         continue;
455                 }
456
457                 dep = (xfs_dir2_data_entry_t *)ptr;
458                 length = dp->d_ops->data_entsize(dep->namelen);
459                 filetype = dp->d_ops->data_get_ftype(dep);
460
461                 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
462                 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
463                             be64_to_cpu(dep->inumber),
464                             xfs_dir3_get_dtype(dp->i_mount, filetype)))
465                         break;
466
467                 /*
468                  * Advance to next entry in the block.
469                  */
470                 ptr += length;
471                 curoff += length;
472                 /* bufsize may have just been a guess; don't go negative */
473                 bufsize = bufsize > length ? bufsize - length : 0;
474         }
475
476         /*
477          * All done.  Set output offset value to current offset.
478          */
479         if (curoff > xfs_dir2_dataptr_to_byte(XFS_DIR2_MAX_DATAPTR))
480                 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
481         else
482                 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
483         if (bp)
484                 xfs_trans_brelse(args->trans, bp);
485         return error;
486 }
487
488 /*
489  * Read a directory.
490  *
491  * If supplied, the transaction collects locked dir buffers to avoid
492  * nested buffer deadlocks.  This function does not dirty the
493  * transaction.  The caller should ensure that the inode is locked
494  * before calling this function.
495  */
496 int
497 xfs_readdir(
498         struct xfs_trans        *tp,
499         struct xfs_inode        *dp,
500         struct dir_context      *ctx,
501         size_t                  bufsize)
502 {
503         struct xfs_da_args      args = { NULL };
504         int                     rval;
505         int                     v;
506
507         trace_xfs_readdir(dp);
508
509         if (XFS_FORCED_SHUTDOWN(dp->i_mount))
510                 return -EIO;
511
512         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
513         XFS_STATS_INC(dp->i_mount, xs_dir_getdents);
514
515         args.dp = dp;
516         args.geo = dp->i_mount->m_dir_geo;
517         args.trans = tp;
518
519         if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
520                 rval = xfs_dir2_sf_getdents(&args, ctx);
521         else if ((rval = xfs_dir2_isblock(&args, &v)))
522                 ;
523         else if (v)
524                 rval = xfs_dir2_block_getdents(&args, ctx);
525         else
526                 rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
527
528         return rval;
529 }