summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-07-03 23:36:26 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-07-03 23:36:26 -0400
commit7035f9724f8497c709077c08df2073bfcde9c2f5 (patch)
treec54718e02aa9003ed7588f5f789b2537d947f7a7
parent8bfe9d1810e657aaa1b4137f43fae83560e6d71d (diff)
xfs: introduce new v5 bulkstat structure
Introduce a new version of the in-core bulkstat structure that supports our new v5 format features. This structure also fills the gaps in the previous structure. We leave wiring up the ioctls for the next patch. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Allison Collins <allison.henderson@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
-rw-r--r--fs/xfs/libxfs/xfs_fs.h48
-rw-r--r--fs/xfs/libxfs/xfs_health.h2
-rw-r--r--fs/xfs/xfs_health.c2
-rw-r--r--fs/xfs/xfs_ioctl.c9
-rw-r--r--fs/xfs/xfs_ioctl.h2
-rw-r--r--fs/xfs/xfs_ioctl32.c10
-rw-r--r--fs/xfs/xfs_itable.c76
-rw-r--r--fs/xfs/xfs_itable.h4
-rw-r--r--fs/xfs/xfs_ondisk.h2
9 files changed, 125 insertions, 30 deletions
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index ef0dce229fa4..132e364eb141 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -358,6 +358,52 @@ struct xfs_bstat {
358 __u16 bs_aextents; /* attribute number of extents */ 358 __u16 bs_aextents; /* attribute number of extents */
359}; 359};
360 360
361/* New bulkstat structure that reports v5 features and fixes padding issues */
362struct xfs_bulkstat {
363 uint64_t bs_ino; /* inode number */
364 uint64_t bs_size; /* file size */
365
366 uint64_t bs_blocks; /* number of blocks */
367 uint64_t bs_xflags; /* extended flags */
368
369 uint64_t bs_atime; /* access time, seconds */
370 uint64_t bs_mtime; /* modify time, seconds */
371
372 uint64_t bs_ctime; /* inode change time, seconds */
373 uint64_t bs_btime; /* creation time, seconds */
374
375 uint32_t bs_gen; /* generation count */
376 uint32_t bs_uid; /* user id */
377 uint32_t bs_gid; /* group id */
378 uint32_t bs_projectid; /* project id */
379
380 uint32_t bs_atime_nsec; /* access time, nanoseconds */
381 uint32_t bs_mtime_nsec; /* modify time, nanoseconds */
382 uint32_t bs_ctime_nsec; /* inode change time, nanoseconds */
383 uint32_t bs_btime_nsec; /* creation time, nanoseconds */
384
385 uint32_t bs_blksize; /* block size */
386 uint32_t bs_rdev; /* device value */
387 uint32_t bs_cowextsize_blks; /* cow extent size hint, blocks */
388 uint32_t bs_extsize_blks; /* extent size hint, blocks */
389
390 uint32_t bs_nlink; /* number of links */
391 uint32_t bs_extents; /* number of extents */
392 uint32_t bs_aextents; /* attribute number of extents */
393 uint16_t bs_version; /* structure version */
394 uint16_t bs_forkoff; /* inode fork offset in bytes */
395
396 uint16_t bs_sick; /* sick inode metadata */
397 uint16_t bs_checked; /* checked inode metadata */
398 uint16_t bs_mode; /* type and mode */
399 uint16_t bs_pad2; /* zeroed */
400
401 uint64_t bs_pad[7]; /* zeroed */
402};
403
404#define XFS_BULKSTAT_VERSION_V1 (1)
405#define XFS_BULKSTAT_VERSION_V5 (5)
406
361/* bs_sick flags */ 407/* bs_sick flags */
362#define XFS_BS_SICK_INODE (1 << 0) /* inode core */ 408#define XFS_BS_SICK_INODE (1 << 0) /* inode core */
363#define XFS_BS_SICK_BMBTD (1 << 1) /* data fork */ 409#define XFS_BS_SICK_BMBTD (1 << 1) /* data fork */
@@ -374,7 +420,7 @@ struct xfs_bstat {
374 * to retain compatibility with "old" filesystems). 420 * to retain compatibility with "old" filesystems).
375 */ 421 */
376static inline uint32_t 422static inline uint32_t
377bstat_get_projid(struct xfs_bstat *bs) 423bstat_get_projid(const struct xfs_bstat *bs)
378{ 424{
379 return (uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo; 425 return (uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo;
380} 426}
diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h
index 49ddfeac19f2..272005ac8c88 100644
--- a/fs/xfs/libxfs/xfs_health.h
+++ b/fs/xfs/libxfs/xfs_health.h
@@ -185,6 +185,6 @@ xfs_inode_is_healthy(struct xfs_inode *ip)
185 185
186void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo); 186void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
187void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo); 187void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
188void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bstat *bs); 188void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs);
189 189
190#endif /* __XFS_HEALTH_H__ */ 190#endif /* __XFS_HEALTH_H__ */
diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c
index ca66c314a928..8e0cb05a7142 100644
--- a/fs/xfs/xfs_health.c
+++ b/fs/xfs/xfs_health.c
@@ -369,7 +369,7 @@ static const struct ioctl_sick_map ino_map[] = {
369void 369void
370xfs_bulkstat_health( 370xfs_bulkstat_health(
371 struct xfs_inode *ip, 371 struct xfs_inode *ip,
372 struct xfs_bstat *bs) 372 struct xfs_bulkstat *bs)
373{ 373{
374 const struct ioctl_sick_map *m; 374 const struct ioctl_sick_map *m;
375 unsigned int sick; 375 unsigned int sick;
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 0bfee8a05454..9f1984c31ba2 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -716,10 +716,13 @@ out_unlock:
716/* Return 0 on success or positive error */ 716/* Return 0 on success or positive error */
717int 717int
718xfs_fsbulkstat_one_fmt( 718xfs_fsbulkstat_one_fmt(
719 struct xfs_ibulk *breq, 719 struct xfs_ibulk *breq,
720 const struct xfs_bstat *bstat) 720 const struct xfs_bulkstat *bstat)
721{ 721{
722 if (copy_to_user(breq->ubuffer, bstat, sizeof(*bstat))) 722 struct xfs_bstat bs1;
723
724 xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
725 if (copy_to_user(breq->ubuffer, &bs1, sizeof(bs1)))
723 return -EFAULT; 726 return -EFAULT;
724 return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat)); 727 return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat));
725} 728}
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index cb34bc821201..514d3028a134 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -82,7 +82,7 @@ struct xfs_bstat;
82struct xfs_inogrp; 82struct xfs_inogrp;
83 83
84int xfs_fsbulkstat_one_fmt(struct xfs_ibulk *breq, 84int xfs_fsbulkstat_one_fmt(struct xfs_ibulk *breq,
85 const struct xfs_bstat *bstat); 85 const struct xfs_bulkstat *bstat);
86int xfs_fsinumbers_fmt(struct xfs_ibulk *breq, const struct xfs_inogrp *igrp); 86int xfs_fsinumbers_fmt(struct xfs_ibulk *breq, const struct xfs_inogrp *igrp);
87 87
88#endif 88#endif
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 084b44a026a7..ed8e012dabbb 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -166,10 +166,14 @@ xfs_bstime_store_compat(
166/* Return 0 on success or positive error (to xfs_bulkstat()) */ 166/* Return 0 on success or positive error (to xfs_bulkstat()) */
167STATIC int 167STATIC int
168xfs_fsbulkstat_one_fmt_compat( 168xfs_fsbulkstat_one_fmt_compat(
169 struct xfs_ibulk *breq, 169 struct xfs_ibulk *breq,
170 const struct xfs_bstat *buffer) 170 const struct xfs_bulkstat *bstat)
171{ 171{
172 struct compat_xfs_bstat __user *p32 = breq->ubuffer; 172 struct compat_xfs_bstat __user *p32 = breq->ubuffer;
173 struct xfs_bstat bs1;
174 struct xfs_bstat *buffer = &bs1;
175
176 xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
173 177
174 if (put_user(buffer->bs_ino, &p32->bs_ino) || 178 if (put_user(buffer->bs_ino, &p32->bs_ino) ||
175 put_user(buffer->bs_mode, &p32->bs_mode) || 179 put_user(buffer->bs_mode, &p32->bs_mode) ||
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 8be4f8edbcad..5d406915144d 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -24,7 +24,7 @@
24 * Bulk Stat 24 * Bulk Stat
25 * ========= 25 * =========
26 * 26 *
27 * Use the inode walking functions to fill out struct xfs_bstat for every 27 * Use the inode walking functions to fill out struct xfs_bulkstat for every
28 * allocated inode, then pass the stat information to some externally provided 28 * allocated inode, then pass the stat information to some externally provided
29 * iteration function. 29 * iteration function.
30 */ 30 */
@@ -32,7 +32,7 @@
32struct xfs_bstat_chunk { 32struct xfs_bstat_chunk {
33 bulkstat_one_fmt_pf formatter; 33 bulkstat_one_fmt_pf formatter;
34 struct xfs_ibulk *breq; 34 struct xfs_ibulk *breq;
35 struct xfs_bstat *buf; 35 struct xfs_bulkstat *buf;
36}; 36};
37 37
38/* 38/*
@@ -61,7 +61,7 @@ xfs_bulkstat_one_int(
61 struct xfs_icdinode *dic; /* dinode core info pointer */ 61 struct xfs_icdinode *dic; /* dinode core info pointer */
62 struct xfs_inode *ip; /* incore inode pointer */ 62 struct xfs_inode *ip; /* incore inode pointer */
63 struct inode *inode; 63 struct inode *inode;
64 struct xfs_bstat *buf = bc->buf; 64 struct xfs_bulkstat *buf = bc->buf;
65 int error = -EINVAL; 65 int error = -EINVAL;
66 66
67 if (xfs_internal_inum(mp, ino)) 67 if (xfs_internal_inum(mp, ino))
@@ -84,37 +84,35 @@ xfs_bulkstat_one_int(
84 /* xfs_iget returns the following without needing 84 /* xfs_iget returns the following without needing
85 * further change. 85 * further change.
86 */ 86 */
87 buf->bs_projid_lo = dic->di_projid_lo; 87 buf->bs_projectid = xfs_get_projid(ip);
88 buf->bs_projid_hi = dic->di_projid_hi;
89 buf->bs_ino = ino; 88 buf->bs_ino = ino;
90 buf->bs_uid = dic->di_uid; 89 buf->bs_uid = dic->di_uid;
91 buf->bs_gid = dic->di_gid; 90 buf->bs_gid = dic->di_gid;
92 buf->bs_size = dic->di_size; 91 buf->bs_size = dic->di_size;
93 92
94 buf->bs_nlink = inode->i_nlink; 93 buf->bs_nlink = inode->i_nlink;
95 buf->bs_atime.tv_sec = inode->i_atime.tv_sec; 94 buf->bs_atime = inode->i_atime.tv_sec;
96 buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec; 95 buf->bs_atime_nsec = inode->i_atime.tv_nsec;
97 buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec; 96 buf->bs_mtime = inode->i_mtime.tv_sec;
98 buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec; 97 buf->bs_mtime_nsec = inode->i_mtime.tv_nsec;
99 buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec; 98 buf->bs_ctime = inode->i_ctime.tv_sec;
100 buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec; 99 buf->bs_ctime_nsec = inode->i_ctime.tv_nsec;
100 buf->bs_btime = dic->di_crtime.t_sec;
101 buf->bs_btime_nsec = dic->di_crtime.t_nsec;
101 buf->bs_gen = inode->i_generation; 102 buf->bs_gen = inode->i_generation;
102 buf->bs_mode = inode->i_mode; 103 buf->bs_mode = inode->i_mode;
103 104
104 buf->bs_xflags = xfs_ip2xflags(ip); 105 buf->bs_xflags = xfs_ip2xflags(ip);
105 buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; 106 buf->bs_extsize_blks = dic->di_extsize;
106 buf->bs_extents = dic->di_nextents; 107 buf->bs_extents = dic->di_nextents;
107 memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
108 xfs_bulkstat_health(ip, buf); 108 xfs_bulkstat_health(ip, buf);
109 buf->bs_dmevmask = dic->di_dmevmask;
110 buf->bs_dmstate = dic->di_dmstate;
111 buf->bs_aextents = dic->di_anextents; 109 buf->bs_aextents = dic->di_anextents;
112 buf->bs_forkoff = XFS_IFORK_BOFF(ip); 110 buf->bs_forkoff = XFS_IFORK_BOFF(ip);
111 buf->bs_version = XFS_BULKSTAT_VERSION_V5;
113 112
114 if (dic->di_version == 3) { 113 if (dic->di_version == 3) {
115 if (dic->di_flags2 & XFS_DIFLAG2_COWEXTSIZE) 114 if (dic->di_flags2 & XFS_DIFLAG2_COWEXTSIZE)
116 buf->bs_cowextsize = dic->di_cowextsize << 115 buf->bs_cowextsize_blks = dic->di_cowextsize;
117 mp->m_sb.sb_blocklog;
118 } 116 }
119 117
120 switch (dic->di_format) { 118 switch (dic->di_format) {
@@ -170,7 +168,8 @@ xfs_bulkstat_one(
170 168
171 ASSERT(breq->icount == 1); 169 ASSERT(breq->icount == 1);
172 170
173 bc.buf = kmem_zalloc(sizeof(struct xfs_bstat), KM_SLEEP | KM_MAYFAIL); 171 bc.buf = kmem_zalloc(sizeof(struct xfs_bulkstat),
172 KM_SLEEP | KM_MAYFAIL);
174 if (!bc.buf) 173 if (!bc.buf)
175 return -ENOMEM; 174 return -ENOMEM;
176 175
@@ -243,7 +242,8 @@ xfs_bulkstat(
243 if (xfs_bulkstat_already_done(breq->mp, breq->startino)) 242 if (xfs_bulkstat_already_done(breq->mp, breq->startino))
244 return 0; 243 return 0;
245 244
246 bc.buf = kmem_zalloc(sizeof(struct xfs_bstat), KM_SLEEP | KM_MAYFAIL); 245 bc.buf = kmem_zalloc(sizeof(struct xfs_bulkstat),
246 KM_SLEEP | KM_MAYFAIL);
247 if (!bc.buf) 247 if (!bc.buf)
248 return -ENOMEM; 248 return -ENOMEM;
249 249
@@ -265,6 +265,44 @@ xfs_bulkstat(
265 return error; 265 return error;
266} 266}
267 267
268/* Convert bulkstat (v5) to bstat (v1). */
269void
270xfs_bulkstat_to_bstat(
271 struct xfs_mount *mp,
272 struct xfs_bstat *bs1,
273 const struct xfs_bulkstat *bstat)
274{
275 memset(bs1, 0, sizeof(struct xfs_bstat));
276 bs1->bs_ino = bstat->bs_ino;
277 bs1->bs_mode = bstat->bs_mode;
278 bs1->bs_nlink = bstat->bs_nlink;
279 bs1->bs_uid = bstat->bs_uid;
280 bs1->bs_gid = bstat->bs_gid;
281 bs1->bs_rdev = bstat->bs_rdev;
282 bs1->bs_blksize = bstat->bs_blksize;
283 bs1->bs_size = bstat->bs_size;
284 bs1->bs_atime.tv_sec = bstat->bs_atime;
285 bs1->bs_mtime.tv_sec = bstat->bs_mtime;
286 bs1->bs_ctime.tv_sec = bstat->bs_ctime;
287 bs1->bs_atime.tv_nsec = bstat->bs_atime_nsec;
288 bs1->bs_mtime.tv_nsec = bstat->bs_mtime_nsec;
289 bs1->bs_ctime.tv_nsec = bstat->bs_ctime_nsec;
290 bs1->bs_blocks = bstat->bs_blocks;
291 bs1->bs_xflags = bstat->bs_xflags;
292 bs1->bs_extsize = XFS_FSB_TO_B(mp, bstat->bs_extsize_blks);
293 bs1->bs_extents = bstat->bs_extents;
294 bs1->bs_gen = bstat->bs_gen;
295 bs1->bs_projid_lo = bstat->bs_projectid & 0xFFFF;
296 bs1->bs_forkoff = bstat->bs_forkoff;
297 bs1->bs_projid_hi = bstat->bs_projectid >> 16;
298 bs1->bs_sick = bstat->bs_sick;
299 bs1->bs_checked = bstat->bs_checked;
300 bs1->bs_cowextsize = XFS_FSB_TO_B(mp, bstat->bs_cowextsize_blks);
301 bs1->bs_dmevmask = 0;
302 bs1->bs_dmstate = 0;
303 bs1->bs_aextents = bstat->bs_aextents;
304}
305
268struct xfs_inumbers_chunk { 306struct xfs_inumbers_chunk {
269 inumbers_fmt_pf formatter; 307 inumbers_fmt_pf formatter;
270 struct xfs_ibulk *breq; 308 struct xfs_ibulk *breq;
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index cfd3c93226f3..60e259192056 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -38,10 +38,12 @@ xfs_ibulk_advance(
38 */ 38 */
39 39
40typedef int (*bulkstat_one_fmt_pf)(struct xfs_ibulk *breq, 40typedef int (*bulkstat_one_fmt_pf)(struct xfs_ibulk *breq,
41 const struct xfs_bstat *bstat); 41 const struct xfs_bulkstat *bstat);
42 42
43int xfs_bulkstat_one(struct xfs_ibulk *breq, bulkstat_one_fmt_pf formatter); 43int xfs_bulkstat_one(struct xfs_ibulk *breq, bulkstat_one_fmt_pf formatter);
44int xfs_bulkstat(struct xfs_ibulk *breq, bulkstat_one_fmt_pf formatter); 44int xfs_bulkstat(struct xfs_ibulk *breq, bulkstat_one_fmt_pf formatter);
45void xfs_bulkstat_to_bstat(struct xfs_mount *mp, struct xfs_bstat *bs1,
46 const struct xfs_bulkstat *bstat);
45 47
46typedef int (*inumbers_fmt_pf)(struct xfs_ibulk *breq, 48typedef int (*inumbers_fmt_pf)(struct xfs_ibulk *breq,
47 const struct xfs_inogrp *igrp); 49 const struct xfs_inogrp *igrp);
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index c8ba98fae30a..0b4cdda68524 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -146,6 +146,8 @@ xfs_check_ondisk_structs(void)
146 XFS_CHECK_OFFSET(struct xfs_dir3_data_hdr, hdr.magic, 0); 146 XFS_CHECK_OFFSET(struct xfs_dir3_data_hdr, hdr.magic, 0);
147 XFS_CHECK_OFFSET(struct xfs_dir3_free, hdr.hdr.magic, 0); 147 XFS_CHECK_OFFSET(struct xfs_dir3_free, hdr.hdr.magic, 0);
148 XFS_CHECK_OFFSET(struct xfs_attr3_leafblock, hdr.info.hdr, 0); 148 XFS_CHECK_OFFSET(struct xfs_attr3_leafblock, hdr.info.hdr, 0);
149
150 XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat, 192);
149} 151}
150 152
151#endif /* __XFS_ONDISK_H */ 153#endif /* __XFS_ONDISK_H */