Commit 3e3f9f58 authored by Brian Foster's avatar Brian Foster Committed by Ben Myers
Browse files

xfs: add inode id filtering to eofblocks scan



Support inode ID filtering in the eofblocks scan. The caller must
set the associated XFS_EOF_FLAGS_*ID bit and ID field.

Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarMark Tinguely <tinguely@sgi.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>
parent 8ca149de
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -346,13 +346,23 @@ typedef struct xfs_error_injection {
struct xfs_eofblocks {
	__u32		eof_version;
	__u32		eof_flags;
	__u64		pad[15];
	uid_t		eof_uid;
	gid_t		eof_gid;
	prid_t		eof_prid;
	__u32		pad32;
	__u64		pad64[13];
};

/* eof_flags values */
#define XFS_EOF_FLAGS_SYNC		(1 << 0) /* sync/wait mode scan */
#define XFS_EOF_FLAGS_UID		(1 << 1) /* filter by uid */
#define XFS_EOF_FLAGS_GID		(1 << 2) /* filter by gid */
#define XFS_EOF_FLAGS_PRID		(1 << 3) /* filter by project id */
#define XFS_EOF_FLAGS_VALID	\
	(XFS_EOF_FLAGS_SYNC)
	(XFS_EOF_FLAGS_SYNC |	\
	 XFS_EOF_FLAGS_UID |	\
	 XFS_EOF_FLAGS_GID |	\
	 XFS_EOF_FLAGS_PRID)


/*
+22 −0
Original line number Diff line number Diff line
@@ -1170,6 +1170,21 @@ xfs_reclaim_inodes_count(
	return reclaimable;
}

STATIC int
xfs_inode_match_id(
	struct xfs_inode	*ip,
	struct xfs_eofblocks	*eofb)
{
	if (eofb->eof_flags & XFS_EOF_FLAGS_UID)
		return ip->i_d.di_uid == eofb->eof_uid;
	else if (eofb->eof_flags & XFS_EOF_FLAGS_GID)
		return ip->i_d.di_gid == eofb->eof_gid;
	else if (eofb->eof_flags & XFS_EOF_FLAGS_PRID)
		return xfs_get_projid(ip) == eofb->eof_prid;

	return 0;
}

STATIC int
xfs_inode_free_eofblocks(
	struct xfs_inode	*ip,
@@ -1178,6 +1193,7 @@ xfs_inode_free_eofblocks(
	void			*args)
{
	int ret;
	struct xfs_eofblocks *eofb = args;

	if (!xfs_can_free_eofblocks(ip, false)) {
		/* inode could be preallocated or append-only */
@@ -1194,6 +1210,12 @@ xfs_inode_free_eofblocks(
	    mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
		return 0;

	if (eofb &&
	    (eofb->eof_flags & (XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID|
			       XFS_EOF_FLAGS_PRID)) &&
	    !xfs_inode_match_id(ip, eofb))
		return 0;

	ret = xfs_free_eofblocks(ip->i_mount, ip, true);

	/* don't revisit the inode if we're not waiting */
+2 −1
Original line number Diff line number Diff line
@@ -1615,7 +1615,8 @@ xfs_file_ioctl(
		if (eofb.eof_flags & ~XFS_EOF_FLAGS_VALID)
			return -XFS_ERROR(EINVAL);

		if (memchr_inv(eofb.pad, 0, sizeof(eofb.pad)))
		if (memchr_inv(&eofb.pad32, 0, sizeof(eofb.pad32)) ||
		    memchr_inv(eofb.pad64, 0, sizeof(eofb.pad64)))
			return -XFS_ERROR(EINVAL);

		error = xfs_icache_free_eofblocks(mp, &eofb);