All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 xfstests resend 0/3] add generic/795
@ 2026-07-20 16:42 ChenXiaoSong
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 1/3] src: factor out common stat code ChenXiaoSong
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: ChenXiaoSong @ 2026-07-20 16:42 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, zlang, lukas
  Cc: linux-cifs, fstests, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

v1->v2:
  - Add patch#01 patch#02.
  - Patch#03: some cleanups.

v1: https://lore.kernel.org/linux-cifs/20260713151658.533155-1-chenxiaosong@chenxiaosong.com/

ChenXiaoSong (3):
  src: factor out common stat code
  generic/002: clean up the test
  generic/795: check nlink returned by fstat()

 src/Makefile          |  13 ++-
 src/fstat.c           |  42 ++++++++++
 src/lstat64.c         | 166 +------------------------------------
 src/stat_common.c     | 185 ++++++++++++++++++++++++++++++++++++++++++
 src/stat_common.h     |  16 ++++
 tests/generic/002     |  16 ++--
 tests/generic/002.out |   2 +-
 tests/generic/795     |  60 ++++++++++++++
 tests/generic/795.out |   2 +
 9 files changed, 324 insertions(+), 178 deletions(-)
 create mode 100644 src/fstat.c
 create mode 100644 src/stat_common.c
 create mode 100644 src/stat_common.h
 create mode 100755 tests/generic/795
 create mode 100644 tests/generic/795.out

-- 
2.43.0


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

* [PATCH v2 xfstests resend 1/3] src: factor out common stat code
  2026-07-20 16:42 [PATCH v2 xfstests resend 0/3] add generic/795 ChenXiaoSong
@ 2026-07-20 16:42 ` ChenXiaoSong
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 2/3] generic/002: clean up the test ChenXiaoSong
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: ChenXiaoSong @ 2026-07-20 16:42 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, zlang, lukas
  Cc: linux-cifs, fstests, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

To see only the differences in the code copied from lstat64.c to
stat_common.c, run:

  git show --find-copies --diff-filter=C <commit-id>

Move command-line parsing and stat output formatting from lstat64 into
stat_common so the implementation can be shared by other stat helpers.

No functional change.

Suggested-by: Zorro Lang <zlang@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
 src/Makefile      |  11 ++-
 src/lstat64.c     | 166 +----------------------------------------
 src/stat_common.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat_common.h |  16 ++++
 4 files changed, 212 insertions(+), 166 deletions(-)
 create mode 100644 src/stat_common.c
 create mode 100644 src/stat_common.h

diff --git a/src/Makefile b/src/Makefile
index 31ac43b2..7fab5d05 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -115,7 +115,8 @@ ifeq ($(NEED_INTERNAL_XFS_IOC_EXCHANGE_RANGE),yes)
 LCFLAGS += -DNEED_INTERNAL_XFS_IOC_EXCHANGE_RANGE
 endif
 
-CFILES = $(TARGETS:=.c)
+CFILES = $(TARGETS:=.c) stat_common.c
+HFILES = stat_common.h
 LDIRT = $(TARGETS) fssum
 
 
@@ -129,7 +130,13 @@ fssum: fssum.c md5.c
 	@echo "    [CC]    $@"
 	$(Q)$(LTLINK) fssum.c md5.c -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
 
-$(TARGETS): $(LIBTEST)
+STAT_TARGETS = lstat64
+
+$(STAT_TARGETS): %: %.c stat_common.c stat_common.h $(LIBTEST)
+	@echo "    [CC]    $@"
+	$(Q)$(LTLINK) $@.c stat_common.c -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(LIBTEST)
+
+$(filter-out $(STAT_TARGETS),$(TARGETS)): $(LIBTEST)
 	@echo "    [CC]    $@"
 	$(Q)$(LTLINK) $@.c -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(LIBTEST)
 
diff --git a/src/lstat64.c b/src/lstat64.c
index db8726fd..5cca2347 100644
--- a/src/lstat64.c
+++ b/src/lstat64.c
@@ -12,172 +12,10 @@
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
 
-long	timebuf;
-
-void
-timesince(long timesec)
-{
-	long	d_since;	/* days */
-	long	h_since;	/* hours */
-	long	m_since;	/* minutes */
-	long	s_since;	/* seconds */
-
-	s_since = timebuf - timesec;
-	d_since = s_since / 86400l ;
-	s_since -= d_since * 86400l ;
-	h_since = s_since / 3600l ;
-	s_since -= h_since * 3600l ;
-	m_since = s_since / 60l ;
-	s_since -= m_since * 60l ;
-
-	printf("(%05ld.%02ld:%02ld:%02ld)\n",
-			d_since, h_since, m_since, s_since);
-}
-
-void
-usage(void)
-{
-	fprintf(stderr, "Usage: lstat64 [-t] filename ...\n");
-	exit(1);
-}
+#include "stat_common.h"
 
 int
 main(int argc, char **argv)
 {
-	struct stat64	sbuf;
-	int		i, c;
-	int		terse_flag = 0;
-
-	while ((c = getopt(argc, argv, "t")) != EOF) {
-		switch (c) {
-			case 't':
-				terse_flag = 1;
-				break;
-
-			case '?':
-				usage();
-		}
-	}
-	if (optind == argc) {
-		usage();
-	}
-
-	time(&timebuf);
-
-	for (i = optind; i < argc; i++) {
-		char mode[] = "----------";
-
-		if( lstat64(argv[i], &sbuf) < 0) {
-			perror(argv[i]);
-			continue;
-		}
-
-		if (terse_flag) {
-			printf("%s %llu ", argv[i], (unsigned long long)sbuf.st_size);
-		}
-		else {
-			printf("  File: \"%s\"\n", argv[i]);
-			printf("  Size: %-10llu", (unsigned long long)sbuf.st_size);
-		}
-
-		if (sbuf.st_mode & S_IXOTH)
-			mode[9] = 'x';
-		if (sbuf.st_mode & S_IWOTH)
-			mode[8] = 'w';
-		if (sbuf.st_mode & S_IROTH)
-			mode[7] = 'r';
-		if (sbuf.st_mode & S_IXGRP)
-			mode[6] = 'x';
-		if (sbuf.st_mode & S_IWGRP)
-			mode[5] = 'w';
-		if (sbuf.st_mode & S_IRGRP)
-			mode[4] = 'r';
-		if (sbuf.st_mode & S_IXUSR)
-			mode[3] = 'x';
-		if (sbuf.st_mode & S_IWUSR)
-			mode[2] = 'w';
-		if (sbuf.st_mode & S_IRUSR)
-			mode[1] = 'r';
-		if (sbuf.st_mode & S_ISVTX)
-			mode[9] = 't';
-		if (sbuf.st_mode & S_ISGID)
-			mode[6] = 's';
-		if (sbuf.st_mode & S_ISUID)
-			mode[3] = 's';
-
-		if (!terse_flag)
-			printf("   Filetype: ");
-		switch (sbuf.st_mode & S_IFMT) {
-		case S_IFSOCK:	
-			if (!terse_flag)
-				puts("Socket");
-			mode[0] = 's';
-			break;
-		case S_IFDIR:	
-			if (!terse_flag)
-				puts("Directory");
-			mode[0] = 'd';
-			break;
-		case S_IFCHR:	
-			if (!terse_flag)
-				puts("Character Device");
-			mode[0] = 'c';
-			break;
-		case S_IFBLK:	
-			if (!terse_flag)
-				puts("Block Device");
-			mode[0] = 'b';
-			break;
-		case S_IFREG:	
-			if (!terse_flag)
-				puts("Regular File");
-			mode[0] = '-';
-			break;
-		case S_IFLNK:	
-			if (!terse_flag)
-				puts("Symbolic Link");
-			mode[0] = 'l';
-			break;
-		case S_IFIFO:	
-			if (!terse_flag)
-				puts("Fifo File");
-			mode[0] = 'f';
-			break;
-		default:	
-			if (!terse_flag)
-				puts("Unknown");
-			mode[0] = '?';
-		}
-
-		if (terse_flag) {
-			printf("%s %d,%d\n", mode, (int)sbuf.st_uid, (int)sbuf.st_gid);
-			continue;
-		}
-
-		printf("  Mode: (%04o/%s)", (unsigned int)(sbuf.st_mode & 07777), mode);
-		printf("         Uid: (%d)", (int)sbuf.st_uid);
-		printf("  Gid: (%d)\n", (int)sbuf.st_gid);
-		printf("Device: %2d,%-2d", major(sbuf.st_dev),
-				minor(sbuf.st_dev));
-		printf("  Inode: %-9llu", (unsigned long long)sbuf.st_ino);
-		printf(" Links: %-5ld", (long)sbuf.st_nlink);
-
-		if ( ((sbuf.st_mode & S_IFMT) == S_IFCHR)
-		    || ((sbuf.st_mode & S_IFMT) == S_IFBLK) )
-			printf("     Device type: %2d,%-2d\n",
-				major(sbuf.st_rdev), minor(sbuf.st_rdev));
-		else
-			printf("\n");
-
-		printf("Access: %.24s",ctime(&sbuf.st_atime));
-		timesince(sbuf.st_atime);
-		printf("Modify: %.24s",ctime(&sbuf.st_mtime));
-		timesince(sbuf.st_mtime);
-		printf("Change: %.24s",ctime(&sbuf.st_ctime));
-		timesince(sbuf.st_ctime);
-
-		if (i+1 < argc)
-			printf("\n");
-	}
-	exit(0);
+	return handle_stat(argc, argv, "lstat64", lstat64);
 }
diff --git a/src/stat_common.c b/src/stat_common.c
new file mode 100644
index 00000000..e94114ff
--- /dev/null
+++ b/src/stat_common.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ */
+ 
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+
+#include "stat_common.h"
+
+long	timebuf;
+
+void
+timesince(long timesec)
+{
+	long	d_since;	/* days */
+	long	h_since;	/* hours */
+	long	m_since;	/* minutes */
+	long	s_since;	/* seconds */
+
+	s_since = timebuf - timesec;
+	d_since = s_since / 86400l ;
+	s_since -= d_since * 86400l ;
+	h_since = s_since / 3600l ;
+	s_since -= h_since * 3600l ;
+	m_since = s_since / 60l ;
+	s_since -= m_since * 60l ;
+
+	printf("(%05ld.%02ld:%02ld:%02ld)\n",
+			d_since, h_since, m_since, s_since);
+}
+
+void
+usage(const char *program)
+{
+	fprintf(stderr, "Usage: %s [-t] filename ...\n", program);
+	exit(1);
+}
+
+int
+handle_stat(int argc, char **argv, const char *program, get_stat_fn get_stat)
+{
+	struct stat64	sbuf;
+	int		i, c;
+	int		terse_flag = 0;
+
+	while ((c = getopt(argc, argv, "t")) != EOF) {
+		switch (c) {
+			case 't':
+				terse_flag = 1;
+				break;
+
+			case '?':
+				usage(program);
+		}
+	}
+	if (optind == argc) {
+		usage(program);
+	}
+
+	time(&timebuf);
+
+	for (i = optind; i < argc; i++) {
+		char mode[] = "----------";
+
+		if(get_stat(argv[i], &sbuf) < 0) {
+			perror(argv[i]);
+			continue;
+		}
+
+		if (terse_flag) {
+			printf("%s %llu ", argv[i], (unsigned long long)sbuf.st_size);
+		}
+		else {
+			printf("  File: \"%s\"\n", argv[i]);
+			printf("  Size: %-10llu", (unsigned long long)sbuf.st_size);
+		}
+
+		if (sbuf.st_mode & S_IXOTH)
+			mode[9] = 'x';
+		if (sbuf.st_mode & S_IWOTH)
+			mode[8] = 'w';
+		if (sbuf.st_mode & S_IROTH)
+			mode[7] = 'r';
+		if (sbuf.st_mode & S_IXGRP)
+			mode[6] = 'x';
+		if (sbuf.st_mode & S_IWGRP)
+			mode[5] = 'w';
+		if (sbuf.st_mode & S_IRGRP)
+			mode[4] = 'r';
+		if (sbuf.st_mode & S_IXUSR)
+			mode[3] = 'x';
+		if (sbuf.st_mode & S_IWUSR)
+			mode[2] = 'w';
+		if (sbuf.st_mode & S_IRUSR)
+			mode[1] = 'r';
+		if (sbuf.st_mode & S_ISVTX)
+			mode[9] = 't';
+		if (sbuf.st_mode & S_ISGID)
+			mode[6] = 's';
+		if (sbuf.st_mode & S_ISUID)
+			mode[3] = 's';
+
+		if (!terse_flag)
+			printf("   Filetype: ");
+		switch (sbuf.st_mode & S_IFMT) {
+		case S_IFSOCK:	
+			if (!terse_flag)
+				puts("Socket");
+			mode[0] = 's';
+			break;
+		case S_IFDIR:	
+			if (!terse_flag)
+				puts("Directory");
+			mode[0] = 'd';
+			break;
+		case S_IFCHR:	
+			if (!terse_flag)
+				puts("Character Device");
+			mode[0] = 'c';
+			break;
+		case S_IFBLK:	
+			if (!terse_flag)
+				puts("Block Device");
+			mode[0] = 'b';
+			break;
+		case S_IFREG:	
+			if (!terse_flag)
+				puts("Regular File");
+			mode[0] = '-';
+			break;
+		case S_IFLNK:	
+			if (!terse_flag)
+				puts("Symbolic Link");
+			mode[0] = 'l';
+			break;
+		case S_IFIFO:	
+			if (!terse_flag)
+				puts("Fifo File");
+			mode[0] = 'f';
+			break;
+		default:	
+			if (!terse_flag)
+				puts("Unknown");
+			mode[0] = '?';
+		}
+
+		if (terse_flag) {
+			printf("%s %d,%d\n", mode, (int)sbuf.st_uid, (int)sbuf.st_gid);
+			continue;
+		}
+
+		printf("  Mode: (%04o/%s)", (unsigned int)(sbuf.st_mode & 07777), mode);
+		printf("         Uid: (%d)", (int)sbuf.st_uid);
+		printf("  Gid: (%d)\n", (int)sbuf.st_gid);
+		printf("Device: %2d,%-2d", major(sbuf.st_dev),
+				minor(sbuf.st_dev));
+		printf("  Inode: %-9llu", (unsigned long long)sbuf.st_ino);
+		printf(" Links: %-5ld", (long)sbuf.st_nlink);
+
+		if ( ((sbuf.st_mode & S_IFMT) == S_IFCHR)
+		    || ((sbuf.st_mode & S_IFMT) == S_IFBLK) )
+			printf("     Device type: %2d,%-2d\n",
+				major(sbuf.st_rdev), minor(sbuf.st_rdev));
+		else
+			printf("\n");
+
+		printf("Access: %.24s",ctime(&sbuf.st_atime));
+		timesince(sbuf.st_atime);
+		printf("Modify: %.24s",ctime(&sbuf.st_mtime));
+		timesince(sbuf.st_mtime);
+		printf("Change: %.24s",ctime(&sbuf.st_ctime));
+		timesince(sbuf.st_ctime);
+
+		if (i+1 < argc)
+			printf("\n");
+	}
+	exit(0);
+}
diff --git a/src/stat_common.h b/src/stat_common.h
new file mode 100644
index 00000000..290643d7
--- /dev/null
+++ b/src/stat_common.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ */
+
+#ifndef STAT_COMMON_H
+#define STAT_COMMON_H
+
+#include <sys/stat.h>
+
+typedef int (*get_stat_fn)(const char *path, struct stat64 *sbuf);
+
+int handle_stat(int argc, char **argv, const char *program, get_stat_fn get_stat);
+
+#endif /* STAT_COMMON_H */
-- 
2.43.0


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

* [PATCH v2 xfstests resend 2/3] generic/002: clean up the test
  2026-07-20 16:42 [PATCH v2 xfstests resend 0/3] add generic/795 ChenXiaoSong
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 1/3] src: factor out common stat code ChenXiaoSong
@ 2026-07-20 16:42 ` ChenXiaoSong
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 3/3] generic/795: check nlink returned by fstat() ChenXiaoSong
  2026-07-28  3:28 ` [PATCH v2 xfstests resend 0/3] add generic/795 Christoph Hellwig
  3 siblings, 0 replies; 6+ messages in thread
From: ChenXiaoSong @ 2026-07-20 16:42 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, zlang, lukas
  Cc: linux-cifs, fstests, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

Add the hardlink group and use shorter loops. Use _exit() and change
the success text to "Silence is golden".

Suggested-by: Zorro Lang <zlang@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
 tests/generic/002     | 16 ++++++----------
 tests/generic/002.out |  2 +-
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/tests/generic/002 b/tests/generic/002
index 6df57a7a..9b210705 100755
--- a/tests/generic/002
+++ b/tests/generic/002
@@ -2,12 +2,12 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
 #
-# FS QA Test No. 002
+# FS QA Test 002
 #
 # simple inode link count test for a regular file
 #
 . ./common/preamble
-_begin_fstest metadata udf auto quick
+_begin_fstest metadata udf auto quick hardlink
 
 # Import common functions.
 . ./common/filter
@@ -17,14 +17,11 @@ status=0	# success is the default!
 _require_test
 _require_hardlinks
 
-echo "Silence is goodness ..."
-
 # ensure target directory exists
 mkdir `dirname $TEST_DIR/tmp` 2>/dev/null
 
 touch $TEST_DIR/tmp.1
-for l in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-do
+for ((l = 2; l <= 20; l++)); do
     ln $TEST_DIR/tmp.1 $TEST_DIR/tmp.$l
     x=`$here/src/lstat64 $TEST_DIR/tmp.1 | sed -n -e '/ Links: /s/.*Links: *//p'`
     if [ "$l" -ne $x ]
@@ -35,8 +32,7 @@ do
     fi
 done
 
-for l in 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
-do
+for ((l = 20; l >= 1; l--)); do
     x=`$here/src/lstat64 $TEST_DIR/tmp.1 | sed -n -e '/ Links: /s/.*Links: *//p'`
     if [ "$l" -ne $x ]
     then
@@ -47,5 +43,5 @@ do
     rm -f $TEST_DIR/tmp.$l
 done
 
-# success, all done
-exit
+echo "Silence is golden"
+exit $status
diff --git a/tests/generic/002.out b/tests/generic/002.out
index 11426b54..61705c7c 100644
--- a/tests/generic/002.out
+++ b/tests/generic/002.out
@@ -1,2 +1,2 @@
 QA output created by 002
-Silence is goodness ...
+Silence is golden
-- 
2.43.0


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

* [PATCH v2 xfstests resend 3/3] generic/795: check nlink returned by fstat()
  2026-07-20 16:42 [PATCH v2 xfstests resend 0/3] add generic/795 ChenXiaoSong
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 1/3] src: factor out common stat code ChenXiaoSong
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 2/3] generic/002: clean up the test ChenXiaoSong
@ 2026-07-20 16:42 ` ChenXiaoSong
  2026-07-28  3:28 ` [PATCH v2 xfstests resend 0/3] add generic/795 Christoph Hellwig
  3 siblings, 0 replies; 6+ messages in thread
From: ChenXiaoSong @ 2026-07-20 16:42 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, zlang, lukas
  Cc: linux-cifs, fstests, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

Add a test to verify that fstat(2) returns the expected
st_nlink value as hardlinks are created and removed.

Suggested-by: Zorro Lang <zlang@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
 src/Makefile          |  4 +--
 src/fstat.c           | 42 ++++++++++++++++++++++++++++++
 tests/generic/795     | 60 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/795.out |  2 ++
 4 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 src/fstat.c
 create mode 100755 tests/generic/795
 create mode 100644 tests/generic/795.out

diff --git a/src/Makefile b/src/Makefile
index 7fab5d05..fd2622e8 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -6,7 +6,7 @@
 TOPDIR = ..
 include $(TOPDIR)/include/builddefs
 
-TARGETS = dirstress fill fill2 getpagesize holes lstat64 \
+TARGETS = dirstress fill fill2 getpagesize holes lstat64 fstat \
 	nametest permname randholes runas truncfile usemem \
 	mmapcat append_reader append_writer dirperf metaperf \
 	devzero feature alloc fault fstest t_access_root \
@@ -130,7 +130,7 @@ fssum: fssum.c md5.c
 	@echo "    [CC]    $@"
 	$(Q)$(LTLINK) fssum.c md5.c -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
 
-STAT_TARGETS = lstat64
+STAT_TARGETS = lstat64 fstat
 
 $(STAT_TARGETS): %: %.c stat_common.c stat_common.h $(LIBTEST)
 	@echo "    [CC]    $@"
diff --git a/src/fstat.c b/src/fstat.c
new file mode 100644
index 00000000..fb878f77
--- /dev/null
+++ b/src/fstat.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 KylinSoft Co., Ltd. All rights reserved.
+ * Author(s): ChenXiaoSong <chenxiaosong@kylinos.cn>
+ *
+ *  from
+ *  src/lstat64.c
+ *  Copyright (c) 2000-2002 Silicon Graphics, Inc.
+ *  All Rights Reserved.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "stat_common.h"
+
+static int
+get_fstat(const char *path, struct stat64 *sbuf)
+{
+	int	fd;
+	int	ret;
+	int	saved_errno;
+
+	fd = open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return -1;
+
+	ret = fstat64(fd, sbuf);
+	saved_errno = errno;
+	close(fd);
+	errno = saved_errno;
+
+	return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+	return handle_stat(argc, argv, "fstat", get_fstat);
+}
diff --git a/tests/generic/795 b/tests/generic/795
new file mode 100755
index 00000000..0fc9a9bc
--- /dev/null
+++ b/tests/generic/795
@@ -0,0 +1,60 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2026 KylinSoft Co., Ltd. All rights reserved.
+# Author(s): ChenXiaoSong <chenxiaosong@kylinos.cn>
+#
+# FS QA Test 795
+#
+# Check that fstat(2) returns the correct hard link count for a regular file.
+# Regression test for kernel commit:
+# 9dd1964ac59d ("smb/client: fix incorrect nlink returned by fstat()")
+#
+#  from
+#  tests/generic/002
+#  Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
+#
+. ./common/preamble
+_begin_fstest metadata auto quick hardlink
+
+# Override the default cleanup function.
+_cleanup()
+{
+	cd /
+	[ -d "$testdir" ] && rm -rf $testdir
+}
+
+status=0	# success is the default!
+
+_require_test
+_require_hardlinks
+_require_test_program fstat
+
+_fixed_by_fs_commit cifs 9dd1964ac59d \
+	"smb/client: fix incorrect nlink returned by fstat()"
+
+testdir=$TEST_DIR/$$
+mkdir -p $testdir
+
+touch $testdir/tmp.1
+for ((l = 2; l <= 20; l++)); do
+	ln $testdir/tmp.1 $testdir/tmp.$l
+	x=`$here/src/fstat $testdir/tmp.1 | sed -n -e '/ Links: /s/.*Links: *//p'`
+	if [ "$l" -ne $x ]; then
+		echo "Arrgh, created link #$l and fstat looks like ..."
+		$here/src/fstat $testdir/tmp.1
+		status=1
+	fi
+done
+
+for ((l = 20; l >= 1; l--)); do
+	x=`$here/src/fstat $testdir/tmp.1 | sed -n -e '/ Links: /s/.*Links: *//p'`
+	if [ "$l" -ne $x ]; then
+		echo "Arrgh, about to remove link #$l and fstat looks like ..."
+		$here/src/fstat $testdir/tmp.1
+		status=1
+	fi
+	rm -f $testdir/tmp.$l
+done
+
+echo "Silence is golden"
+exit $status
diff --git a/tests/generic/795.out b/tests/generic/795.out
new file mode 100644
index 00000000..cb357003
--- /dev/null
+++ b/tests/generic/795.out
@@ -0,0 +1,2 @@
+QA output created by 795
+Silence is golden
-- 
2.43.0


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

* Re: [PATCH v2 xfstests resend 0/3] add generic/795
  2026-07-20 16:42 [PATCH v2 xfstests resend 0/3] add generic/795 ChenXiaoSong
                   ` (2 preceding siblings ...)
  2026-07-20 16:42 ` [PATCH v2 xfstests resend 3/3] generic/795: check nlink returned by fstat() ChenXiaoSong
@ 2026-07-28  3:28 ` Christoph Hellwig
  2026-07-28  3:35   ` ChenXiaoSong
  3 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2026-07-28  3:28 UTC (permalink / raw)
  To: ChenXiaoSong
  Cc: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, zlang, lukas, linux-cifs, fstests,
	ChenXiaoSong

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


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

* Re: [PATCH v2 xfstests resend 0/3] add generic/795
  2026-07-28  3:28 ` [PATCH v2 xfstests resend 0/3] add generic/795 Christoph Hellwig
