aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */