diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index d7b3b712b2791820d8a360ea0c88ab0d4655e35c..52d03a3a02a4e4a8b21bae62d0871b494d642e2d 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -472,7 +472,18 @@ struct xfs_bulk_ireq { */ #define XFS_BULK_IREQ_AGNO (1 << 0) -#define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO) +/* + * Return bulkstat information for a single inode, where @ino value is a + * special value, not a literal inode number. See the XFS_BULK_IREQ_SPECIAL_* + * values below. Not compatible with XFS_BULK_IREQ_AGNO. + */ +#define XFS_BULK_IREQ_SPECIAL (1 << 1) + +#define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO | \ + XFS_BULK_IREQ_SPECIAL) + +/* Operate on the root directory inode. */ +#define XFS_BULK_IREQ_SPECIAL_ROOT (1) /* * ioctl structures for v5 bulkstat and inumbers requests diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index e1e1d9d6c16df0293c7961787c514ee76717c365..6bf04e71325bf684b09f0a26c3933e5d8e8cc51d 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -853,6 +853,25 @@ xfs_bulk_ireq_setup( breq->ocount = 0; breq->flags = 0; + /* + * The @ino parameter is a special value, so we must look it up here. + * We're not allowed to have IREQ_AGNO, and we only return one inode + * worth of data. + */ + if (hdr->flags & XFS_BULK_IREQ_SPECIAL) { + if (hdr->flags & XFS_BULK_IREQ_AGNO) + return -EINVAL; + + switch (hdr->ino) { + case XFS_BULK_IREQ_SPECIAL_ROOT: + hdr->ino = mp->m_sb.sb_rootino; + break; + default: + return -EINVAL; + } + breq->icount = 1; + } + /* * The IREQ_AGNO flag means that we only want results from a given AG. * If @hdr->ino is zero, we start iterating in that AG. If @hdr->ino is