@ 2026-07-28  3:35   ` ChenXiaoSong
  0 siblings, 0 replies; 6+ messages in thread
From: ChenXiaoSong @ 2026-07-28  3:35 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, zlang, lukas, linux-cifs, fstests,
	ChenXiaoSong

Hi Christoph,

Thanks for your review. There is new version:
https://lore.kernel.org/linux-cifs/20260724031210.332153-1-chenxiaosong@chenxiaosong.com/

On 7/28/26 11:28, Christoph Hellwig wrote:
> Looks good:
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> 

-- 
ChenXiaoSong <chenxiaosong@chenxiaosong.com>
Chinese Homepage: https://chenxiaosong.com
English Homepage: https://chenxiaosong.com/en


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

end of thread, other threads:[~2026-07-28  3:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 16:42 [PATCH v2 xfstests resend 0/3] add generic/795 ChenXiaoSong
2026-07-20 16:42 ` [PATCH v2 xfstests resend 1/3] src: factor out common stat code ChenXiaoSong
2026-07-20 16:42 ` [PATCH v2 xfstests resend 2/3] generic/002: clean up the test ChenXiaoSong
2026-07-20 16:42 ` [PATCH v2 xfstests resend 3/3] generic/795: check nlink returned by fstat() ChenXiaoSong
2026-07-28  3:28 ` [PATCH v2 xfstests resend 0/3] add generic/795 Christoph Hellwig
2026-07-28  3:35   ` ChenXiaoSong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.