* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox