diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-03-25 13:37:03 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-03-25 17:08:24 -0700 |
commit | dca33ac51e74b0511c2eeb86fed5b3341d496c5a (patch) | |
tree | 76fdce2dfe8733b6f24bb2fb30dd40aa49889f1e | |
parent | 5799c2fba9827f834f6cc1cd337317453cd80efc (diff) |
xfs: add inode scan limits to the eofblocks ioctl
Allow callers of the userspace eofblocks ioctl to set a limit on the
number of inodes to scan, and then plumb that through the interface.
This removes a minor wart from the internal inode walk interface.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r-- | fs/xfs/libxfs/xfs_fs.h | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 9 |
4 files changed, 17 insertions, 8 deletions
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 97d21a282db9..bb53bc68fb3c 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -524,7 +524,7 @@ struct xfs_fs_eofblocks { uid_t eof_uid; gid_t eof_gid; prid_t eof_prid; - __u32 pad32; + __u32 eof_limit; __u64 eof_min_file_size; __u64 pad64[12]; }; @@ -538,12 +538,15 @@ struct xfs_fs_eofblocks { #define XFS_EOF_FLAGS_UNION (1 << 5) /* union filter algorithm; * kernel only, not included in * valid mask */ +#define XFS_EOF_FLAGS_LIMIT (1 << 6) /* scan this many inodes */ + #define XFS_EOF_FLAGS_VALID \ (XFS_EOF_FLAGS_SYNC | \ XFS_EOF_FLAGS_UID | \ XFS_EOF_FLAGS_GID | \ XFS_EOF_FLAGS_PRID | \ - XFS_EOF_FLAGS_MINFILESIZE) + XFS_EOF_FLAGS_MINFILESIZE | \ + XFS_EOF_FLAGS_LIMIT) /* diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index d45166066847..5fc4a1b54f72 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1054,7 +1054,7 @@ restart: break; cond_resched(); - if (tag == XFS_ICI_RECLAIM_TAG && eofb) { + if (eofb && (eofb->eof_flags & XFS_EOF_FLAGS_LIMIT)) { eofb->nr_to_scan -= XFS_LOOKUP_BATCH; if (eofb->nr_to_scan < 0) break; @@ -1256,7 +1256,10 @@ xfs_reclaim_inodes_nr( struct xfs_mount *mp, int nr_to_scan) { - struct xfs_eofblocks eofb = { .nr_to_scan = nr_to_scan }; + struct xfs_eofblocks eofb = { + .eof_flags = XFS_EOF_FLAGS_LIMIT, + .nr_to_scan = nr_to_scan + }; /* kick background reclaimer and push the AIL */ xfs_reclaim_work_queue(mp); diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index a1230ebcea3e..0f832fa95fd4 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -15,8 +15,6 @@ struct xfs_eofblocks { kgid_t eof_gid; prid_t eof_prid; __u64 eof_min_file_size; - - /* Number of inodes to scan, currently limited to reclaim */ int nr_to_scan; }; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 562b57b7a4a3..ac3192a433f9 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -2041,8 +2041,7 @@ xfs_fs_eofblocks_from_user( if (src->eof_flags & ~XFS_EOF_FLAGS_VALID) return -EINVAL; - if (memchr_inv(&src->pad32, 0, sizeof(src->pad32)) || - memchr_inv(src->pad64, 0, sizeof(src->pad64))) + if (memchr_inv(src->pad64, 0, sizeof(src->pad64))) return -EINVAL; dst->eof_flags = src->eof_flags; @@ -2062,6 +2061,12 @@ xfs_fs_eofblocks_from_user( if (!gid_valid(dst->eof_gid)) return -EINVAL; } + + if (src->eof_flags & XFS_EOF_FLAGS_LIMIT) + dst->nr_to_scan = min_t(int, src->eof_limit, INT_MAX); + else if (src->eof_limit != 0) + return -EINVAL; + return 0; } |