@@ -6,6 +6,7 @@
#include "libxfs.h"
#include "xfs.h"
+#include "xfs/xfs_fs.h"
#include "xfs_types.h"
#include "jdm.h"
#include "xfs_bmap_btree.h"
@@ -604,9 +605,11 @@ cmp(const void *s1, const void *s2)
ASSERT((bs1->bs_version == XFS_BULKSTAT_VERSION_V1 &&
bs2->bs_version == XFS_BULKSTAT_VERSION_V1) ||
(bs1->bs_version == XFS_BULKSTAT_VERSION_V5 &&
- bs2->bs_version == XFS_BULKSTAT_VERSION_V5));
+ bs2->bs_version == XFS_BULKSTAT_VERSION_V5) ||
+ (bs1->bs_version == XFS_BULKSTAT_VERSION_V6 &&
+ bs2->bs_version == XFS_BULKSTAT_VERSION_V6));
- return (bs2->bs_extents32 - bs1->bs_extents32);
+ return (bs2->bs_extents64 - bs1->bs_extents64);
}
/*
@@ -670,7 +673,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
for (p = buf, endp = (buf + buflenout); p < endp ; p++) {
/* Do some obvious checks now */
if (((p->bs_mode & S_IFMT) != S_IFREG) ||
- (p->bs_extents32 < 2))
+ (p->bs_extents64 < 2))
continue;
ret = open_handle(&file_fd, fshandlep, p,
@@ -49,7 +49,7 @@ dump_bulkstat(
printf("\tbs_extsize_blks = %"PRIu32"\n", bstat->bs_extsize_blks);
printf("\tbs_nlink = %"PRIu32"\n", bstat->bs_nlink);
- printf("\tbs_extents = %"PRIu32"\n", bstat->bs_extents32);
+ printf("\tbs_extents = %"PRIu64"\n", bstat->bs_extents64);
printf("\tbs_aextents = %"PRIu32"\n", bstat->bs_aextents);
printf("\tbs_version = %"PRIu16"\n", bstat->bs_version);
printf("\tbs_forkoff = %"PRIu16"\n", bstat->bs_forkoff);
@@ -86,6 +86,9 @@ set_xfd_flags(
case 5:
xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V5;
break;
+ case 6:
+ xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V6;
+ break;
default:
break;
}
@@ -153,8 +156,9 @@ bulkstat_f(
perror(optarg);
return 1;
}
- if (ver != 1 && ver != 5) {
- fprintf(stderr, "version must be 1 or 5.\n");
+ if (ver != 1 && ver != 5 && ver != 6) {
+ fprintf(stderr,
+ "version must be 1 or 5 or 6.\n");
return 1;
}
break;
@@ -5,6 +5,7 @@
*/
#include <string.h>
#include <strings.h>
+#include <assert.h>
#include "xfs.h"
#include "fsgeom.h"
#include "bulkstat.h"
@@ -42,6 +43,42 @@ xfrog_bulkstat_prep_v1_emulation(
return xfd_prepare_geometry(xfd);
}
+/* Bulkstat a single inode using v6 ioctl. */
+static int
+xfrog_bulkstat_single6(
+ struct xfs_fd *xfd,
+ uint64_t ino,
+ unsigned int flags,
+ struct xfs_bulkstat *bulkstat)
+{
+ struct xfs_bulkstat_req *req;
+ int ret;
+
+ if (flags & ~(XFS_BULK_IREQ_SPECIAL))
+ return -EINVAL;
+
+ ret = xfrog_bulkstat_alloc_req(1, ino, &req);
+ if (ret)
+ return ret;
+
+ req->hdr.flags = flags;
+ ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V6, req);
+ if (ret) {
+ ret = -errno;
+ goto free;
+ }
+
+ if (req->hdr.ocount == 0) {
+ ret = -ENOENT;
+ goto free;
+ }
+
+ memcpy(bulkstat, req->bulkstat, sizeof(struct xfs_bulkstat));
+free:
+ free(req);
+ return ret;
+}
+
/* Bulkstat a single inode using v5 ioctl. */
static int
xfrog_bulkstat_single5(
@@ -73,6 +110,9 @@ xfrog_bulkstat_single5(
}
memcpy(bulkstat, req->bulkstat, sizeof(struct xfs_bulkstat));
+
+ xfrog_bulkstat_v5_to_v6(bulkstat);
+
free:
free(req);
return ret;
@@ -104,34 +144,46 @@ xfrog_bulkstat_single1(
if (error)
return -errno;
- xfrog_bulkstat_v1_to_v5(xfd, bulkstat, &bstat);
+ xfrog_bulkstat_v1_to_v6(xfd, bulkstat, &bstat);
return 0;
}
/* Bulkstat a single inode. Returns zero or a negative error code. */
int
xfrog_bulkstat_single(
- struct xfs_fd *xfd,
- uint64_t ino,
- unsigned int flags,
- struct xfs_bulkstat *bulkstat)
+ struct xfs_fd *xfd,
+ uint64_t ino,
+ unsigned int flags,
+ struct xfs_bulkstat *bulkstat)
{
- int error;
+ unsigned int xfd_flags = 0;
+ int error;
if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V1)
goto try_v1;
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
+ goto try_v5;
+
+ error = xfrog_bulkstat_single6(xfd, ino, flags, bulkstat);
+ if (error == 0 || xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V6)
+ return error;
+
+ if (error == -EOPNOTSUPP && error == -ENOTTY)
+ xfd_flags = XFROG_FLAG_BULKSTAT_FORCE_V5;
+
+try_v5:
error = xfrog_bulkstat_single5(xfd, ino, flags, bulkstat);
- if (error == 0 || (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5))
+ if (error == 0) {
+ xfd->flags |= xfd_flags;
+ return 0;
+ }
+
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
return error;
- /* If the v5 ioctl wasn't found, we punt to v1. */
- switch (error) {
- case -EOPNOTSUPP:
- case -ENOTTY:
+ if (error == -EOPNOTSUPP && error == -ENOTTY)
xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
- break;
- }
try_v1:
return xfrog_bulkstat_single1(xfd, ino, flags, bulkstat);
@@ -200,14 +252,14 @@ xfrog_bulk_req_v1_cleanup(
struct xfs_fsop_bulkreq *bulkreq,
size_t v1_rec_size,
uint64_t (*v1_ino)(void *v1_rec),
- void *v5_records,
- size_t v5_rec_size,
+ void *v6_records,
+ size_t v6_rec_size,
void (*cvt)(struct xfs_fd *xfd, void *v5, void *v1),
unsigned int startino_adj,
int error)
{
void *v1_rec = bulkreq->ubuffer;
- void *v5_rec = v5_records;
+ void *v6_rec = v6_records;
unsigned int i;
if (error == -ECANCELED) {
@@ -224,7 +276,7 @@ xfrog_bulk_req_v1_cleanup(
*/
for (i = 0;
i < hdr->ocount;
- i++, v1_rec += v1_rec_size, v5_rec += v5_rec_size) {
+ i++, v1_rec += v1_rec_size, v6_rec += v6_rec_size) {
uint64_t ino = v1_ino(v1_rec);
/* Stop if we hit a different AG. */
@@ -233,7 +285,7 @@ xfrog_bulk_req_v1_cleanup(
hdr->ocount = i;
break;
}
- cvt(xfd, v5_rec, v1_rec);
+ cvt(xfd, v6_rec, v1_rec);
hdr->ino = ino + startino_adj;
}
@@ -247,9 +299,23 @@ static uint64_t xfrog_bstat_ino(void *v1_rec)
return ((struct xfs_bstat *)v1_rec)->bs_ino;
}
-static void xfrog_bstat_cvt(struct xfs_fd *xfd, void *v5, void *v1)
+static void xfrog_bstat_cvt(struct xfs_fd *xfd, void *v6, void *v1)
{
- xfrog_bulkstat_v1_to_v5(xfd, v5, v1);
+ xfrog_bulkstat_v1_to_v6(xfd, v6, v1);
+}
+
+/* Bulkstat a bunch of inodes using the v6 interface. */
+static int
+xfrog_bulkstat6(
+ struct xfs_fd *xfd,
+ struct xfs_bulkstat_req *req)
+{
+ int ret;
+
+ ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V6, req);
+ if (ret)
+ return -errno;
+ return 0;
}
/* Bulkstat a bunch of inodes using the v5 interface. */
@@ -258,11 +324,17 @@ xfrog_bulkstat5(
struct xfs_fd *xfd,
struct xfs_bulkstat_req *req)
{
+ struct xfs_bulk_ireq *hdr = &req->hdr;
int ret;
+ int i;
ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V5, req);
if (ret)
return -errno;
+
+ for (i = 0; i < hdr->ocount; i++)
+ xfrog_bulkstat_v5_to_v6(&req->bulkstat[i]);
+
return 0;
}
@@ -303,118 +375,86 @@ xfrog_bulkstat(
struct xfs_fd *xfd,
struct xfs_bulkstat_req *req)
{
+ unsigned int xfd_flags = 0;
int error;
if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V1)
goto try_v1;
- error = xfrog_bulkstat5(xfd, req);
- if (error == 0 || (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5))
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
+ goto try_v5;
+
+ error = xfrog_bulkstat6(xfd, req);
+ if (error == 0 || xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V6)
return error;
- /* If the v5 ioctl wasn't found, we punt to v1. */
- switch (error) {
- case -EOPNOTSUPP:
- case -ENOTTY:
- xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
- break;
+ if (error == -EOPNOTSUPP || error == -ENOTTY)
+ xfd_flags = XFROG_FLAG_BULKSTAT_FORCE_V5;
+
+try_v5:
+ error = xfrog_bulkstat5(xfd, req);
+ if (error == 0) {
+ xfd->flags |= xfd_flags;
+ return 0;
}
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
+ return error;
+
+ if (error == -EOPNOTSUPP || error == -ENOTTY)
+ xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
+
try_v1:
return xfrog_bulkstat1(xfd, req);
}
-static bool
-time_too_big(
- uint64_t time)
+/* Convert bulkstat data from v5 format to v6 format. */
+void
+xfrog_bulkstat_v5_to_v6(
+ struct xfs_bulkstat *bs)
{
- time_t TIME_MAX;
+ bs->bs_version = XFS_BULKSTAT_VERSION_V5;
- memset(&TIME_MAX, 0xFF, sizeof(TIME_MAX));
- return time > TIME_MAX;
-}
-
-/* Convert bulkstat data from v5 format to v1 format. */
-int
-xfrog_bulkstat_v5_to_v1(
- struct xfs_fd *xfd,
- struct xfs_bstat *bs1,
- const struct xfs_bulkstat *bs5)
-{
- if (bs5->bs_aextents > UINT16_MAX ||
- cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks) > UINT32_MAX ||
- cvt_off_fsb_to_b(xfd, bs5->bs_cowextsize_blks) > UINT32_MAX ||
- time_too_big(bs5->bs_atime) ||
- time_too_big(bs5->bs_ctime) ||
- time_too_big(bs5->bs_mtime))
- return -ERANGE;
-
- bs1->bs_ino = bs5->bs_ino;
- bs1->bs_mode = bs5->bs_mode;
- bs1->bs_nlink = bs5->bs_nlink;
- bs1->bs_uid = bs5->bs_uid;
- bs1->bs_gid = bs5->bs_gid;
- bs1->bs_rdev = bs5->bs_rdev;
- bs1->bs_blksize = bs5->bs_blksize;
- bs1->bs_size = bs5->bs_size;
- bs1->bs_atime.tv_sec = bs5->bs_atime;
- bs1->bs_mtime.tv_sec = bs5->bs_mtime;
- bs1->bs_ctime.tv_sec = bs5->bs_ctime;
- bs1->bs_atime.tv_nsec = bs5->bs_atime_nsec;
- bs1->bs_mtime.tv_nsec = bs5->bs_mtime_nsec;
- bs1->bs_ctime.tv_nsec = bs5->bs_ctime_nsec;
- bs1->bs_blocks = bs5->bs_blocks;
- bs1->bs_xflags = bs5->bs_xflags;
- bs1->bs_extsize = cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks);
- bs1->bs_extents = bs5->bs_extents32;
- bs1->bs_gen = bs5->bs_gen;
- bs1->bs_projid_lo = bs5->bs_projectid & 0xFFFF;
- bs1->bs_forkoff = bs5->bs_forkoff;
- bs1->bs_projid_hi = bs5->bs_projectid >> 16;
- bs1->bs_sick = bs5->bs_sick;
- bs1->bs_checked = bs5->bs_checked;
- bs1->bs_cowextsize = cvt_off_fsb_to_b(xfd, bs5->bs_cowextsize_blks);
- bs1->bs_dmevmask = 0;
- bs1->bs_dmstate = 0;
- bs1->bs_aextents = bs5->bs_aextents;
- return 0;
+ assert(bs->bs_extents64 == 0);
+ bs->bs_extents64 = bs->bs_extents32;
+ bs->bs_extents32 = 0;
}
/* Convert bulkstat data from v1 format to v5 format. */
void
-xfrog_bulkstat_v1_to_v5(
+xfrog_bulkstat_v1_to_v6(
struct xfs_fd *xfd,
- struct xfs_bulkstat *bs5,
+ struct xfs_bulkstat *bs6,
const struct xfs_bstat *bs1)
{
- memset(bs5, 0, sizeof(*bs5));
- bs5->bs_version = XFS_BULKSTAT_VERSION_V1;
-
- bs5->bs_ino = bs1->bs_ino;
- bs5->bs_mode = bs1->bs_mode;
- bs5->bs_nlink = bs1->bs_nlink;
- bs5->bs_uid = bs1->bs_uid;
- bs5->bs_gid = bs1->bs_gid;
- bs5->bs_rdev = bs1->bs_rdev;
- bs5->bs_blksize = bs1->bs_blksize;
- bs5->bs_size = bs1->bs_size;
- bs5->bs_atime = bs1->bs_atime.tv_sec;
- bs5->bs_mtime = bs1->bs_mtime.tv_sec;
- bs5->bs_ctime = bs1->bs_ctime.tv_sec;
- bs5->bs_atime_nsec = bs1->bs_atime.tv_nsec;
- bs5->bs_mtime_nsec = bs1->bs_mtime.tv_nsec;
- bs5->bs_ctime_nsec = bs1->bs_ctime.tv_nsec;
- bs5->bs_blocks = bs1->bs_blocks;
- bs5->bs_xflags = bs1->bs_xflags;
- bs5->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
- bs5->bs_extents32 = bs1->bs_extents;
- bs5->bs_gen = bs1->bs_gen;
- bs5->bs_projectid = bstat_get_projid(bs1);
- bs5->bs_forkoff = bs1->bs_forkoff;
- bs5->bs_sick = bs1->bs_sick;
- bs5->bs_checked = bs1->bs_checked;
- bs5->bs_cowextsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_cowextsize);
- bs5->bs_aextents = bs1->bs_aextents;
+ memset(bs6, 0, sizeof(*bs6));
+ bs6->bs_version = XFS_BULKSTAT_VERSION_V1;
+
+ bs6->bs_ino = bs1->bs_ino;
+ bs6->bs_mode = bs1->bs_mode;
+ bs6->bs_nlink = bs1->bs_nlink;
+ bs6->bs_uid = bs1->bs_uid;
+ bs6->bs_gid = bs1->bs_gid;
+ bs6->bs_rdev = bs1->bs_rdev;
+ bs6->bs_blksize = bs1->bs_blksize;
+ bs6->bs_size = bs1->bs_size;
+ bs6->bs_atime = bs1->bs_atime.tv_sec;
+ bs6->bs_mtime = bs1->bs_mtime.tv_sec;
+ bs6->bs_ctime = bs1->bs_ctime.tv_sec;
+ bs6->bs_atime_nsec = bs1->bs_atime.tv_nsec;
+ bs6->bs_mtime_nsec = bs1->bs_mtime.tv_nsec;
+ bs6->bs_ctime_nsec = bs1->bs_ctime.tv_nsec;
+ bs6->bs_blocks = bs1->bs_blocks;
+ bs6->bs_xflags = bs1->bs_xflags;
+ bs6->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
+ bs6->bs_extents64 = bs1->bs_extents;
+ bs6->bs_gen = bs1->bs_gen;
+ bs6->bs_projectid = bstat_get_projid(bs1);
+ bs6->bs_forkoff = bs1->bs_forkoff;
+ bs6->bs_sick = bs1->bs_sick;
+ bs6->bs_checked = bs1->bs_checked;
+ bs6->bs_cowextsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_cowextsize);
+ bs6->bs_aextents = bs1->bs_aextents;
}
/* Allocate a bulkstat request. Returns zero or a negative error code. */
@@ -18,10 +18,9 @@ int xfrog_bulkstat(struct xfs_fd *xfd, struct xfs_bulkstat_req *req);
int xfrog_bulkstat_alloc_req(uint32_t nr, uint64_t startino,
struct xfs_bulkstat_req **preq);
-int xfrog_bulkstat_v5_to_v1(struct xfs_fd *xfd, struct xfs_bstat *bs1,
- const struct xfs_bulkstat *bstat);
-void xfrog_bulkstat_v1_to_v5(struct xfs_fd *xfd, struct xfs_bulkstat *bstat,
- const struct xfs_bstat *bs1);
+void xfrog_bulkstat_v1_to_v6(struct xfs_fd *xfd, struct xfs_bulkstat *bstat,
+ const struct xfs_bstat *bs1);
+void xfrog_bulkstat_v5_to_v6(struct xfs_bulkstat *bs);
void xfrog_bulkstat_set_ag(struct xfs_bulkstat_req *req, uint32_t agno);
@@ -48,7 +48,10 @@ struct xfs_fd {
#define XFROG_FLAG_BULKSTAT_FORCE_V1 (1 << 0)
/* Only use v5 bulkstat/inumbers ioctls. */
-#define XFROG_FLAG_BULKSTAT_FORCE_V5 (1 << 1)
+#define XFROG_FLAG_BULKSTAT_FORCE_V5 (1 << 1)
+
+/* Only use v6 bulkstat ioctls. */
+#define XFROG_FLAG_BULKSTAT_FORCE_V6 (1 << 2)
/* Only use the old XFS swapext ioctl for file data exchanges. */
#define XFROG_FLAG_FORCE_SWAPEXT (1 << 2)
@@ -394,7 +394,7 @@ struct xfs_bulkstat {
uint32_t bs_extsize_blks; /* extent size hint, blocks */
uint32_t bs_nlink; /* number of links */
- uint32_t bs_extents32; /* number of extents */
+ uint32_t bs_extents32; /* number of extents; v5 only */
uint32_t bs_aextents; /* attribute number of extents */
uint16_t bs_version; /* structure version */
uint16_t bs_forkoff; /* inode fork offset in bytes */
@@ -403,12 +403,14 @@ struct xfs_bulkstat {
uint16_t bs_checked; /* checked inode metadata */
uint16_t bs_mode; /* type and mode */
uint16_t bs_pad2; /* zeroed */
+ uint64_t bs_extents64; /* number of extents; v6 only */
- uint64_t bs_pad[7]; /* zeroed */
+ uint64_t bs_pad[6]; /* zeroed */
};
#define XFS_BULKSTAT_VERSION_V1 (1)
#define XFS_BULKSTAT_VERSION_V5 (5)
+#define XFS_BULKSTAT_VERSION_V6 (6)
/* bs_sick flags */
#define XFS_BS_SICK_INODE (1 << 0) /* inode core */
@@ -856,6 +858,7 @@ struct xfs_scrub_metadata {
#define XFS_IOC_BULKSTAT_V5 _IOR ('X', 127, struct xfs_bulkstat_req)
#define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req)
/* FIEXCHANGE_RANGE ----------- hoisted 129 */
+#define XFS_IOC_BULKSTAT_V6 _IOR ('X', 130, struct xfs_bulkstat_req)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
This commit adds XFS_IOC_BULKSTAT_V6 to support 64-bit inode extent counters. The new field xfs_bulkstat->bs_extents64 is added to hold data extent count for filesystems supporting 64-bit data extent counters. Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com> --- fsr/xfs_fsr.c | 9 +- io/bulkstat.c | 10 +- libfrog/bulkstat.c | 260 ++++++++++++++++++++++++++------------------- libfrog/bulkstat.h | 7 +- libfrog/fsgeom.h | 5 +- libxfs/xfs_fs.h | 7 +- 6 files changed, 175 insertions(+), 123 deletions(-)