aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-04-12 10:41:17 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-04-14 21:15:57 -0400
commit7cd5006bdb6f6d9d9d7e68aa1d96b6e4a8b68bc5 (patch)
treedf47e1074e3c043f5206a0e6c0201ae421fc0462 /fs/xfs
parent1b6d968de22bffd85a60538d2628185b17228291 (diff)
xfs: add a new ioctl to describe allocation group geometry
Add a new ioctl to describe an allocation group's geometry. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_ag.c52
-rw-r--r--fs/xfs/libxfs/xfs_ag.h2
-rw-r--r--fs/xfs/libxfs/xfs_fs.h14
-rw-r--r--fs/xfs/xfs_ioctl.c24
-rw-r--r--fs/xfs/xfs_ioctl32.c1
5 files changed, 93 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 1ef8acf35e7d..1c0f2a6c10b4 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -19,6 +19,7 @@
19#include "xfs_ialloc.h" 19#include "xfs_ialloc.h"
20#include "xfs_rmap.h" 20#include "xfs_rmap.h"
21#include "xfs_ag.h" 21#include "xfs_ag.h"
22#include "xfs_ag_resv.h"
22 23
23static struct xfs_buf * 24static struct xfs_buf *
24xfs_get_aghdr_buf( 25xfs_get_aghdr_buf(
@@ -461,3 +462,54 @@ xfs_ag_extend_space(
461 len, &XFS_RMAP_OINFO_SKIP_UPDATE, 462 len, &XFS_RMAP_OINFO_SKIP_UPDATE,
462 XFS_AG_RESV_NONE); 463 XFS_AG_RESV_NONE);
463} 464}
465
466/* Retrieve AG geometry. */
467int
468xfs_ag_get_geometry(
469 struct xfs_mount *mp,
470 xfs_agnumber_t agno,
471 struct xfs_ag_geometry *ageo)
472{
473 struct xfs_buf *agi_bp;
474 struct xfs_buf *agf_bp;
475 struct xfs_agi *agi;
476 struct xfs_agf *agf;
477 struct xfs_perag *pag;
478 unsigned int freeblks;
479 int error;
480
481 if (agno >= mp->m_sb.sb_agcount)
482 return -EINVAL;
483
484 /* Lock the AG headers. */
485 error = xfs_ialloc_read_agi(mp, NULL, agno, &agi_bp);
486 if (error)
487 return error;
488 error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agf_bp);
489 if (error)
490 goto out_agi;
491 pag = xfs_perag_get(mp, agno);
492
493 /* Fill out form. */
494 memset(ageo, 0, sizeof(*ageo));
495 ageo->ag_number = agno;
496
497 agi = XFS_BUF_TO_AGI(agi_bp);
498 ageo->ag_icount = be32_to_cpu(agi->agi_count);
499 ageo->ag_ifree = be32_to_cpu(agi->agi_freecount);
500
501 agf = XFS_BUF_TO_AGF(agf_bp);
502 ageo->ag_length = be32_to_cpu(agf->agf_length);
503 freeblks = pag->pagf_freeblks +
504 pag->pagf_flcount +
505 pag->pagf_btreeblks -
506 xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE);
507 ageo->ag_freeblks = freeblks;
508
509 /* Release resources. */
510 xfs_perag_put(pag);
511 xfs_buf_relse(agf_bp);
512out_agi:
513 xfs_buf_relse(agi_bp);
514 return error;
515}
diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h
index 412702e23f61..5166322807e7 100644
--- a/fs/xfs/libxfs/xfs_ag.h
+++ b/fs/xfs/libxfs/xfs_ag.h
@@ -26,5 +26,7 @@ struct aghdr_init_data {
26int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id); 26int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
27int xfs_ag_extend_space(struct xfs_mount *mp, struct xfs_trans *tp, 27int xfs_ag_extend_space(struct xfs_mount *mp, struct xfs_trans *tp,
28 struct aghdr_init_data *id, xfs_extlen_t len); 28 struct aghdr_init_data *id, xfs_extlen_t len);
29int xfs_ag_get_geometry(struct xfs_mount *mp, xfs_agnumber_t agno,
30 struct xfs_ag_geometry *ageo);
29 31
30#endif /* __LIBXFS_AG_H */ 32#endif /* __LIBXFS_AG_H */
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index cb7d0b1453cd..ee33d628a240 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -268,6 +268,19 @@ typedef struct xfs_fsop_resblks {
268 (s)->sb_agblocks + XFS_MIN_AG_BLOCKS) 268 (s)->sb_agblocks + XFS_MIN_AG_BLOCKS)
269 269
270/* 270/*
271 * Output for XFS_IOC_AG_GEOMETRY
272 */
273struct xfs_ag_geometry {
274 uint32_t ag_number; /* i/o: AG number */
275 uint32_t ag_length; /* o: length in blocks */
276 uint32_t ag_freeblks; /* o: free space */
277 uint32_t ag_icount; /* o: inodes allocated */
278 uint32_t ag_ifree; /* o: inodes free */
279 uint32_t ag_reserved32; /* o: zero */
280 uint64_t ag_reserved[13];/* o: zero */
281};
282
283/*
271 * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT 284 * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
272 */ 285 */
273typedef struct xfs_growfs_data { 286typedef struct xfs_growfs_data {
@@ -620,6 +633,7 @@ struct xfs_scrub_metadata {
620#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) 633#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks)
621/* XFS_IOC_GETFSMAP ------ hoisted 59 */ 634/* XFS_IOC_GETFSMAP ------ hoisted 59 */
622#define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata) 635#define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata)
636#define XFS_IOC_AG_GEOMETRY _IOWR('X', 61, struct xfs_ag_geometry)
623 637
624/* 638/*
625 * ioctl commands that replace IRIX syssgi()'s 639 * ioctl commands that replace IRIX syssgi()'s
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index ec3c6c401ee7..b36abd453709 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -33,6 +33,7 @@
33#include "xfs_fsmap.h" 33#include "xfs_fsmap.h"
34#include "scrub/xfs_scrub.h" 34#include "scrub/xfs_scrub.h"
35#include "xfs_sb.h" 35#include "xfs_sb.h"
36#include "xfs_ag.h"
36 37
37#include <linux/capability.h> 38#include <linux/capability.h>
38#include <linux/cred.h> 39#include <linux/cred.h>
@@ -804,6 +805,26 @@ xfs_ioc_fsgeometry(
804 return 0; 805 return 0;
805} 806}
806 807
808STATIC int
809xfs_ioc_ag_geometry(
810 struct xfs_mount *mp,
811 void __user *arg)
812{
813 struct xfs_ag_geometry ageo;
814 int error;
815
816 if (copy_from_user(&ageo, arg, sizeof(ageo)))
817 return -EFAULT;
818
819 error = xfs_ag_get_geometry(mp, ageo.ag_number, &ageo);
820 if (error)
821 return error;
822
823 if (copy_to_user(arg, &ageo, sizeof(ageo)))
824 return -EFAULT;
825 return 0;
826}
827
807/* 828/*
808 * Linux extended inode flags interface. 829 * Linux extended inode flags interface.
809 */ 830 */
@@ -1930,6 +1951,9 @@ xfs_file_ioctl(
1930 case XFS_IOC_FSGEOMETRY: 1951 case XFS_IOC_FSGEOMETRY:
1931 return xfs_ioc_fsgeometry(mp, arg, 5); 1952 return xfs_ioc_fsgeometry(mp, arg, 5);
1932 1953
1954 case XFS_IOC_AG_GEOMETRY:
1955 return xfs_ioc_ag_geometry(mp, arg);
1956
1933 case XFS_IOC_GETVERSION: 1957 case XFS_IOC_GETVERSION:
1934 return put_user(inode->i_generation, (int __user *)arg); 1958 return put_user(inode->i_generation, (int __user *)arg);
1935 1959
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 55ace6308637..65997a6315e9 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -563,6 +563,7 @@ xfs_file_compat_ioctl(
563 case XFS_IOC_DIOINFO: 563 case XFS_IOC_DIOINFO:
564 case XFS_IOC_FSGEOMETRY_V4: 564 case XFS_IOC_FSGEOMETRY_V4:
565 case XFS_IOC_FSGEOMETRY: 565 case XFS_IOC_FSGEOMETRY:
566 case XFS_IOC_AG_GEOMETRY:
566 case XFS_IOC_FSGETXATTR: 567 case XFS_IOC_FSGETXATTR:
567 case XFS_IOC_FSSETXATTR: 568 case XFS_IOC_FSSETXATTR:
568 case XFS_IOC_FSGETXATTRA: 569 case XFS_IOC_FSGETXATTRA: