linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] xfsprogs: Enable extent forcealign feature
@ 2023-09-29  9:53 John Garry
  2023-09-29  9:53 ` [PATCH 1/7] xfs: create a new inode flag to require extsize alignment of file data space John Garry
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

This series enables a new feature to always honour the extent size hint.

It is required for atomic writes support.

It is possible to enable this feature at mkfs time or by changing the
attribute of regular file or directory. For extszhint, it is inherited
by descenent files/directories.

Associated kernel atomic writes patches to follow. We are sending this
support now so that people can try out the kernel support. More testing
is required.

Based on origin/for-next_2023-09-25

Darrick J. Wong (7):
  xfs: create a new inode flag to require extsize alignment of file data
    space
  xfs: allow files to require data mappings to be aligned to extszhint
  xfs_db: expose force_align feature and flags
  xfs_io: implement lsattr and chattr support for forcealign
  xfs_repair: check the force-align flag
  mkfs: add an extsize= option that allows units
  mkfs: enable the new force-align feature

 db/inode.c                      |   3 +
 db/sb.c                         |   2 +
 include/linux.h                 |   5 +
 include/xfs_inode.h             |   5 +
 include/xfs_mount.h             |   2 +
 io/attr.c                       |   5 +-
 libxfs/util.c                   |   2 +
 libxfs/xfs_bmap.c               |  26 ++++-
 libxfs/xfs_format.h             |   9 +-
 libxfs/xfs_inode_buf.c          |  40 ++++++++
 libxfs/xfs_inode_buf.h          |   3 +
 libxfs/xfs_sb.c                 |   3 +
 man/man2/ioctl_xfs_fsgetxattr.2 |   6 ++
 man/man8/mkfs.xfs.8.in          |  29 ++++++
 mkfs/xfs_mkfs.c                 | 175 ++++++++++++++++++++++++++++++--
 repair/dinode.c                 |  66 ++++++++++++
 16 files changed, 367 insertions(+), 14 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] xfs: create a new inode flag to require extsize alignment of file data space
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
@ 2023-09-29  9:53 ` John Garry
  2023-09-29  9:53 ` [PATCH 2/7] xfs: allow files to require data mappings to be aligned to extszhint John Garry
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Add a new inode flag to require that all file data extent mappings must
be aligned (both the file offset range and the allocated space itself)
to the extent size hint.  Having a separate COW extent size hint is no
longer allowed.

The goal here is to enable sysadmins and users to mandate that all space
mappings in a file must have a startoff/blockcount that are aligned to
(say) a 2MB alignment and that the startblock/blockcount will follow the
same alignment.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Co-developed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 include/linux.h        |  5 +++++
 include/xfs_inode.h    |  5 +++++
 include/xfs_mount.h    |  2 ++
 libxfs/util.c          |  2 ++
 libxfs/xfs_format.h    |  6 +++++-
 libxfs/xfs_inode_buf.c | 40 ++++++++++++++++++++++++++++++++++++++++
 libxfs/xfs_inode_buf.h |  3 +++
 libxfs/xfs_sb.c        |  3 +++
 8 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/include/linux.h b/include/linux.h
index eddc4ad9c899..05dde8723c15 100644
--- a/include/linux.h
+++ b/include/linux.h
@@ -251,6 +251,11 @@ struct fsxattr {
 #define FS_XFLAG_COWEXTSIZE	0x00010000	/* CoW extent size allocator hint */
 #endif
 
+/* data extent mappings for regular files must be aligned to extent size hint */
+#ifndef FS_XFLAG_FORCEALIGN
+#define FS_XFLAG_FORCEALIGN	0x00020000
+#endif
+
 /*
  * Reminder: anything added to this file will be compiled into downstream
  * userspace projects!
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 069fcf362ece..7aea79ab3af4 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -233,6 +233,11 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip)
 	return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
 }
 
+static inline bool xfs_inode_forcealign(struct xfs_inode *ip)
+{
+	return ip->i_diflags2 & XFS_DIFLAG2_FORCEALIGN;
+}
+
 /* Always set the child's GID to this value, even if the parent is setgid. */
 #define CRED_FORCE_GID	(1U << 0)
 struct cred {
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index 99d1d9ab13cb..d31fe38f7c84 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -166,6 +166,7 @@ typedef struct xfs_mount {
 #define XFS_FEAT_BIGTIME	(1ULL << 24)	/* large timestamps */
 #define XFS_FEAT_NEEDSREPAIR	(1ULL << 25)	/* needs xfs_repair */
 #define XFS_FEAT_NREXT64	(1ULL << 26)	/* large extent counters */
+#define XFS_FEAT_FORCEALIGN	(1ULL << 27)	/* aligned file data extents */
 
 #define __XFS_HAS_FEAT(name, NAME) \
 static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
@@ -210,6 +211,7 @@ __XFS_HAS_FEAT(inobtcounts, INOBTCNT)
 __XFS_HAS_FEAT(bigtime, BIGTIME)
 __XFS_HAS_FEAT(needsrepair, NEEDSREPAIR)
 __XFS_HAS_FEAT(large_extent_counts, NREXT64)
+__XFS_HAS_FEAT(forcealign, FORCEALIGN)
 
 /* Kernel mount features that we don't support */
 #define __XFS_UNSUPP_FEAT(name) \
diff --git a/libxfs/util.c b/libxfs/util.c
index e7d3497ec96f..58b6a85562a2 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -206,6 +206,8 @@ xfs_flags2diflags2(
 		di_flags2 |= XFS_DIFLAG2_DAX;
 	if (xflags & FS_XFLAG_COWEXTSIZE)
 		di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
+	if (xflags & FS_XFLAG_FORCEALIGN)
+		di_flags2 |= XFS_DIFLAG2_FORCEALIGN;
 
 	return di_flags2;
 }
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 371dc07233e0..d718b73f48ca 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -353,6 +353,7 @@ xfs_sb_has_compat_feature(
 #define XFS_SB_FEAT_RO_COMPAT_RMAPBT   (1 << 1)		/* reverse map btree */
 #define XFS_SB_FEAT_RO_COMPAT_REFLINK  (1 << 2)		/* reflinked files */
 #define XFS_SB_FEAT_RO_COMPAT_INOBTCNT (1 << 3)		/* inobt block counts */
+#define XFS_SB_FEAT_RO_COMPAT_FORCEALIGN (1 << 30)	/* aligned file data extents */
 #define XFS_SB_FEAT_RO_COMPAT_ALL \
 		(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
 		 XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
@@ -1069,16 +1070,19 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
 #define XFS_DIFLAG2_COWEXTSIZE_BIT   2  /* copy on write extent size hint */
 #define XFS_DIFLAG2_BIGTIME_BIT	3	/* big timestamps */
 #define XFS_DIFLAG2_NREXT64_BIT 4	/* large extent counters */
+/* data extent mappings for regular files must be aligned to extent size hint */
+#define XFS_DIFLAG2_FORCEALIGN_BIT 5
 
 #define XFS_DIFLAG2_DAX		(1 << XFS_DIFLAG2_DAX_BIT)
 #define XFS_DIFLAG2_REFLINK     (1 << XFS_DIFLAG2_REFLINK_BIT)
 #define XFS_DIFLAG2_COWEXTSIZE  (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
 #define XFS_DIFLAG2_BIGTIME	(1 << XFS_DIFLAG2_BIGTIME_BIT)
 #define XFS_DIFLAG2_NREXT64	(1 << XFS_DIFLAG2_NREXT64_BIT)
+#define XFS_DIFLAG2_FORCEALIGN	(1 << XFS_DIFLAG2_FORCEALIGN_BIT)
 
 #define XFS_DIFLAG2_ANY \
 	(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
-	 XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_NREXT64)
+	 XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_NREXT64 | XFS_DIFLAG2_FORCEALIGN)
 
 static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
 {
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index cbcaadbcf69c..d6ad361ea893 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -601,6 +601,14 @@ xfs_dinode_verify(
 	    !xfs_has_bigtime(mp))
 		return __this_address;
 
+	if (flags2 & XFS_DIFLAG2_FORCEALIGN) {
+		fa = xfs_inode_validate_forcealign(mp, mode, flags,
+				be32_to_cpu(dip->di_extsize),
+				be32_to_cpu(dip->di_cowextsize));
+		if (fa)
+			return fa;
+	}
+
 	return NULL;
 }
 
@@ -768,3 +776,35 @@ xfs_inode_validate_cowextsize(
 
 	return NULL;
 }
+
+/* Validate the forcealign inode flag */
+xfs_failaddr_t
+xfs_inode_validate_forcealign(
+	struct xfs_mount	*mp,
+	uint16_t		mode,
+	uint16_t		flags,
+	uint32_t		extsize,
+	uint32_t		cowextsize)
+{
+	/* superblock rocompat feature flag */
+	if (!xfs_has_forcealign(mp))
+		return __this_address;
+
+	/* Only regular files and directories */
+	if (!S_ISDIR(mode) && !S_ISREG(mode))
+		return __this_address;
+
+	/* Doesn't apply to realtime files */
+	if (flags & XFS_DIFLAG_REALTIME)
+		return __this_address;
+
+	/* Requires a nonzero extent size hint */
+	if (extsize == 0)
+		return __this_address;
+
+	/* Requires no cow extent size hint */
+	if (cowextsize != 0)
+		return __this_address;
+
+	return NULL;
+}
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 585ed5a110af..50db17d22b68 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -33,6 +33,9 @@ xfs_failaddr_t xfs_inode_validate_extsize(struct xfs_mount *mp,
 xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
 		uint32_t cowextsize, uint16_t mode, uint16_t flags,
 		uint64_t flags2);
+xfs_failaddr_t xfs_inode_validate_forcealign(struct xfs_mount *mp,
+		uint16_t mode, uint16_t flags, uint32_t extsize,
+		uint32_t cowextsize);
 
 static inline uint64_t xfs_inode_encode_bigtime(struct timespec64 tv)
 {
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 1e71d43d0a45..0c31cd062d63 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -160,6 +160,9 @@ xfs_sb_version_to_features(
 		features |= XFS_FEAT_REFLINK;
 	if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
 		features |= XFS_FEAT_INOBTCNT;
+	if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FORCEALIGN)
+		features |= XFS_FEAT_FORCEALIGN;
+
 	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_FTYPE)
 		features |= XFS_FEAT_FTYPE;
 	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_SPINODES)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/7] xfs: allow files to require data mappings to be aligned to extszhint
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
  2023-09-29  9:53 ` [PATCH 1/7] xfs: create a new inode flag to require extsize alignment of file data space John Garry
@ 2023-09-29  9:53 ` John Garry
  2023-09-29  9:53 ` [PATCH 3/7] xfs_db: expose force_align feature and flags John Garry
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Add a new inode flag to require that all file data extent mappings must
be aligned (both the file offset range and the allocated space itself)
to the extent size hint.  Having a separate COW extent size hint is no
longer allowed.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Co-developed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 libxfs/xfs_bmap.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 2bd23d40e743..809adcf67985 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -3321,6 +3321,19 @@ xfs_bmap_compute_alignments(
 		align = xfs_get_cowextsz_hint(ap->ip);
 	else if (ap->datatype & XFS_ALLOC_USERDATA)
 		align = xfs_get_extsz_hint(ap->ip);
+
+	/*
+	 * xfs_get_cowextsz_hint() returns extsz_hint for when forcealign is
+	 * set as forcealign and cowextsz_hint are mutually exclusive
+	 */
+	if (xfs_inode_forcealign(ap->ip) && align) {
+		args->alignment = align;
+		if (stripe_align % align)
+			stripe_align = align;
+	} else {
+		args->alignment = 1;
+	}
+
 	if (align) {
 		if (xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, align, 0,
 					ap->eof, 0, ap->conv, &ap->offset,
@@ -3416,7 +3429,6 @@ xfs_bmap_exact_minlen_extent_alloc(
 	args.minlen = args.maxlen = ap->minlen;
 	args.total = ap->total;
 
-	args.alignment = 1;
 	args.minalignslop = 0;
 
 	args.minleft = ap->minleft;
@@ -3462,6 +3474,7 @@ xfs_bmap_btalloc_at_eof(
 {
 	struct xfs_mount	*mp = args->mp;
 	struct xfs_perag	*caller_pag = args->pag;
+	int			orig_alignment = args->alignment;
 	int			error;
 
 	/*
@@ -3536,10 +3549,10 @@ xfs_bmap_btalloc_at_eof(
 
 	/*
 	 * Allocation failed, so turn return the allocation args to their
-	 * original non-aligned state so the caller can proceed on allocation
-	 * failure as if this function was never called.
+	 * original state so the caller can proceed on allocation failure as
+	 * if this function was never called.
 	 */
-	args->alignment = 1;
+	args->alignment = orig_alignment;
 	return 0;
 }
 
@@ -3562,6 +3575,10 @@ xfs_bmap_btalloc_low_space(
 {
 	int			error;
 
+	/* The allocator doesn't honour args->alignment */
+	if (args->alignment > 1)
+		return 0;
+
 	if (args->minlen > ap->minlen) {
 		args->minlen = ap->minlen;
 		error = xfs_alloc_vextent_start_ag(args, ap->blkno);
@@ -3683,7 +3700,6 @@ xfs_bmap_btalloc(
 		.wasdel		= ap->wasdel,
 		.resv		= XFS_AG_RESV_NONE,
 		.datatype	= ap->datatype,
-		.alignment	= 1,
 		.minalignslop	= 0,
 	};
 	xfs_fileoff_t		orig_offset;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/7] xfs_db: expose force_align feature and flags
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
  2023-09-29  9:53 ` [PATCH 1/7] xfs: create a new inode flag to require extsize alignment of file data space John Garry
  2023-09-29  9:53 ` [PATCH 2/7] xfs: allow files to require data mappings to be aligned to extszhint John Garry
@ 2023-09-29  9:53 ` John Garry
  2023-09-29  9:53 ` [PATCH 4/7] xfs_io: implement lsattr and chattr support for forcealign John Garry
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Expose the superblock feature and inode flags.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 db/inode.c | 3 +++
 db/sb.c    | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/db/inode.c b/db/inode.c
index c9b506b905d0..b674db3ca1c6 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -207,6 +207,9 @@ const field_t	inode_v3_flds[] = {
 	{ "nrext64", FLDT_UINT1,
 	  OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_NREXT64_BIT - 1), C1,
 	  0, TYP_NONE },
+	{ "forcealign", FLDT_UINT1,
+	  OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_FORCEALIGN_BIT-1), C1,
+	  0, TYP_NONE },
 	{ NULL }
 };
 
diff --git a/db/sb.c b/db/sb.c
index 2d508c26a3b7..8b7d7c215a48 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -706,6 +706,8 @@ version_string(
 		strcat(s, ",NEEDSREPAIR");
 	if (xfs_has_large_extent_counts(mp))
 		strcat(s, ",NREXT64");
+	if (xfs_has_forcealign(mp))
+		strcat(s, ",FORCEALIGN");
 	return s;
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/7] xfs_io: implement lsattr and chattr support for forcealign
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
                   ` (2 preceding siblings ...)
  2023-09-29  9:53 ` [PATCH 3/7] xfs_db: expose force_align feature and flags John Garry
@ 2023-09-29  9:53 ` John Garry
  2023-09-29  9:53 ` [PATCH 5/7] xfs_repair: check the force-align flag John Garry
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Make it so that we can adjust the forcealign flag at runtime.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Co-developed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 io/attr.c                       | 5 ++++-
 man/man2/ioctl_xfs_fsgetxattr.2 | 6 ++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/io/attr.c b/io/attr.c
index fd82a2e73801..248a9c28eae1 100644
--- a/io/attr.c
+++ b/io/attr.c
@@ -38,9 +38,10 @@ static struct xflags {
 	{ FS_XFLAG_DAX,			"x", "dax"		},
 	{ FS_XFLAG_COWEXTSIZE,		"C", "cowextsize"	},
 	{ FS_XFLAG_HASATTR,		"X", "has-xattr"	},
+	{ FS_XFLAG_FORCEALIGN,		"F", "force-align"	},
 	{ 0, NULL, NULL }
 };
-#define CHATTR_XFLAG_LIST	"r"/*p*/"iasAdtPneEfSxC"/*X*/
+#define CHATTR_XFLAG_LIST	"r"/*p*/"iasAdtPneEfSxC"/*X*/"F"
 
 static void
 lsattr_help(void)
@@ -67,6 +68,7 @@ lsattr_help(void)
 " x -- Use direct access (DAX) for data in this file\n"
 " C -- for files with shared blocks, observe the inode CoW extent size value\n"
 " X -- file has extended attributes (cannot be changed using chattr)\n"
+" F -- data extent mappings must be aligned to extent size hint\n"
 "\n"
 " Options:\n"
 " -R -- recursively descend (useful when current file is a directory)\n"
@@ -104,6 +106,7 @@ chattr_help(void)
 " +/-S -- set/clear the filestreams allocator flag\n"
 " +/-x -- set/clear the direct access (DAX) flag\n"
 " +/-C -- set/clear the CoW extent-size flag\n"
+" +/-F -- set/clear the forcealign flag\n"
 " Note1: user must have certain capabilities to modify immutable/append-only.\n"
 " Note2: immutable/append-only files cannot be deleted; removing these files\n"
 "        requires the immutable/append-only flag to be cleared first.\n"
diff --git a/man/man2/ioctl_xfs_fsgetxattr.2 b/man/man2/ioctl_xfs_fsgetxattr.2
index 2c626a7e3742..d97fb1b508aa 100644
--- a/man/man2/ioctl_xfs_fsgetxattr.2
+++ b/man/man2/ioctl_xfs_fsgetxattr.2
@@ -200,6 +200,12 @@ below).
 If set on a directory, new files and subdirectories created in the directory
 will have both the flag and the CoW extent size value set.
 .TP
+.B XFS_XFLAG_FORCEALIGN
+Force Alignment bit - requires that all file data extents must be aligned
+to the extent size hint value.
+If set on a directory, new files and subdirectories created in the directory
+will have the flag set.
+.TP
 .B XFS_XFLAG_HASATTR
 The file has extended attributes associated with it.
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/7] xfs_repair: check the force-align flag
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
                   ` (3 preceding siblings ...)
  2023-09-29  9:53 ` [PATCH 4/7] xfs_io: implement lsattr and chattr support for forcealign John Garry
@ 2023-09-29  9:53 ` John Garry
  2023-09-29  9:53 ` [PATCH 6/7] mkfs: add an extsize= option that allows units John Garry
  2023-09-29  9:53 ` [PATCH 7/7] mkfs: enable the new force-align feature John Garry
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Make sure the flag isn't set incorrectly.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 repair/dinode.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/repair/dinode.c b/repair/dinode.c
index e534a01b5009..a9de2ee73ef4 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2262,6 +2262,69 @@ _("Bad extent size hint %u on inode %" PRIu64 ", "),
 	}
 }
 
+static void
+validate_forcealign(
+	struct xfs_mount	*mp,
+	struct xfs_dinode	*dino,
+	xfs_ino_t		lino,
+	int			*dirty)
+{
+	uint16_t		mode;
+	uint16_t		flags;
+	uint64_t		flags2;
+	
+	mode = be16_to_cpu(dino->di_mode);
+	flags = be16_to_cpu(dino->di_flags);
+	flags2 = be64_to_cpu(dino->di_flags2);
+
+	if (!(flags2 & XFS_DIFLAG2_FORCEALIGN))
+		return;
+
+	if (!xfs_has_forcealign(mp)) {
+		do_warn(
+ _("Filesystem does not support forcealign flag set on inode %" PRIu64 ", "),
+					lino);
+		goto zap;
+	}
+
+	if (!S_ISDIR(mode) && !S_ISREG(mode)) {
+		do_warn(
+ _("Cannot have forcealign inode flag set on non-dir non-regular file inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	if (flags & XFS_DIFLAG_REALTIME) {
+		do_warn(
+ _("Cannot have forcealign inode flag set on realtime inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	if (dino->di_extsize == 0) {
+		do_warn(
+ _("Cannot have forcealign inode flag set without an extent size hint on inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	if (dino->di_cowextsize != 0) {
+		do_warn(
+ _("Cannot have forcealign inode flag set with nonzero CoW extent size hint on inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	return;
+zap:
+	if (!no_modify) {
+		do_warn(_("clearing flag\n"));
+		dino->di_flags2 &= ~cpu_to_be64(XFS_DIFLAG2_FORCEALIGN);
+		*dirty = 1;
+	} else
+		do_warn(_("would clear flag\n"));
+}
+
 /*
  * returns 0 if the inode is ok, 1 if the inode is corrupt
  * check_dups can be set to 1 *only* when called by the
@@ -2833,6 +2896,9 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "),
 			do_warn(_("would reset to zero\n"));
 	}
 
+	if (dino->di_version >= 3)
+		validate_forcealign(mp, dino, lino, dirty);
+
 	/* nsec fields cannot be larger than 1 billion */
 	check_nsec("atime", lino, dino, &dino->di_atime, dirty);
 	check_nsec("mtime", lino, dino, &dino->di_mtime, dirty);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/7] mkfs: add an extsize= option that allows units
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
                   ` (4 preceding siblings ...)
  2023-09-29  9:53 ` [PATCH 5/7] xfs_repair: check the force-align flag John Garry
@ 2023-09-29  9:53 ` John Garry
  2023-09-29  9:53 ` [PATCH 7/7] mkfs: enable the new force-align feature John Garry
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Add a new mkfs option that allows the user to specify an extent size
hint with units.  This removes the need to specify the option in
filesystem block size, which eases the computation requirements in
deployment scripts.

# mkfs.xfs -d extsize=2m /dev/sda

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 man/man8/mkfs.xfs.8.in | 15 +++++++++++++
 mkfs/xfs_mkfs.c        | 48 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index 08bb92f6522d..9742482dcee9 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -482,6 +482,18 @@ will be assigned the project quota id provided in
 Directories will pass on the project id to newly created regular files and
 directories.
 .TP
+.BI extsize= num
+All inodes created by
+.B mkfs.xfs
+will have this
+.I value
+extent size hint applied.
+Directories will pass on this hint to newly created regular files and
+directories.
+This option cannot be combined with the
+.B extszinherit
+option.
+.TP
 .BI extszinherit= value
 All inodes created by
 .B mkfs.xfs
@@ -491,6 +503,9 @@ extent size hint applied.
 The value must be provided in units of filesystem blocks.
 Directories will pass on this hint to newly created regular files and
 directories.
+This option cannot be combined with the
+.B extsize
+option.
 .TP
 .BI daxinherit= value
 If
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index d3a15cf44e00..bffe0b7ea8b0 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -74,6 +74,7 @@ enum {
 	D_NOALIGN,
 	D_RTINHERIT,
 	D_PROJINHERIT,
+	D_EXTSIZE,
 	D_EXTSZINHERIT,
 	D_COWEXTSIZE,
 	D_DAXINHERIT,
@@ -315,6 +316,7 @@ static struct opt_params dopts = {
 		[D_NOALIGN] = "noalign",
 		[D_RTINHERIT] = "rtinherit",
 		[D_PROJINHERIT] = "projinherit",
+		[D_EXTSIZE] = "extsize",
 		[D_EXTSZINHERIT] = "extszinherit",
 		[D_COWEXTSIZE] = "cowextsize",
 		[D_DAXINHERIT] = "daxinherit",
@@ -422,8 +424,17 @@ static struct opt_params dopts = {
 		  .maxval = UINT_MAX,
 		  .defaultval = SUBOPT_NEEDS_VAL,
 		},
+		{ .index = D_EXTSIZE,
+		  .conflicts = { { &dopts, D_EXTSZINHERIT },
+				 { NULL, LAST_CONFLICT } },
+		  .convert = true,
+		  .minval = 0,
+		  .maxval = XFS_AG_MAX_BYTES,
+		  .defaultval = SUBOPT_NEEDS_VAL,
+		},
 		{ .index = D_EXTSZINHERIT,
-		  .conflicts = { { NULL, LAST_CONFLICT } },
+		  .conflicts = { { &dopts, D_EXTSIZE },
+				 { NULL, LAST_CONFLICT } },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
 		  .defaultval = SUBOPT_NEEDS_VAL,
@@ -881,6 +892,7 @@ struct cli_params {
 	char	*lsu;
 	char	*rtextsize;
 	char	*rtsize;
+	char	*extsize;
 
 	/* parameters where 0 is a valid CLI value */
 	int	dsunit;
@@ -993,7 +1005,7 @@ usage( void )
 			    inobtcount=0|1,bigtime=0|1]\n\
 /* data subvol */	[-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
 			    (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
-			    sectsize=num\n\
+			    sectsize=num,extsize=num\n\
 /* force overwrite */	[-f]\n\
 /* inode size */	[-i perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
 			    projid32bit=0|1,sparse=0|1,nrext64=0|1]\n\
@@ -1601,6 +1613,9 @@ data_opts_parser(
 		cli->fsx.fsx_projid = getnum(value, opts, subopt);
 		cli->fsx.fsx_xflags |= FS_XFLAG_PROJINHERIT;
 		break;
+	case D_EXTSIZE:
+		cli->extsize = getstr(value, opts, subopt);
+		break;
 	case D_EXTSZINHERIT:
 		cli->fsx.fsx_extsize = getnum(value, opts, subopt);
 		if (cli->fsx.fsx_extsize)
@@ -2084,6 +2099,33 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 
 }
 
+/*
+ * Convert the -d extsize= option to a number, then set the extent size hint
+ * to that number.
+ */
+static void
+set_extsize(
+	struct cli_params	*cli,
+	char			*extsize,
+	struct opt_params	*opts,
+	int			subopt)
+{
+	uint64_t		extsz_bytes;
+	if (!extsize)
+		return;
+
+	extsz_bytes = getnum(extsize, opts, subopt);
+	if (extsz_bytes % blocksize)
+		illegal_option(extsize, opts, subopt,
+				_("Value must be a multiple of block size."));
+
+	cli->fsx.fsx_extsize = extsz_bytes / blocksize;
+	if (cli->fsx.fsx_extsize)
+		cli->fsx.fsx_xflags |= FS_XFLAG_EXTSZINHERIT;
+	else
+		cli->fsx.fsx_xflags &= ~FS_XFLAG_EXTSZINHERIT;
+}
+
 /*
  * Grab log sector size and validate.
  *
@@ -4251,6 +4293,8 @@ main(
 	blocksize = cfg.blocksize;
 	sectorsize = cfg.sectorsize;
 
+	set_extsize(&cli, cli.extsize, &dopts, D_EXTSIZE);
+
 	validate_log_sectorsize(&cfg, &cli, &dft);
 	validate_sb_features(&cfg, &cli);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/7] mkfs: enable the new force-align feature
  2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
                   ` (5 preceding siblings ...)
  2023-09-29  9:53 ` [PATCH 6/7] mkfs: add an extsize= option that allows units John Garry
@ 2023-09-29  9:53 ` John Garry
  6 siblings, 0 replies; 8+ messages in thread
From: John Garry @ 2023-09-29  9:53 UTC (permalink / raw)
  To: djwong, linux-xfs, david, chandanbabu, cem; +Cc: martin.petersen, John Garry

From: "Darrick J. Wong" <djwong@kernel.org>

Make it so that we can create filesystems with the forcealign feature
turned on.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
#jpg: set .forcealign = true in SB
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 libxfs/xfs_format.h    |   3 +-
 man/man8/mkfs.xfs.8.in |  14 +++++
 mkfs/xfs_mkfs.c        | 127 +++++++++++++++++++++++++++++++++++++++--
 3 files changed, 139 insertions(+), 5 deletions(-)

diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index d718b73f48ca..afb843b14074 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -358,7 +358,8 @@ xfs_sb_has_compat_feature(
 		(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
 		 XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
 		 XFS_SB_FEAT_RO_COMPAT_REFLINK| \
-		 XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
+		 XFS_SB_FEAT_RO_COMPAT_INOBTCNT | \
+		 XFS_SB_FEAT_RO_COMPAT_FORCEALIGN)
 #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN	~XFS_SB_FEAT_RO_COMPAT_ALL
 static inline bool
 xfs_sb_has_ro_compat_feature(
diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index 9742482dcee9..b86ee4794206 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -657,6 +657,20 @@ Extend maximum values of inode data and attr fork extent counters from 2^31 -
 omitted, 1 is assumed. This feature is disabled by default. This feature is
 only available for filesystems formatted with -m crc=1.
 .TP
+.BI forcealign[= value]
+If
+.B value
+is 1, mark the root directory so that all file data extent allocations will be
+aligned to the extent size hint.
+These allocations will be mapped into the file range at offsets that are
+aligned to the extent size hint.
+The
+.B extszinherit
+option must be specified.
+The
+.B cowextsize
+option must not be specified.
+This feature is only available for filesystems formatted with -m crc=1.
 .RE
 .PP
 .PD 0
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index bffe0b7ea8b0..292d0cbad31a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -90,6 +90,7 @@ enum {
 	I_PROJID32BIT,
 	I_SPINODES,
 	I_NREXT64,
+	I_FORCEALIGN,
 	I_MAX_OPTS,
 };
 
@@ -467,6 +468,7 @@ static struct opt_params iopts = {
 		[I_PROJID32BIT] = "projid32bit",
 		[I_SPINODES] = "sparse",
 		[I_NREXT64] = "nrext64",
+		[I_FORCEALIGN] = "forcealign",
 		[I_MAX_OPTS] = NULL,
 	},
 	.subopt_params = {
@@ -521,7 +523,13 @@ static struct opt_params iopts = {
 		  .minval = 0,
 		  .maxval = 1,
 		  .defaultval = 1,
-		}
+		},
+		{ .index = I_FORCEALIGN,
+		  .conflicts = { { NULL, LAST_CONFLICT } },
+		  .minval = 0,
+		  .maxval = 1,
+		  .defaultval = 1,
+		},
 	},
 };
 
@@ -874,6 +882,7 @@ struct sb_feat_args {
 	bool	nodalign;
 	bool	nortalign;
 	bool	nrext64;
+	bool	forcealign;		/* XFS_SB_FEAT_RO_COMPAT_FORCEALIGN */
 };
 
 struct cli_params {
@@ -1008,7 +1017,8 @@ usage( void )
 			    sectsize=num,extsize=num\n\
 /* force overwrite */	[-f]\n\
 /* inode size */	[-i perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
-			    projid32bit=0|1,sparse=0|1,nrext64=0|1]\n\
+			    projid32bit=0|1,sparse=0|1,nrext64=0|1],\n\
+			    forcealign=0|1\n\
 /* no discard */	[-K]\n\
 /* log subvol */	[-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
 			    sunit=value|su=num,sectsize=num,lazy-count=0|1]\n\
@@ -1674,6 +1684,17 @@ inode_opts_parser(
 	case I_NREXT64:
 		cli->sb_feat.nrext64 = getnum(value, opts, subopt);
 		break;
+	case I_FORCEALIGN:
+		long long	val = getnum(value, opts, subopt);
+
+		if (val == 1) {
+			cli->sb_feat.forcealign = true;
+			cli->fsx.fsx_xflags |= FS_XFLAG_FORCEALIGN;
+		} else {
+			cli->sb_feat.forcealign = false;
+			cli->fsx.fsx_xflags &= ~FS_XFLAG_FORCEALIGN;
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2329,6 +2350,13 @@ _("64 bit extent count not supported without CRC support\n"));
 			usage();
 		}
 		cli->sb_feat.nrext64 = false;
+
+		if (cli->sb_feat.forcealign) {
+			fprintf(stderr,
+_("forced file data alignment not supported without CRC support\n"));
+			usage();
+		}
+		cli->sb_feat.forcealign = false;
 	}
 
 	if (!cli->sb_feat.finobt) {
@@ -2363,6 +2391,13 @@ _("cowextsize not supported without reflink support\n"));
 		usage();
 	}
 
+	if ((cli->fsx.fsx_xflags & FS_XFLAG_FORCEALIGN) &&
+	    (cli->fsx.fsx_cowextsize > 0 || cli->fsx.fsx_extsize == 0)) {
+		fprintf(stderr,
+_("forcealign requires a nonzero extent size hint and no cow extent size hint\n"));
+		usage();
+	}
+
 	/*
 	 * Copy features across to config structure now.
 	 */
@@ -2612,6 +2647,34 @@ _("illegal CoW extent size hint %lld, must be less than %u.\n"),
 	}
 }
 
+/* Validate the incoming forcealign flag. */
+static void
+validate_forcealign(
+	struct xfs_mount	*mp,
+	struct cli_params	*cli)
+{
+	if (!(cli->fsx.fsx_xflags & FS_XFLAG_FORCEALIGN))
+		return;
+
+	if (cli->fsx.fsx_cowextsize != 0) {
+		fprintf(stderr,
+_("cannot set CoW extent size hint when forcealign is set.\n"));
+		usage();
+	}
+
+	if (cli->fsx.fsx_extsize == 0) {
+		fprintf(stderr,
+_("cannot set forcealign without an extent size hint.\n"));
+		usage();
+	}
+
+	if (cli->fsx.fsx_xflags & (FS_XFLAG_REALTIME | FS_XFLAG_RTINHERIT)) {
+		fprintf(stderr,
+_("cannot set forcealign and realtime flags.\n"));
+		usage();
+	}
+}
+
 /* Complain if this filesystem is not a supported configuration. */
 static void
 validate_supported(
@@ -3155,11 +3218,63 @@ _("agsize (%s) not a multiple of fs blk size (%d)\n"),
  */
 static void
 align_ag_geometry(
-	struct mkfs_params	*cfg)
+	struct mkfs_params	*cfg,
+	struct cli_params	*cli)
 {
 	uint64_t	tmp_agsize;
 	int		dsunit = cfg->dsunit;
 
+	/*
+	 * If the sysadmin wants to force all file data space mappings to be
+	 * aligned to the extszinherit value, then we need the AGs to be
+	 * aligned to the same value.  Skip these checks if the extent size
+	 * hint is zero; the extszinherit validation will fail the format
+	 * later.
+	 */
+	if (cli->sb_feat.forcealign && cli->fsx.fsx_extsize != 0) {
+		/* Perfect alignment; we're done. */
+		if (cfg->agsize % cli->fsx.fsx_extsize == 0)
+			goto validate;
+
+		/*
+		 * Round up to file extent size boundary.  Make sure that
+		 * agsize is still larger than XFS_AG_MIN_BLOCKS(blocklog).
+		 */
+		tmp_agsize = ((cfg->agsize + cli->fsx.fsx_extsize - 1) /
+				cli->fsx.fsx_extsize) * cli->fsx.fsx_extsize;
+
+		/*
+		 * Round down to file extent size boundary if rounding up
+		 * created an AG size that is larger than the AG max.
+		 */
+		if (tmp_agsize > XFS_AG_MAX_BLOCKS(cfg->blocklog))
+			tmp_agsize = (cfg->agsize / cli->fsx.fsx_extsize) *
+							cli->fsx.fsx_extsize;
+
+		if (tmp_agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog) &&
+		    tmp_agsize > XFS_AG_MAX_BLOCKS(cfg->blocklog)) {
+			/*
+			 * Set the agsize to the invalid value so the following
+			 * validation of the ag will fail and print a nice error
+			 * and exit.
+			 */
+			cfg->agsize = tmp_agsize;
+			goto validate;
+		}
+
+		/* Update geometry to be file extent size aligned */
+		cfg->agsize = tmp_agsize;
+		if (!cli_opt_set(&dopts, D_AGCOUNT))
+			cfg->agcount = cfg->dblocks / cfg->agsize +
+					(cfg->dblocks % cfg->agsize != 0);
+
+		if (cli_opt_set(&dopts, D_AGSIZE))
+			fprintf(stderr,
+_("agsize rounded to %lld, extszhint = %d\n"),
+				(long long)cfg->agsize, cli->fsx.fsx_extsize);
+		goto validate;
+	}
+
 	if (!dsunit)
 		goto validate;
 
@@ -3380,6 +3495,8 @@ sb_set_features(
 		sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
 	if (fp->inobtcnt)
 		sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+	if (fp->forcealign)
+		sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_FORCEALIGN;
 	if (fp->bigtime)
 		sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
 
@@ -4184,6 +4301,7 @@ main(
 			.nortalign = false,
 			.bigtime = true,
 			.nrext64 = false,
+			.forcealign = true,
 			/*
 			 * When we decide to enable a new feature by default,
 			 * please remember to update the mkfs conf files.
@@ -4334,7 +4452,7 @@ main(
 	 * aligns to device geometry correctly.
 	 */
 	calculate_initial_ag_geometry(&cfg, &cli);
-	align_ag_geometry(&cfg);
+	align_ag_geometry(&cfg, &cli);
 
 	calculate_imaxpct(&cfg, &cli);
 
@@ -4357,6 +4475,7 @@ main(
 	/* Validate the extent size hints now that @mp is fully set up. */
 	validate_extsize_hint(mp, &cli);
 	validate_cowextsize_hint(mp, &cli);
+	validate_forcealign(mp, &cli);
 
 	validate_supported(mp, &cli);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-09-29  9:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-29  9:53 [PATCH 0/7] xfsprogs: Enable extent forcealign feature John Garry
2023-09-29  9:53 ` [PATCH 1/7] xfs: create a new inode flag to require extsize alignment of file data space John Garry
2023-09-29  9:53 ` [PATCH 2/7] xfs: allow files to require data mappings to be aligned to extszhint John Garry
2023-09-29  9:53 ` [PATCH 3/7] xfs_db: expose force_align feature and flags John Garry
2023-09-29  9:53 ` [PATCH 4/7] xfs_io: implement lsattr and chattr support for forcealign John Garry
2023-09-29  9:53 ` [PATCH 5/7] xfs_repair: check the force-align flag John Garry
2023-09-29  9:53 ` [PATCH 6/7] mkfs: add an extsize= option that allows units John Garry
2023-09-29  9:53 ` [PATCH 7/7] mkfs: enable the new force-align feature John Garry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).