Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_mount.h"
13 : #include "xfs_inode.h"
14 : #include "xfs_btree.h"
15 : #include "xfs_ialloc.h"
16 : #include "xfs_ialloc_btree.h"
17 : #include "xfs_iwalk.h"
18 : #include "xfs_itable.h"
19 : #include "xfs_error.h"
20 : #include "xfs_icache.h"
21 : #include "xfs_health.h"
22 : #include "xfs_trans.h"
23 :
24 : /*
25 : * Bulk Stat
26 : * =========
27 : *
28 : * Use the inode walking functions to fill out struct xfs_bulkstat for every
29 : * allocated inode, then pass the stat information to some externally provided
30 : * iteration function.
31 : */
32 :
33 : struct xfs_bstat_chunk {
34 : bulkstat_one_fmt_pf formatter;
35 : struct xfs_ibulk *breq;
36 : struct xfs_bulkstat *buf;
37 : };
38 :
39 : static inline bool
40 : want_metadir(
41 : struct xfs_inode *ip,
42 : struct xfs_ibulk *breq)
43 : {
44 81792179650 : return xfs_is_metadir_inode(ip) &&
45 81752408440 : S_ISDIR(VFS_I(ip)->i_mode) &&
46 6687027 : (breq->flags & XFS_IBULK_METADIR);
47 : }
48 :
49 : /*
50 : * Fill out the bulkstat info for a single inode and report it somewhere.
51 : *
52 : * bc->breq->lastino is effectively the inode cursor as we walk through the
53 : * filesystem. Therefore, we update it any time we need to move the cursor
54 : * forward, regardless of whether or not we're sending any bstat information
55 : * back to userspace. If the inode is internal metadata or, has been freed
56 : * out from under us, we just simply keep going.
57 : *
58 : * However, if any other type of error happens we want to stop right where we
59 : * are so that userspace will call back with exact number of the bad inode and
60 : * we can send back an error code.
61 : *
62 : * Note that if the formatter tells us there's no space left in the buffer we
63 : * move the cursor forward and abort the walk.
64 : */
65 : STATIC int
66 82153307268 : xfs_bulkstat_one_int(
67 : struct xfs_mount *mp,
68 : struct mnt_idmap *idmap,
69 : struct xfs_trans *tp,
70 : xfs_ino_t ino,
71 : struct xfs_bstat_chunk *bc)
72 : {
73 82153307268 : struct user_namespace *sb_userns = mp->m_super->s_user_ns;
74 82153307268 : struct xfs_inode *ip; /* incore inode pointer */
75 82153307268 : struct inode *inode;
76 82153307268 : struct xfs_bulkstat *buf = bc->buf;
77 82153307268 : xfs_extnum_t nextents;
78 82153307268 : int error = -EINVAL;
79 82153307268 : vfsuid_t vfsuid;
80 82153307268 : vfsgid_t vfsgid;
81 :
82 82153307268 : error = xfs_iget(mp, tp, ino,
83 : (XFS_IGET_DONTCACHE | XFS_IGET_UNTRUSTED),
84 : XFS_ILOCK_SHARED, &ip);
85 82377223988 : if (error == -ENOENT || error == -EINVAL)
86 2264194 : goto out_advance;
87 82374959794 : if (error)
88 2417 : goto out;
89 :
90 82374957377 : ASSERT(ip != NULL);
91 82374957377 : ASSERT(ip->i_imap.im_blkno != 0);
92 82374957377 : inode = VFS_I(ip);
93 82374957377 : vfsuid = i_uid_into_vfsuid(idmap, inode);
94 81587924937 : vfsgid = i_gid_into_vfsgid(idmap, inode);
95 :
96 : /* If we want metadata directories, push out the bare minimum. */
97 81792179650 : if (want_metadir(ip, bc->breq)) {
98 90618 : memset(buf, 0, sizeof(*buf));
99 90618 : buf->bs_ino = ino;
100 90618 : buf->bs_gen = inode->i_generation;
101 90618 : buf->bs_mode = inode->i_mode & S_IFMT;
102 90618 : xfs_bulkstat_health(ip, buf);
103 90618 : buf->bs_version = XFS_BULKSTAT_VERSION_V5;
104 90618 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
105 90618 : xfs_irele(ip);
106 :
107 90618 : error = bc->formatter(bc->breq, buf);
108 90618 : if (!error || error == -ECANCELED)
109 90618 : goto out_advance;
110 0 : goto out;
111 : }
112 :
113 : /* If this is a private inode, don't leak its details to userspace. */
114 81752317822 : if (IS_PRIVATE(inode) || xfs_internal_inum(mp, ino)) {
115 33153037 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
116 39811594 : xfs_irele(ip);
117 40145492 : error = -EINVAL;
118 40145492 : goto out_advance;
119 : }
120 :
121 : /* xfs_iget returns the following without needing
122 : * further change.
123 : */
124 82498842650 : buf->bs_projectid = ip->i_projid;
125 82498842650 : buf->bs_ino = ino;
126 82498842650 : buf->bs_uid = from_kuid(sb_userns, vfsuid_into_kuid(vfsuid));
127 82320971741 : buf->bs_gid = from_kgid(sb_userns, vfsgid_into_kgid(vfsgid));
128 82039780817 : buf->bs_size = ip->i_disk_size;
129 :
130 82039780817 : buf->bs_nlink = inode->i_nlink;
131 82039780817 : buf->bs_atime = inode->i_atime.tv_sec;
132 82039780817 : buf->bs_atime_nsec = inode->i_atime.tv_nsec;
133 82039780817 : buf->bs_mtime = inode->i_mtime.tv_sec;
134 82039780817 : buf->bs_mtime_nsec = inode->i_mtime.tv_nsec;
135 82039780817 : buf->bs_ctime = inode->i_ctime.tv_sec;
136 82039780817 : buf->bs_ctime_nsec = inode->i_ctime.tv_nsec;
137 82039780817 : buf->bs_gen = inode->i_generation;
138 82039780817 : buf->bs_mode = inode->i_mode;
139 :
140 82039780817 : buf->bs_xflags = xfs_ip2xflags(ip);
141 81631565096 : buf->bs_extsize_blks = ip->i_extsize;
142 :
143 81631565096 : nextents = xfs_ifork_nextents(&ip->i_df);
144 81631565096 : if (!(bc->breq->flags & XFS_IBULK_NREXT64))
145 81333984607 : buf->bs_extents = min(nextents, XFS_MAX_EXTCNT_DATA_FORK_SMALL);
146 : else
147 297580489 : buf->bs_extents64 = nextents;
148 :
149 81631565096 : xfs_bulkstat_health(ip, buf);
150 83142882967 : buf->bs_aextents = xfs_ifork_nextents(&ip->i_af);
151 83142882967 : buf->bs_forkoff = xfs_inode_fork_boff(ip);
152 83142882967 : buf->bs_version = XFS_BULKSTAT_VERSION_V5;
153 :
154 83142882967 : if (xfs_has_v3inodes(mp)) {
155 82883073391 : buf->bs_btime = ip->i_crtime.tv_sec;
156 82883073391 : buf->bs_btime_nsec = ip->i_crtime.tv_nsec;
157 82883073391 : if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
158 39786 : buf->bs_cowextsize_blks = ip->i_cowextsize;
159 : }
160 :
161 83142882967 : switch (ip->i_df.if_format) {
162 30961114426 : case XFS_DINODE_FMT_DEV:
163 30961114426 : buf->bs_rdev = sysv_encode_dev(inode->i_rdev);
164 30961114426 : buf->bs_blksize = BLKDEV_IOSIZE;
165 30961114426 : buf->bs_blocks = 0;
166 30961114426 : break;
167 16107214381 : case XFS_DINODE_FMT_LOCAL:
168 16107214381 : buf->bs_rdev = 0;
169 16107214381 : buf->bs_blksize = mp->m_sb.sb_blocksize;
170 16107214381 : buf->bs_blocks = 0;
171 16107214381 : break;
172 36074554160 : case XFS_DINODE_FMT_EXTENTS:
173 : case XFS_DINODE_FMT_BTREE:
174 36074554160 : buf->bs_rdev = 0;
175 36074554160 : buf->bs_blksize = mp->m_sb.sb_blocksize;
176 36074554160 : buf->bs_blocks = ip->i_nblocks + ip->i_delayed_blks;
177 36074554160 : break;
178 : }
179 83142882967 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
180 81388696848 : xfs_irele(ip);
181 :
182 82444246143 : error = bc->formatter(bc->breq, buf);
183 81845047391 : if (error == -ECANCELED)
184 549006677 : goto out_advance;
185 81296040714 : if (error)
186 0 : goto out;
187 :
188 81296040714 : out_advance:
189 : /*
190 : * Advance the cursor to the inode that comes after the one we just
191 : * looked at. We want the caller to move along if the bulkstat
192 : * information was copied successfully; if we tried to grab the inode
193 : * but it's no longer allocated; or if it's internal metadata.
194 : */
195 81887547695 : bc->breq->startino = ino + 1;
196 81887550112 : out:
197 81887550112 : return error;
198 : }
199 :
200 : /* Bulkstat a single inode. */
201 : int
202 2253450 : xfs_bulkstat_one(
203 : struct xfs_ibulk *breq,
204 : bulkstat_one_fmt_pf formatter)
205 : {
206 2253450 : struct xfs_bstat_chunk bc = {
207 : .formatter = formatter,
208 : .breq = breq,
209 : };
210 2253450 : struct xfs_trans *tp;
211 2253450 : int error;
212 :
213 2253450 : if (breq->idmap != &nop_mnt_idmap) {
214 0 : xfs_warn_ratelimited(breq->mp,
215 : "bulkstat not supported inside of idmapped mounts.");
216 0 : return -EINVAL;
217 : }
218 :
219 2253450 : ASSERT(breq->icount == 1);
220 :
221 2253450 : bc.buf = kmem_zalloc(sizeof(struct xfs_bulkstat),
222 : KM_MAYFAIL);
223 2253099 : if (!bc.buf)
224 : return -ENOMEM;
225 :
226 : /*
227 : * Grab an empty transaction so that we can use its recursive buffer
228 : * locking abilities to detect cycles in the inobt without deadlocking.
229 : */
230 2253099 : error = xfs_trans_alloc_empty(breq->mp, &tp);
231 2253335 : if (error)
232 0 : goto out;
233 :
234 2253335 : error = xfs_bulkstat_one_int(breq->mp, breq->idmap, tp,
235 : breq->startino, &bc);
236 2253397 : xfs_trans_cancel(tp);
237 2253530 : out:
238 2253530 : kmem_free(bc.buf);
239 :
240 : /*
241 : * If we reported one inode to userspace then we abort because we hit
242 : * the end of the buffer. Don't leak that back to userspace.
243 : */
244 2253460 : if (error == -ECANCELED)
245 1094099 : error = 0;
246 :
247 : return error;
248 : }
249 :
250 : static int
251 81670730064 : xfs_bulkstat_iwalk(
252 : struct xfs_mount *mp,
253 : struct xfs_trans *tp,
254 : xfs_ino_t ino,
255 : void *data)
256 : {
257 81670730064 : struct xfs_bstat_chunk *bc = data;
258 81670730064 : int error;
259 :
260 81670730064 : error = xfs_bulkstat_one_int(mp, bc->breq->idmap, tp, ino, data);
261 : /* bulkstat just skips over missing inodes */
262 81445927614 : if (error == -ENOENT || error == -EINVAL)
263 41165980 : return 0;
264 : return error;
265 : }
266 :
267 : /*
268 : * Check the incoming lastino parameter.
269 : *
270 : * We allow any inode value that could map to physical space inside the
271 : * filesystem because if there are no inodes there, bulkstat moves on to the
272 : * next chunk. In other words, the magic agino value of zero takes us to the
273 : * first chunk in the AG, and an agino value past the end of the AG takes us to
274 : * the first chunk in the next AG.
275 : *
276 : * Therefore we can end early if the requested inode is beyond the end of the
277 : * filesystem or doesn't map properly.
278 : */
279 : static inline bool
280 557183866 : xfs_bulkstat_already_done(
281 : struct xfs_mount *mp,
282 : xfs_ino_t startino)
283 : {
284 557183866 : xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino);
285 557183866 : xfs_agino_t agino = XFS_INO_TO_AGINO(mp, startino);
286 :
287 557183866 : return agno >= mp->m_sb.sb_agcount ||
288 557172902 : startino != XFS_AGINO_TO_INO(mp, agno, agino);
289 : }
290 :
291 : /* Return stat information in bulk (by-inode) for the filesystem. */
292 : int
293 552244631 : xfs_bulkstat(
294 : struct xfs_ibulk *breq,
295 : bulkstat_one_fmt_pf formatter)
296 : {
297 552244631 : struct xfs_bstat_chunk bc = {
298 : .formatter = formatter,
299 : .breq = breq,
300 : };
301 552244631 : struct xfs_trans *tp;
302 552244631 : unsigned int iwalk_flags = 0;
303 552244631 : int error;
304 :
305 552244631 : if (breq->idmap != &nop_mnt_idmap) {
306 0 : xfs_warn_ratelimited(breq->mp,
307 : "bulkstat not supported inside of idmapped mounts.");
308 0 : return -EINVAL;
309 : }
310 552244631 : if (xfs_bulkstat_already_done(breq->mp, breq->startino))
311 : return 0;
312 :
313 552221627 : bc.buf = kmem_zalloc(sizeof(struct xfs_bulkstat),
314 : KM_MAYFAIL);
315 552236784 : if (!bc.buf)
316 : return -ENOMEM;
317 :
318 : /*
319 : * Grab an empty transaction so that we can use its recursive buffer
320 : * locking abilities to detect cycles in the inobt without deadlocking.
321 : */
322 552236784 : error = xfs_trans_alloc_empty(breq->mp, &tp);
323 552286553 : if (error)
324 0 : goto out;
325 :
326 552286553 : if (breq->flags & XFS_IBULK_SAME_AG)
327 87736 : iwalk_flags |= XFS_IWALK_SAME_AG;
328 :
329 552286553 : error = xfs_iwalk(breq->mp, tp, breq->startino, iwalk_flags,
330 : xfs_bulkstat_iwalk, breq->icount, &bc);
331 552306520 : xfs_trans_cancel(tp);
332 552294758 : out:
333 552294758 : kmem_free(bc.buf);
334 :
335 : /*
336 : * We found some inodes, so clear the error status and return them.
337 : * The lastino pointer will point directly at the inode that triggered
338 : * any error that occurred, so on the next call the error will be
339 : * triggered again and propagated to userspace as there will be no
340 : * formatted inodes in the buffer.
341 : */
342 552317696 : if (breq->ocount > 0)
343 550122762 : error = 0;
344 :
345 : return error;
346 : }
347 :
348 : /* Convert bulkstat (v5) to bstat (v1). */
349 : void
350 81841758031 : xfs_bulkstat_to_bstat(
351 : struct xfs_mount *mp,
352 : struct xfs_bstat *bs1,
353 : const struct xfs_bulkstat *bstat)
354 : {
355 : /* memset is needed here because of padding holes in the structure. */
356 81841758031 : memset(bs1, 0, sizeof(struct xfs_bstat));
357 81841758031 : bs1->bs_ino = bstat->bs_ino;
358 81841758031 : bs1->bs_mode = bstat->bs_mode;
359 81841758031 : bs1->bs_nlink = bstat->bs_nlink;
360 81841758031 : bs1->bs_uid = bstat->bs_uid;
361 81841758031 : bs1->bs_gid = bstat->bs_gid;
362 81841758031 : bs1->bs_rdev = bstat->bs_rdev;
363 81841758031 : bs1->bs_blksize = bstat->bs_blksize;
364 81841758031 : bs1->bs_size = bstat->bs_size;
365 81841758031 : bs1->bs_atime.tv_sec = bstat->bs_atime;
366 81841758031 : bs1->bs_mtime.tv_sec = bstat->bs_mtime;
367 81841758031 : bs1->bs_ctime.tv_sec = bstat->bs_ctime;
368 81841758031 : bs1->bs_atime.tv_nsec = bstat->bs_atime_nsec;
369 81841758031 : bs1->bs_mtime.tv_nsec = bstat->bs_mtime_nsec;
370 81841758031 : bs1->bs_ctime.tv_nsec = bstat->bs_ctime_nsec;
371 81841758031 : bs1->bs_blocks = bstat->bs_blocks;
372 81841758031 : bs1->bs_xflags = bstat->bs_xflags;
373 81841758031 : bs1->bs_extsize = XFS_FSB_TO_B(mp, bstat->bs_extsize_blks);
374 81841758031 : bs1->bs_extents = bstat->bs_extents;
375 81841758031 : bs1->bs_gen = bstat->bs_gen;
376 81841758031 : bs1->bs_projid_lo = bstat->bs_projectid & 0xFFFF;
377 81841758031 : bs1->bs_forkoff = bstat->bs_forkoff;
378 81841758031 : bs1->bs_projid_hi = bstat->bs_projectid >> 16;
379 81841758031 : bs1->bs_sick = bstat->bs_sick;
380 81841758031 : bs1->bs_checked = bstat->bs_checked;
381 81841758031 : bs1->bs_cowextsize = XFS_FSB_TO_B(mp, bstat->bs_cowextsize_blks);
382 81841758031 : bs1->bs_dmevmask = 0;
383 81841758031 : bs1->bs_dmstate = 0;
384 81841758031 : bs1->bs_aextents = bstat->bs_aextents;
385 81841758031 : }
386 :
387 : struct xfs_inumbers_chunk {
388 : inumbers_fmt_pf formatter;
389 : struct xfs_ibulk *breq;
390 : };
391 :
392 : /*
393 : * INUMBERS
394 : * ========
395 : * This is how we export inode btree records to userspace, so that XFS tools
396 : * can figure out where inodes are allocated.
397 : */
398 :
399 : /*
400 : * Format the inode group structure and report it somewhere.
401 : *
402 : * Similar to xfs_bulkstat_one_int, lastino is the inode cursor as we walk
403 : * through the filesystem so we move it forward unless there was a runtime
404 : * error. If the formatter tells us the buffer is now full we also move the
405 : * cursor forward and abort the walk.
406 : */
407 : STATIC int
408 6889541 : xfs_inumbers_walk(
409 : struct xfs_mount *mp,
410 : struct xfs_trans *tp,
411 : xfs_agnumber_t agno,
412 : const struct xfs_inobt_rec_incore *irec,
413 : void *data)
414 : {
415 13779082 : struct xfs_inumbers inogrp = {
416 6889541 : .xi_startino = XFS_AGINO_TO_INO(mp, agno, irec->ir_startino),
417 6889541 : .xi_alloccount = irec->ir_count - irec->ir_freecount,
418 6889541 : .xi_allocmask = ~irec->ir_free,
419 : .xi_version = XFS_INUMBERS_VERSION_V5,
420 : };
421 6889541 : struct xfs_inumbers_chunk *ic = data;
422 6889541 : int error;
423 :
424 6889541 : error = ic->formatter(ic->breq, &inogrp);
425 6894071 : if (error && error != -ECANCELED)
426 : return error;
427 :
428 6894071 : ic->breq->startino = XFS_AGINO_TO_INO(mp, agno, irec->ir_startino) +
429 : XFS_INODES_PER_CHUNK;
430 6894071 : return error;
431 : }
432 :
433 : /*
434 : * Return inode number table for the filesystem.
435 : */
436 : int
437 4966671 : xfs_inumbers(
438 : struct xfs_ibulk *breq,
439 : inumbers_fmt_pf formatter)
440 : {
441 4966671 : struct xfs_inumbers_chunk ic = {
442 : .formatter = formatter,
443 : .breq = breq,
444 : };
445 4966671 : struct xfs_trans *tp;
446 4966671 : int error = 0;
447 :
448 4966671 : if (xfs_bulkstat_already_done(breq->mp, breq->startino))
449 : return 0;
450 :
451 : /*
452 : * Grab an empty transaction so that we can use its recursive buffer
453 : * locking abilities to detect cycles in the inobt without deadlocking.
454 : */
455 4953537 : error = xfs_trans_alloc_empty(breq->mp, &tp);
456 4961918 : if (error)
457 0 : goto out;
458 :
459 4961918 : error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->flags,
460 : xfs_inumbers_walk, breq->icount, &ic);
461 4960003 : xfs_trans_cancel(tp);
462 4939373 : out:
463 :
464 : /*
465 : * We found some inode groups, so clear the error status and return
466 : * them. The lastino pointer will point directly at the inode that
467 : * triggered any error that occurred, so on the next call the error
468 : * will be triggered again and propagated to userspace as there will be
469 : * no formatted inode groups in the buffer.
470 : */
471 4939373 : if (breq->ocount > 0)
472 4442649 : error = 0;
473 :
474 : return error;
475 : }
476 :
477 : /* Convert an inumbers (v5) struct to a inogrp (v1) struct. */
478 : void
479 69983 : xfs_inumbers_to_inogrp(
480 : struct xfs_inogrp *ig1,
481 : const struct xfs_inumbers *ig)
482 : {
483 : /* memset is needed here because of padding holes in the structure. */
484 69983 : memset(ig1, 0, sizeof(struct xfs_inogrp));
485 69983 : ig1->xi_startino = ig->xi_startino;
486 69983 : ig1->xi_alloccount = ig->xi_alloccount;
487 69983 : ig1->xi_allocmask = ig->xi_allocmask;
488 69983 : }
|