diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-03-24 16:26:36 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-03-25 17:00:00 -0700 |
commit | 92a79b0b074e02bc025a027fa39419a900e10258 (patch) | |
tree | 3c118709e9654aa631acb41e6f5807502e2fd9b8 | |
parent | 0e8f2db42714a01bfdcfd29aadabeb3b819a8b69 (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 6fad140d4c8e..0b21d4b93072 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -523,7 +523,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]; }; @@ -537,12 +537,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 23b04cfa38f3..e8a2e1cf7577 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1047,7 +1047,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; @@ -1249,7 +1249,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 7f139ee442bf..b13869954846 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -2043,8 +2043,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; @@ -2064,6 +2063,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; } |