All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Change fssum to support POSIX
@ 2020-06-21 23:14 Arvind Raghavan
  2020-06-21 23:15 ` [PATCH v2 1/7] src/fssum: Make sum_file_data global Arvind Raghavan
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:14 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

This patch series modifies fssum to be able to verify POSIX
fsync/fdatasync guarantees. In particular, it allows single
files/symlinks to be passed as input, which allows us to verify
an fsync on a single file without checking the entire directory.

It also adds an option for non-recursive directory traversal,
which is useful because POSIX fsync doesn't guarantee that all
subdirectories are synced. Finally, it adds a flag that allows
file size to be ignored (currently enabled by default). This is
useful because POSIX fsync of a directory doesn't guarantee that
the data in the children is persisted.

These changes will be followed up with several Crashmonkey [1]
tests which make use of these changes.

[1] https://github.com/utsaslab/crashmonkey

Changes since v1:
- Change readlink to readlinkat to fix bug
- Added helper sum_one function to simplify single file input
- Moved fstat -> fstatat change and both of the former into separate
  commit

Manually verified that all of the tests that use fssum still pass for
each commit:

tests/btrfs/083
tests/btrfs/050
tests/btrfs/007
tests/btrfs/016
tests/btrfs/128
tests/btrfs/040
tests/btrfs/092
tests/btrfs/087
tests/btrfs/039
tests/btrfs/127
tests/btrfs/044
tests/btrfs/144
tests/btrfs/168
tests/btrfs/134
tests/btrfs/045
tests/btrfs/129
tests/btrfs/043
tests/btrfs/145
tests/btrfs/191
tests/btrfs/147
tests/btrfs/030
tests/btrfs/077
tests/btrfs/155
tests/btrfs/133
tests/btrfs/038
tests/btrfs/053
tests/btrfs/189
tests/btrfs/084
tests/btrfs/135
tests/btrfs/200
tests/btrfs/178
tests/btrfs/051
tests/generic/474
tests/generic/547

Arvind Raghavan (7):
  src/fssum: Make sum_file_data global
  src/fssum: Refactoring changes for recursive traversal
  src/fssum: Refactor recursive traversal
  src/fssum: Add flag -R for non-recursive mode
  src/fssum: Add a flag for including file size in checksum
  src/fssum: Allow single file input
  src/fssum: Fix whitespace in usage

 src/fssum.c | 354 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 203 insertions(+), 151 deletions(-)

-- 
2.20.1


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

* [PATCH v2 1/7] src/fssum: Make sum_file_data global
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
@ 2020-06-21 23:15 ` Arvind Raghavan
  2020-06-21 23:15 ` [PATCH v2 2/7] src/fssum: Refactoring changes for recursive traversal Arvind Raghavan
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:15 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

Makes deciding which function to use for summing file data happen once
in main instead of for each file.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 src/fssum.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 3d97a70b..30f456c2 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -62,6 +62,7 @@ int n_excludes = 0;
 int verbose = 0;
 FILE *out_fp;
 FILE *in_fp;
+sum_file_data_t sum_file_data;
 
 enum _flags {
 	FLAG_UID,
@@ -514,8 +515,6 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 	int ret;
 	int fd;
 	int excl;
-	sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ?
-			sum_file_data_strict : sum_file_data_permissive;
 	struct stat64 dir_st;
 
 	if (fstat64(dirfd, &dir_st)) {
@@ -824,6 +823,9 @@ main(int argc, char *argv[])
 			flagstring[i] -= 'a' - 'A';
 	}
 
+	sum_file_data = flags[FLAG_STRUCTURE] ?
+			sum_file_data_strict : sum_file_data_permissive;
+
 	path = argv[optind];
 	plen = strlen(path);
 	if (path[plen - 1] == '/') {
-- 
2.20.1


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

* [PATCH v2 2/7] src/fssum: Refactoring changes for recursive traversal
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
  2020-06-21 23:15 ` [PATCH v2 1/7] src/fssum: Make sum_file_data global Arvind Raghavan
@ 2020-06-21 23:15 ` Arvind Raghavan
  2020-06-22  6:47   ` Amir Goldstein
  2020-06-21 23:16 ` [PATCH v2 3/7] src/fssum: Recursive traversal refactoring Arvind Raghavan
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:15 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

Refactoring changes needed for recursive traversal and single file
input. Makes fstat and readlink use the 'at' alternatives, and creates a
helper function for opening files.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
---
 src/fssum.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 30f456c2..135dd60f 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -503,6 +503,13 @@ malformed:
 		excess_file(fn);
 }
 
+int open_one(int dirfd, const char *name)
+{
+	if (!name || !*name)
+		return dup(dirfd);
+	return openat(dirfd, name, 0);
+}
+
 void
 sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 {
@@ -563,12 +570,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 				goto next;
 		}
 
-		ret = fchdir(dirfd);
-		if (ret == -1) {
-			perror("fchdir");
-			exit(-1);
-		}
-		ret = lstat64(namelist[i], &st);
+		ret = fstatat64(dirfd, namelist[i], &st, AT_SYMLINK_NOFOLLOW);
 		if (ret) {
 			fprintf(stderr, "stat failed for %s/%s: %s\n",
 				path_prefix, path, strerror(errno));
@@ -597,7 +599,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			sum_add_time(&meta, st.st_ctime);
 		if (flags[FLAG_XATTRS] &&
 		    (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
-			fd = openat(dirfd, namelist[i], 0);
+			fd = open_one(dirfd, namelist[i]);
 			if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 				sum_add_u64(&meta, errno);
 			} else if (fd == -1) {
@@ -618,7 +620,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			}
 		}
 		if (S_ISDIR(st.st_mode)) {
-			fd = openat(dirfd, namelist[i], 0);
+			fd = open_one(dirfd, namelist[i]);
 			if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 				sum_add_u64(&meta, errno);
 			} else if (fd == -1) {
@@ -635,7 +637,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 				if (verbose)
 					fprintf(stderr, "file %s\n",
 						namelist[i]);
-				fd = openat(dirfd, namelist[i], 0);
+				fd = open_one(dirfd, namelist[i]);
 				if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 					sum_add_u64(&meta, errno);
 				} else if (fd == -1) {
@@ -659,7 +661,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 				}
 			}
 		} else if (S_ISLNK(st.st_mode)) {
-			ret = readlink(namelist[i], buf, sizeof(buf));
+			ret = readlinkat(dirfd, namelist[i], buf, sizeof(buf));
 			if (ret == -1) {
 				perror("readlink");
 				exit(-1);
-- 
2.20.1


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

* [PATCH v2 3/7] src/fssum: Recursive traversal refactoring
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
  2020-06-21 23:15 ` [PATCH v2 1/7] src/fssum: Make sum_file_data global Arvind Raghavan
  2020-06-21 23:15 ` [PATCH v2 2/7] src/fssum: Refactoring changes for recursive traversal Arvind Raghavan
@ 2020-06-21 23:16 ` Arvind Raghavan
  2020-06-22  7:42   ` Amir Goldstein
  2020-06-21 23:16 ` [PATCH v2 4/7] src/fssum: Add flag -R for non-recursive mode Arvind Raghavan
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:16 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

Moves some logic from the recursive directory traversal into a helper
function to make it easier to add support for regular files. Does not
change functionality.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
---
 src/fssum.c | 257 ++++++++++++++++++++++++++++------------------------
 1 file changed, 139 insertions(+), 118 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 135dd60f..506ca7fe 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -510,6 +510,10 @@ int open_one(int dirfd, const char *name)
 	return openat(dirfd, name, 0);
 }
 
+void
+sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
+		char *path_in, char *name);
+
 void
 sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 {
@@ -520,8 +524,6 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 	int entries = 0;
 	int i;
 	int ret;
-	int fd;
-	int excl;
 	struct stat64 dir_st;
 
 	if (fstat64(dirfd, &dir_st)) {
@@ -556,147 +558,166 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 	qsort(namelist, entries, sizeof(*namelist), namecmp);
 	for (i = 0; i < entries; ++i) {
 		struct stat64 st;
-		sum_t cs;
-		sum_t meta;
-		char *path;
-
-		sum_init(&cs);
-		sum_init(&meta);
-		path = alloc(strlen(path_in) + strlen(namelist[i]) + 3);
-		sprintf(path, "%s/%s", path_in, namelist[i]);
-		for (excl = 0; excl < n_excludes; ++excl) {
-			if (strncmp(excludes[excl].path, path,
-			    excludes[excl].len) == 0)
-				goto next;
-		}
 
 		ret = fstatat64(dirfd, namelist[i], &st, AT_SYMLINK_NOFOLLOW);
 		if (ret) {
-			fprintf(stderr, "stat failed for %s/%s: %s\n",
-				path_prefix, path, strerror(errno));
+			fprintf(stderr, "stat failed for %s/%s/%s: %s\n",
+				path_prefix, path_in, namelist[i],
+				strerror(errno));
 			exit(-1);
 		}
 
 		/* We are crossing into a different subvol, skip this subtree. */
 		if (st.st_dev != dir_st.st_dev)
-			goto next;
-
-		sum_add_u64(&meta, level);
-		sum_add(&meta, namelist[i], strlen(namelist[i]));
-		if (!S_ISDIR(st.st_mode))
-			sum_add_u64(&meta, st.st_nlink);
-		if (flags[FLAG_UID])
-			sum_add_u64(&meta, st.st_uid);
-		if (flags[FLAG_GID])
-			sum_add_u64(&meta, st.st_gid);
-		if (flags[FLAG_MODE])
-			sum_add_u64(&meta, st.st_mode);
-		if (flags[FLAG_ATIME])
-			sum_add_time(&meta, st.st_atime);
-		if (flags[FLAG_MTIME])
-			sum_add_time(&meta, st.st_mtime);
-		if (flags[FLAG_CTIME])
-			sum_add_time(&meta, st.st_ctime);
-		if (flags[FLAG_XATTRS] &&
-		    (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
-			fd = open_one(dirfd, namelist[i]);
-			if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
-				sum_add_u64(&meta, errno);
-			} else if (fd == -1) {
-				fprintf(stderr, "open failed for %s/%s: %s\n",
-					path_prefix, path, strerror(errno));
+			continue;
+
+		sum_one(dirfd, level, dircs, path_prefix, path_in, namelist[i]);
+	}
+}
+
+void
+sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
+		char *path_in, char *name) {
+	sum_t cs;
+	sum_t meta;
+	int fd;
+	int ret;
+	int excl;
+	char* path;
+	struct stat64 st;
+
+	sum_init(&cs);
+	sum_init(&meta);
+	path = alloc(strlen(path_in) + strlen(name) + 3);
+	sprintf(path, "%s/%s", path_in, name);
+	for (excl = 0; excl < n_excludes; ++excl) {
+		if (strncmp(excludes[excl].path, path,
+			excludes[excl].len) == 0)
+			goto out;
+	}
+
+	ret = fstatat64(dirfd, name, &st, AT_SYMLINK_NOFOLLOW);
+	if (ret) {
+		fprintf(stderr, "stat failed for %s/%s: %s\n",
+			path_prefix, path, strerror(errno));
+		exit(-1);
+	}
+
+	sum_add_u64(&meta, level);
+	sum_add(&meta, name, strlen(name));
+	if (!S_ISDIR(st.st_mode))
+		sum_add_u64(&meta, st.st_nlink);
+	if (flags[FLAG_UID])
+		sum_add_u64(&meta, st.st_uid);
+	if (flags[FLAG_GID])
+		sum_add_u64(&meta, st.st_gid);
+	if (flags[FLAG_MODE])
+		sum_add_u64(&meta, st.st_mode);
+	if (flags[FLAG_ATIME])
+		sum_add_time(&meta, st.st_atime);
+	if (flags[FLAG_MTIME])
+		sum_add_time(&meta, st.st_mtime);
+	if (flags[FLAG_CTIME])
+		sum_add_time(&meta, st.st_ctime);
+	if (flags[FLAG_XATTRS] &&
+		(S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
+		fd = open_one(dirfd, name);
+		if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+			sum_add_u64(&meta, errno);
+		} else if (fd == -1) {
+			fprintf(stderr, "open failed for %s/%s: %s\n",
+				path_prefix, path, strerror(errno));
+			exit(-1);
+		} else {
+			ret = sum_xattrs(fd, &meta);
+			close(fd);
+			if (ret < 0) {
+				fprintf(stderr,
+					"failed to read xattrs from "
+					"%s/%s: %s\n",
+					path_prefix, path,
+					strerror(-ret));
 				exit(-1);
-			} else {
-				ret = sum_xattrs(fd, &meta);
-				close(fd);
-				if (ret < 0) {
-					fprintf(stderr,
-						"failed to read xattrs from "
-						"%s/%s: %s\n",
-						path_prefix, path,
-						strerror(-ret));
-					exit(-1);
-				}
 			}
 		}
-		if (S_ISDIR(st.st_mode)) {
-			fd = open_one(dirfd, namelist[i]);
+	}
+	if (S_ISDIR(st.st_mode)) {
+		fd = open_one(dirfd, name);
+		if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+			sum_add_u64(&meta, errno);
+		} else if (fd == -1) {
+			fprintf(stderr, "open failed for %s/%s: %s\n",
+				path_prefix, path, strerror(errno));
+			exit(-1);
+		} else {
+			sum(fd, level + 1, &cs, path_prefix, path);
+			close(fd);
+		}
+	} else if (S_ISREG(st.st_mode)) {
+		sum_add_u64(&meta, st.st_size);
+		if (flags[FLAG_DATA]) {
+			if (verbose)
+				fprintf(stderr, "file %s\n",
+					name);
+			fd = open_one(dirfd, name);
 			if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 				sum_add_u64(&meta, errno);
 			} else if (fd == -1) {
-				fprintf(stderr, "open failed for %s/%s: %s\n",
-					path_prefix, path, strerror(errno));
+				fprintf(stderr,
+					"open failed for %s/%s: %s\n",
+					path_prefix, path,
+					strerror(errno));
 				exit(-1);
-			} else {
-				sum(fd, level + 1, &cs, path_prefix, path);
-				close(fd);
 			}
-		} else if (S_ISREG(st.st_mode)) {
-			sum_add_u64(&meta, st.st_size);
-			if (flags[FLAG_DATA]) {
-				if (verbose)
-					fprintf(stderr, "file %s\n",
-						namelist[i]);
-				fd = open_one(dirfd, namelist[i]);
-				if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
-					sum_add_u64(&meta, errno);
-				} else if (fd == -1) {
+			if (fd != -1) {
+				ret = sum_file_data(fd, &cs);
+				if (ret < 0) {
 					fprintf(stderr,
-						"open failed for %s/%s: %s\n",
+						"read failed for "
+						"%s/%s: %s\n",
 						path_prefix, path,
 						strerror(errno));
 					exit(-1);
 				}
-				if (fd != -1) {
-					ret = sum_file_data(fd, &cs);
-					if (ret < 0) {
-						fprintf(stderr,
-							"read failed for "
-							"%s/%s: %s\n",
-							path_prefix, path,
-							strerror(errno));
-						exit(-1);
-					}
-					close(fd);
-				}
-			}
-		} else if (S_ISLNK(st.st_mode)) {
-			ret = readlinkat(dirfd, namelist[i], buf, sizeof(buf));
-			if (ret == -1) {
-				perror("readlink");
-				exit(-1);
+				close(fd);
 			}
-			sum_add(&cs, buf, ret);
-		} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
-			sum_add_u64(&cs, major(st.st_rdev));
-			sum_add_u64(&cs, minor(st.st_rdev));
 		}
-		sum_fini(&cs);
-		sum_fini(&meta);
-		if (gen_manifest || in_manifest) {
-			char *fn;
-			char *m;
-			char *c;
-
-			if (S_ISDIR(st.st_mode))
-				strcat(path, "/");
-			fn = escape(path);
-			m = sum_to_string(&meta);
-			c = sum_to_string(&cs);
-
-			if (gen_manifest)
-				fprintf(out_fp, "%s %s %s\n", fn, m, c);
-			if (in_manifest)
-				check_manifest(fn, m, c, 0);
-			free(c);
-			free(m);
-			free(fn);
+	} else if (S_ISLNK(st.st_mode)) {
+		ret = readlinkat(dirfd, name, buf, sizeof(buf));
+		if (ret == -1) {
+			perror("readlink");
+			exit(-1);
 		}
-		sum_add_sum(dircs, &cs);
-		sum_add_sum(dircs, &meta);
-next:
-		free(path);
+		sum_add(&cs, buf, ret);
+	} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
+		sum_add_u64(&cs, major(st.st_rdev));
+		sum_add_u64(&cs, minor(st.st_rdev));
 	}
+	sum_fini(&cs);
+	sum_fini(&meta);
+	if (gen_manifest || in_manifest) {
+		char *fn;
+		char *m;
+		char *c;
+
+		if (S_ISDIR(st.st_mode))
+			strcat(path, "/");
+		fn = escape(path);
+		m = sum_to_string(&meta);
+		c = sum_to_string(&cs);
+
+		if (gen_manifest)
+			fprintf(out_fp, "%s %s %s\n", fn, m, c);
+		if (in_manifest)
+			check_manifest(fn, m, c, 0);
+		free(c);
+		free(m);
+		free(fn);
+	}
+	sum_add_sum(dircs, &cs);
+	sum_add_sum(dircs, &meta);
+out:
+	free(path);
 }
 
 int
-- 
2.20.1


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

* [PATCH v2 4/7] src/fssum: Add flag -R for non-recursive mode
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
                   ` (2 preceding siblings ...)
  2020-06-21 23:16 ` [PATCH v2 3/7] src/fssum: Recursive traversal refactoring Arvind Raghavan
@ 2020-06-21 23:16 ` Arvind Raghavan
  2020-06-21 23:16 ` [PATCH v2 5/7] src/fssum: Add a flag for including file size in checksum Arvind Raghavan
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:16 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

By default, fssum walks the input directory recursively. This patch adds
a non-recursive mode which is useful because POSIX standards dictate
that fsyncing a directory only guarantees its immediate dirents are
synced.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 src/fssum.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 506ca7fe..3667ec2f 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -56,6 +56,7 @@ typedef int (*sum_file_data_t)(int fd, sum_t *dst);
 
 int gen_manifest = 0;
 int in_manifest = 0;
+int recursive = 1;
 char *checksum = NULL;
 struct excludes *excludes;
 int n_excludes = 0;
@@ -151,6 +152,7 @@ usage(void)
 	fprintf(stderr, "    -n           : reset all flags\n");
 	fprintf(stderr, "    -N           : set all flags\n");
 	fprintf(stderr, "    -x path      : exclude path when building checksum (multiple ok)\n");
+	fprintf(stderr, "    -R           : traverse dirs non-recursively (recursive is default)\n");
 	fprintf(stderr, "    -h           : this help\n\n");
 	fprintf(stderr, "The default field mask is ugoamCdtES. If the checksum/manifest is read from a\n");
 	fprintf(stderr, "file, the mask is taken from there and the values given on the command line\n");
@@ -641,7 +643,7 @@ sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
 			}
 		}
 	}
-	if (S_ISDIR(st.st_mode)) {
+	if (S_ISDIR(st.st_mode) && recursive) {
 		fd = open_one(dirfd, name);
 		if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 			sum_add_u64(&meta, errno);
@@ -734,7 +736,7 @@ main(int argc, char *argv[])
 	int plen;
 	int elen;
 	int n_flags = 0;
-	const char *allopts = "heEfuUgGoOaAmMcCdDtTsSnNw:r:vx:";
+	const char *allopts = "heEfuUgGoOaAmMcCdDtTsSnNRw:r:vx:";
 
 	out_fp = stdout;
 	while ((c = getopt(argc, argv, allopts)) != EOF) {
@@ -742,6 +744,9 @@ main(int argc, char *argv[])
 		case 'f':
 			gen_manifest = 1;
 			break;
+		case 'R':
+			recursive = 0;
+			break;
 		case 'u':
 		case 'U':
 		case 'g':
-- 
2.20.1


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

* [PATCH v2 5/7] src/fssum: Add a flag for including file size in checksum
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
                   ` (3 preceding siblings ...)
  2020-06-21 23:16 ` [PATCH v2 4/7] src/fssum: Add flag -R for non-recursive mode Arvind Raghavan
@ 2020-06-21 23:16 ` Arvind Raghavan
  2020-06-21 23:16 ` [PATCH v2 6/7] src/fssum: Allow single file input Arvind Raghavan
  2020-06-21 23:17 ` [PATCH v2 7/7] src/fssum: Fix whitespace in usage Arvind Raghavan
  6 siblings, 0 replies; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:16 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

File size is currently included by default. It is useful to ignore file
sizes when testing the fsync of a directory, as the data in children is
not guaranteed to be persisted.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 src/fssum.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 3667ec2f..26b0096c 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -76,13 +76,14 @@ enum _flags {
 	FLAG_XATTRS,
 	FLAG_OPEN_ERROR,
 	FLAG_STRUCTURE,
+	FLAG_SIZE,
 	NUM_FLAGS
 };
 
-const char flchar[] = "ugoamcdtes";
+const char flchar[] = "ugoamcdtesz";
 char line[65536];
 
-int flags[NUM_FLAGS] = {1, 1, 1, 1, 1, 0, 1, 1, 0, 0};
+int flags[NUM_FLAGS] = {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1};
 
 char *
 getln(char *buf, int size, FILE *fp)
@@ -137,7 +138,7 @@ usage(void)
 	fprintf(stderr, "    -w <file>    : send output to file\n");
 	fprintf(stderr, "    -v           : verbose mode (debugging only)\n");
 	fprintf(stderr, "    -r <file>    : read checksum or manifest from file\n");
-	fprintf(stderr, "    -[ugoamcdtes]: specify which fields to include in checksum calculation.\n");
+	fprintf(stderr, "    -[ugoamcdtesz]: specify which fields to include in checksum calculation.\n");
 	fprintf(stderr, "         u       : include uid\n");
 	fprintf(stderr, "         g       : include gid\n");
 	fprintf(stderr, "         o       : include mode\n");
@@ -148,13 +149,14 @@ usage(void)
 	fprintf(stderr, "         t       : include xattrs\n");
 	fprintf(stderr, "         e       : include open errors (aborts otherwise)\n");
 	fprintf(stderr, "         s       : include block structure (holes)\n");
-	fprintf(stderr, "    -[UGOAMCDTES]: exclude respective field from calculation\n");
+	fprintf(stderr, "         z       : include file size\n");
+	fprintf(stderr, "    -[UGOAMCDTESZ]: exclude respective field from calculation\n");
 	fprintf(stderr, "    -n           : reset all flags\n");
 	fprintf(stderr, "    -N           : set all flags\n");
 	fprintf(stderr, "    -x path      : exclude path when building checksum (multiple ok)\n");
 	fprintf(stderr, "    -R           : traverse dirs non-recursively (recursive is default)\n");
 	fprintf(stderr, "    -h           : this help\n\n");
-	fprintf(stderr, "The default field mask is ugoamCdtES. If the checksum/manifest is read from a\n");
+	fprintf(stderr, "The default field mask is ugoamCdtESz. If the checksum/manifest is read from a\n");
 	fprintf(stderr, "file, the mask is taken from there and the values given on the command line\n");
 	fprintf(stderr, "are ignored.\n");
 	exit(-1);
@@ -656,7 +658,8 @@ sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
 			close(fd);
 		}
 	} else if (S_ISREG(st.st_mode)) {
-		sum_add_u64(&meta, st.st_size);
+		if (flags[FLAG_SIZE])
+			sum_add_u64(&meta, st.st_size);
 		if (flags[FLAG_DATA]) {
 			if (verbose)
 				fprintf(stderr, "file %s\n",
@@ -736,7 +739,7 @@ main(int argc, char *argv[])
 	int plen;
 	int elen;
 	int n_flags = 0;
-	const char *allopts = "heEfuUgGoOaAmMcCdDtTsSnNRw:r:vx:";
+	const char *allopts = "heEfuUgGoOaAmMcCdDtTsSzZnNRw:r:vx:";
 
 	out_fp = stdout;
 	while ((c = getopt(argc, argv, allopts)) != EOF) {
@@ -767,6 +770,8 @@ main(int argc, char *argv[])
 		case 'E':
 		case 's':
 		case 'S':
+		case 'z':
+		case 'Z':
 			++n_flags;
 			parse_flag(c);
 			break;
-- 
2.20.1


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

* [PATCH v2 6/7] src/fssum: Allow single file input
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
                   ` (4 preceding siblings ...)
  2020-06-21 23:16 ` [PATCH v2 5/7] src/fssum: Add a flag for including file size in checksum Arvind Raghavan
@ 2020-06-21 23:16 ` Arvind Raghavan
  2020-06-22  6:56   ` Amir Goldstein
  2020-06-21 23:17 ` [PATCH v2 7/7] src/fssum: Fix whitespace in usage Arvind Raghavan
  6 siblings, 1 reply; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:16 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

Allow regular links and symlinks to be passed as input to fssum.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
---
Since v1:
	- Simplified logic by using sum_one
 src/fssum.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 26b0096c..c5c27486 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -29,6 +29,7 @@
 #include <inttypes.h>
 #include <assert.h>
 #include <endian.h>
+#include <libgen.h>
 
 #define CS_SIZE 16
 #define CHUNKS	128
@@ -600,7 +601,8 @@ sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
 			goto out;
 	}
 
-	ret = fstatat64(dirfd, name, &st, AT_SYMLINK_NOFOLLOW);
+	ret = fstatat64(dirfd, name, &st, AT_SYMLINK_NOFOLLOW |
+			AT_EMPTY_PATH);
 	if (ret) {
 		fprintf(stderr, "stat failed for %s/%s: %s\n",
 			path_prefix, path, strerror(errno));
@@ -890,8 +892,23 @@ main(int argc, char *argv[])
 	if (gen_manifest)
 		fprintf(out_fp, "Flags: %s\n", flagstring);
 
+	struct stat64 path_st;
+	if (fstat64(fd, &path_st)) {
+		perror("fstat");
+		exit(-1);
+	}
+
 	sum_init(&cs);
-	sum(fd, 1, &cs, path, "");
+
+	if (S_ISDIR(path_st.st_mode)) {
+		sum(fd, 1, &cs, path, "");
+	} else if (S_ISREG(path_st.st_mode) || S_ISLNK(path_st.st_mode)) {
+		sum_one(fd, 1, &cs, path, "", "");
+	} else {
+		fprintf(stderr, "path must be file or dir: %s", path);
+		exit(-1);
+	}
+
 	sum_fini(&cs);
 
 	close(fd);
-- 
2.20.1


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

* [PATCH v2 7/7] src/fssum: Fix whitespace in usage
  2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
                   ` (5 preceding siblings ...)
  2020-06-21 23:16 ` [PATCH v2 6/7] src/fssum: Allow single file input Arvind Raghavan
@ 2020-06-21 23:17 ` Arvind Raghavan
  6 siblings, 0 replies; 11+ messages in thread
From: Arvind Raghavan @ 2020-06-21 23:17 UTC (permalink / raw)
  To: fstests
  Cc: Amir Goldstein, Jayashree Mohan, Vijay Chidambaram, Arvind Raghavan

Aligns the usage whitespace properly.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 src/fssum.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index c5c27486..4c20162c 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -135,28 +135,28 @@ usage(void)
 {
 	fprintf(stderr, "usage: fssum <options> <path>\n");
 	fprintf(stderr, "  options:\n");
-	fprintf(stderr, "    -f           : write out a full manifest file\n");
-	fprintf(stderr, "    -w <file>    : send output to file\n");
-	fprintf(stderr, "    -v           : verbose mode (debugging only)\n");
-	fprintf(stderr, "    -r <file>    : read checksum or manifest from file\n");
+	fprintf(stderr, "    -f            : write out a full manifest file\n");
+	fprintf(stderr, "    -w <file>     : send output to file\n");
+	fprintf(stderr, "    -v            : verbose mode (debugging only)\n");
+	fprintf(stderr, "    -r <file>     : read checksum or manifest from file\n");
 	fprintf(stderr, "    -[ugoamcdtesz]: specify which fields to include in checksum calculation.\n");
-	fprintf(stderr, "         u       : include uid\n");
-	fprintf(stderr, "         g       : include gid\n");
-	fprintf(stderr, "         o       : include mode\n");
-	fprintf(stderr, "         m       : include mtime\n");
-	fprintf(stderr, "         a       : include atime\n");
-	fprintf(stderr, "         c       : include ctime\n");
-	fprintf(stderr, "         d       : include file data\n");
-	fprintf(stderr, "         t       : include xattrs\n");
-	fprintf(stderr, "         e       : include open errors (aborts otherwise)\n");
-	fprintf(stderr, "         s       : include block structure (holes)\n");
-	fprintf(stderr, "         z       : include file size\n");
+	fprintf(stderr, "         u        : include uid\n");
+	fprintf(stderr, "         g        : include gid\n");
+	fprintf(stderr, "         o        : include mode\n");
+	fprintf(stderr, "         m        : include mtime\n");
+	fprintf(stderr, "         a        : include atime\n");
+	fprintf(stderr, "         c        : include ctime\n");
+	fprintf(stderr, "         d        : include file data\n");
+	fprintf(stderr, "         t        : include xattrs\n");
+	fprintf(stderr, "         e        : include open errors (aborts otherwise)\n");
+	fprintf(stderr, "         s        : include block structure (holes)\n");
+	fprintf(stderr, "         z        : include file size\n");
 	fprintf(stderr, "    -[UGOAMCDTESZ]: exclude respective field from calculation\n");
-	fprintf(stderr, "    -n           : reset all flags\n");
-	fprintf(stderr, "    -N           : set all flags\n");
-	fprintf(stderr, "    -x path      : exclude path when building checksum (multiple ok)\n");
-	fprintf(stderr, "    -R           : traverse dirs non-recursively (recursive is default)\n");
-	fprintf(stderr, "    -h           : this help\n\n");
+	fprintf(stderr, "    -n            : reset all flags\n");
+	fprintf(stderr, "    -N            : set all flags\n");
+	fprintf(stderr, "    -x path       : exclude path when building checksum (multiple ok)\n");
+	fprintf(stderr, "    -R            : traverse dirs non-recursively (recursive is default)\n");
+	fprintf(stderr, "    -h            : this help\n\n");
 	fprintf(stderr, "The default field mask is ugoamCdtESz. If the checksum/manifest is read from a\n");
 	fprintf(stderr, "file, the mask is taken from there and the values given on the command line\n");
 	fprintf(stderr, "are ignored.\n");
-- 
2.20.1


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

* Re: [PATCH v2 2/7] src/fssum: Refactoring changes for recursive traversal
  2020-06-21 23:15 ` [PATCH v2 2/7] src/fssum: Refactoring changes for recursive traversal Arvind Raghavan
@ 2020-06-22  6:47   ` Amir Goldstein
  0 siblings, 0 replies; 11+ messages in thread
From: Amir Goldstein @ 2020-06-22  6:47 UTC (permalink / raw)
  To: Arvind Raghavan; +Cc: fstests, Jayashree Mohan, Vijay Chidambaram

On Mon, Jun 22, 2020 at 2:15 AM Arvind Raghavan
<raghavan.arvind@gmail.com> wrote:
>
> Refactoring changes needed for recursive traversal and single file
> input. Makes fstat and readlink use the 'at' alternatives, and creates a
> helper function for opening files.
>
> Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
> Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
> Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>


> ---
>  src/fssum.c | 22 ++++++++++++----------
>  1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/src/fssum.c b/src/fssum.c
> index 30f456c2..135dd60f 100644
> --- a/src/fssum.c
> +++ b/src/fssum.c
> @@ -503,6 +503,13 @@ malformed:
>                 excess_file(fn);
>  }
>
> +int open_one(int dirfd, const char *name)
> +{
> +       if (!name || !*name)
> +               return dup(dirfd);
> +       return openat(dirfd, name, 0);
> +}
> +
>  void
>  sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
>  {
> @@ -563,12 +570,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
>                                 goto next;
>                 }
>
> -               ret = fchdir(dirfd);
> -               if (ret == -1) {
> -                       perror("fchdir");
> -                       exit(-1);
> -               }
> -               ret = lstat64(namelist[i], &st);
> +               ret = fstatat64(dirfd, namelist[i], &st, AT_SYMLINK_NOFOLLOW);
>                 if (ret) {
>                         fprintf(stderr, "stat failed for %s/%s: %s\n",
>                                 path_prefix, path, strerror(errno));
> @@ -597,7 +599,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
>                         sum_add_time(&meta, st.st_ctime);
>                 if (flags[FLAG_XATTRS] &&
>                     (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
> -                       fd = openat(dirfd, namelist[i], 0);
> +                       fd = open_one(dirfd, namelist[i]);
>                         if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
>                                 sum_add_u64(&meta, errno);
>                         } else if (fd == -1) {
> @@ -618,7 +620,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
>                         }
>                 }
>                 if (S_ISDIR(st.st_mode)) {
> -                       fd = openat(dirfd, namelist[i], 0);
> +                       fd = open_one(dirfd, namelist[i]);
>                         if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
>                                 sum_add_u64(&meta, errno);
>                         } else if (fd == -1) {
> @@ -635,7 +637,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
>                                 if (verbose)
>                                         fprintf(stderr, "file %s\n",
>                                                 namelist[i]);
> -                               fd = openat(dirfd, namelist[i], 0);
> +                               fd = open_one(dirfd, namelist[i]);
>                                 if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
>                                         sum_add_u64(&meta, errno);
>                                 } else if (fd == -1) {
> @@ -659,7 +661,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
>                                 }
>                         }
>                 } else if (S_ISLNK(st.st_mode)) {
> -                       ret = readlink(namelist[i], buf, sizeof(buf));
> +                       ret = readlinkat(dirfd, namelist[i], buf, sizeof(buf));
>                         if (ret == -1) {
>                                 perror("readlink");
>                                 exit(-1);
> --
> 2.20.1
>

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

* Re: [PATCH v2 6/7] src/fssum: Allow single file input
  2020-06-21 23:16 ` [PATCH v2 6/7] src/fssum: Allow single file input Arvind Raghavan
@ 2020-06-22  6:56   ` Amir Goldstein
  0 siblings, 0 replies; 11+ messages in thread
From: Amir Goldstein @ 2020-06-22  6:56 UTC (permalink / raw)
  To: Arvind Raghavan; +Cc: fstests, Jayashree Mohan, Vijay Chidambaram

On Mon, Jun 22, 2020 at 2:16 AM Arvind Raghavan
<raghavan.arvind@gmail.com> wrote:
>
> Allow regular links and symlinks to be passed as input to fssum.
>
> Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
> Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
> Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>


> ---
> Since v1:
>         - Simplified logic by using sum_one
>  src/fssum.c | 21 +++++++++++++++++++--
>  1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/src/fssum.c b/src/fssum.c
> index 26b0096c..c5c27486 100644
> --- a/src/fssum.c
> +++ b/src/fssum.c
> @@ -29,6 +29,7 @@
>  #include <inttypes.h>
>  #include <assert.h>
>  #include <endian.h>
> +#include <libgen.h>
>

Is this needed by this patch? needed at all?
Should it have been added in a previous patch?

Thanks,
Amir.

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

* Re: [PATCH v2 3/7] src/fssum: Recursive traversal refactoring
  2020-06-21 23:16 ` [PATCH v2 3/7] src/fssum: Recursive traversal refactoring Arvind Raghavan
@ 2020-06-22  7:42   ` Amir Goldstein
  0 siblings, 0 replies; 11+ messages in thread
From: Amir Goldstein @ 2020-06-22  7:42 UTC (permalink / raw)
  To: Arvind Raghavan; +Cc: fstests, Jayashree Mohan, Vijay Chidambaram

[-- Attachment #1: Type: text/plain, Size: 567 bytes --]

On Mon, Jun 22, 2020 at 2:16 AM Arvind Raghavan
<raghavan.arvind@gmail.com> wrote:
>
> Moves some logic from the recursive directory traversal into a helper
> function to make it easier to add support for regular files. Does not
> change functionality.

It is VERY hard to see in review that this does not change functionality.
As opposed to the attached patches.

I know if we were working with modern code review tools, no need for
those cheap tricks, although using a helper name argument in the previous
patch would have helped in any review tool.

Thanks,
Amir.

[-- Attachment #2: 0001-src-fssum-Refactoring-changes-for-recursive-traversa.patch.txt --]
[-- Type: text/plain, Size: 3713 bytes --]

From 0c8692f28dacbcf5e0dae2b21774706946e54510 Mon Sep 17 00:00:00 2001
From: Arvind Raghavan <raghavan.arvind@gmail.com>
Date: Sun, 21 Jun 2020 19:15:44 -0400
Subject: [PATCH 1/2] src/fssum: Refactoring changes for recursive traversal

Refactoring changes needed for recursive traversal and single file
input. Makes fstat and readlink use the 'at' alternatives, and creates a
helper function for opening files.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
---
 src/fssum.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 30f456c2..6192f109 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -503,6 +503,13 @@ malformed:
 		excess_file(fn);
 }
 
+int open_one(int dirfd, const char *name)
+{
+	if (!name || !*name)
+		return dup(dirfd);
+	return openat(dirfd, name, 0);
+}
+
 void
 sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 {
@@ -552,23 +559,19 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 		sum_t cs;
 		sum_t meta;
 		char *path;
+		char *name = namelist[i];
 
 		sum_init(&cs);
 		sum_init(&meta);
-		path = alloc(strlen(path_in) + strlen(namelist[i]) + 3);
-		sprintf(path, "%s/%s", path_in, namelist[i]);
+		path = alloc(strlen(path_in) + strlen(name) + 3);
+		sprintf(path, "%s/%s", path_in, name);
 		for (excl = 0; excl < n_excludes; ++excl) {
 			if (strncmp(excludes[excl].path, path,
 			    excludes[excl].len) == 0)
 				goto next;
 		}
 
-		ret = fchdir(dirfd);
-		if (ret == -1) {
-			perror("fchdir");
-			exit(-1);
-		}
-		ret = lstat64(namelist[i], &st);
+		ret = fstatat64(dirfd, name, &st, AT_SYMLINK_NOFOLLOW);
 		if (ret) {
 			fprintf(stderr, "stat failed for %s/%s: %s\n",
 				path_prefix, path, strerror(errno));
@@ -580,7 +583,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			goto next;
 
 		sum_add_u64(&meta, level);
-		sum_add(&meta, namelist[i], strlen(namelist[i]));
+		sum_add(&meta, name, strlen(name));
 		if (!S_ISDIR(st.st_mode))
 			sum_add_u64(&meta, st.st_nlink);
 		if (flags[FLAG_UID])
@@ -597,7 +600,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			sum_add_time(&meta, st.st_ctime);
 		if (flags[FLAG_XATTRS] &&
 		    (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
-			fd = openat(dirfd, namelist[i], 0);
+			fd = open_one(dirfd, name);
 			if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 				sum_add_u64(&meta, errno);
 			} else if (fd == -1) {
@@ -618,7 +621,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			}
 		}
 		if (S_ISDIR(st.st_mode)) {
-			fd = openat(dirfd, namelist[i], 0);
+			fd = open_one(dirfd, name);
 			if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 				sum_add_u64(&meta, errno);
 			} else if (fd == -1) {
@@ -633,9 +636,8 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			sum_add_u64(&meta, st.st_size);
 			if (flags[FLAG_DATA]) {
 				if (verbose)
-					fprintf(stderr, "file %s\n",
-						namelist[i]);
-				fd = openat(dirfd, namelist[i], 0);
+					fprintf(stderr, "file %s\n", name);
+				fd = open_one(dirfd, name);
 				if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
 					sum_add_u64(&meta, errno);
 				} else if (fd == -1) {
@@ -659,7 +661,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 				}
 			}
 		} else if (S_ISLNK(st.st_mode)) {
-			ret = readlink(namelist[i], buf, sizeof(buf));
+			ret = readlinkat(dirfd, name, buf, sizeof(buf));
 			if (ret == -1) {
 				perror("readlink");
 				exit(-1);
-- 
2.17.1


[-- Attachment #3: 0002-src-fssum-Recursive-traversal-refactoring.patch.txt --]
[-- Type: text/plain, Size: 3097 bytes --]

From c54d1f8fe91cffe9685268ef5717e999da5a7391 Mon Sep 17 00:00:00 2001
From: Arvind Raghavan <raghavan.arvind@gmail.com>
Date: Sun, 21 Jun 2020 19:16:03 -0400
Subject: [PATCH 2/2] src/fssum: Recursive traversal refactoring

Moves some logic from the recursive directory traversal into a helper
function to make it easier to add support for regular files. Does not
change functionality.

Signed-off-by: Arvind Raghavan <raghavan.arvind@gmail.com>
Signed-off-by: Jayashree Mohan <jaya@cs.utexas.edu>
Signed-off-by: Vijay Chidambaram <vijay@cs.utexas.edu>
---
 src/fssum.c | 44 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/src/fssum.c b/src/fssum.c
index 6192f109..7bfa8c4f 100644
--- a/src/fssum.c
+++ b/src/fssum.c
@@ -510,6 +510,10 @@ int open_one(int dirfd, const char *name)
 	return openat(dirfd, name, 0);
 }
 
+void
+sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
+		char *path_in, char *name);
+
 void
 sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 {
@@ -520,8 +524,6 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 	int entries = 0;
 	int i;
 	int ret;
-	int fd;
-	int excl;
 	struct stat64 dir_st;
 
 	if (fstat64(dirfd, &dir_st)) {
@@ -556,10 +558,36 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 	qsort(namelist, entries, sizeof(*namelist), namecmp);
 	for (i = 0; i < entries; ++i) {
 		struct stat64 st;
+
+		ret = fstatat64(dirfd, namelist[i], &st, AT_SYMLINK_NOFOLLOW);
+		if (ret) {
+			fprintf(stderr, "stat failed for %s/%s/%s: %s\n",
+				path_prefix, path_in, namelist[i],
+				strerror(errno));
+			exit(-1);
+		}
+
+		/* We are crossing into a different subvol, skip this subtree. */
+		if (st.st_dev != dir_st.st_dev)
+			continue;
+
+		sum_one(dirfd, level, dircs, path_prefix, path_in, namelist[i]);
+	}
+}
+
+void
+sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
+		char *path_in, char *name)
+{
+	/* TEMPORARY NESTING WILL BE REMOVED SOON */
+	{
 		sum_t cs;
 		sum_t meta;
-		char *path;
-		char *name = namelist[i];
+		int fd;
+		int ret;
+		int excl;
+		char* path;
+		struct stat64 st;
 
 		sum_init(&cs);
 		sum_init(&meta);
@@ -568,7 +596,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 		for (excl = 0; excl < n_excludes; ++excl) {
 			if (strncmp(excludes[excl].path, path,
 			    excludes[excl].len) == 0)
-				goto next;
+				goto out;
 		}
 
 		ret = fstatat64(dirfd, name, &st, AT_SYMLINK_NOFOLLOW);
@@ -578,10 +606,6 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 			exit(-1);
 		}
 
-		/* We are crossing into a different subvol, skip this subtree. */
-		if (st.st_dev != dir_st.st_dev)
-			goto next;
-
 		sum_add_u64(&meta, level);
 		sum_add(&meta, name, strlen(name));
 		if (!S_ISDIR(st.st_mode))
@@ -694,7 +718,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
 		}
 		sum_add_sum(dircs, &cs);
 		sum_add_sum(dircs, &meta);
-next:
+out:
 		free(path);
 	}
 }
-- 
2.17.1


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

end of thread, other threads:[~2020-06-22  7:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-21 23:14 [PATCH v2 0/7] Change fssum to support POSIX Arvind Raghavan
2020-06-21 23:15 ` [PATCH v2 1/7] src/fssum: Make sum_file_data global Arvind Raghavan
2020-06-21 23:15 ` [PATCH v2 2/7] src/fssum: Refactoring changes for recursive traversal Arvind Raghavan
2020-06-22  6:47   ` Amir Goldstein
2020-06-21 23:16 ` [PATCH v2 3/7] src/fssum: Recursive traversal refactoring Arvind Raghavan
2020-06-22  7:42   ` Amir Goldstein
2020-06-21 23:16 ` [PATCH v2 4/7] src/fssum: Add flag -R for non-recursive mode Arvind Raghavan
2020-06-21 23:16 ` [PATCH v2 5/7] src/fssum: Add a flag for including file size in checksum Arvind Raghavan
2020-06-21 23:16 ` [PATCH v2 6/7] src/fssum: Allow single file input Arvind Raghavan
2020-06-22  6:56   ` Amir Goldstein
2020-06-21 23:17 ` [PATCH v2 7/7] src/fssum: Fix whitespace in usage Arvind Raghavan

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.