]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: remove moveon from vfs directory tree iteration
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 6 Nov 2019 22:28:37 +0000 (17:28 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 6 Nov 2019 22:28:37 +0000 (17:28 -0500)
Replace the moveon returns in the vfs directory tree walking functions
with a direct integer error return.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
scrub/phase6.c
scrub/vfs.c
scrub/vfs.h

index 9348f8e4677bcdd9965a22c12e81e8c1578ca5ad..a0a71ce3bb3ed762d2ebb4444382e5af2b0eeeec 100644 (file)
@@ -309,21 +309,24 @@ _("Disappeared during read error reporting."));
 }
 
 /* Scan a directory for matches in the read verify error list. */
-static bool
+static int
 xfs_report_verify_dir(
        struct scrub_ctx        *ctx,
        const char              *path,
        int                     dir_fd,
        void                    *arg)
 {
-       return xfs_report_verify_fd(ctx, path, dir_fd, arg);
+       bool                    moveon;
+
+       moveon = xfs_report_verify_fd(ctx, path, dir_fd, arg);
+       return moveon ? 0 : -1;
 }
 
 /*
  * Scan the inode associated with a directory entry for matches with
  * the read verify error list.
  */
-static bool
+static int
 xfs_report_verify_dirent(
        struct scrub_ctx        *ctx,
        const char              *path,
@@ -338,11 +341,11 @@ xfs_report_verify_dirent(
 
        /* Ignore things we can't open. */
        if (!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode))
-               return true;
+               return 0;
 
        /* Ignore . and .. */
        if (!strcmp(".", dirent->d_name) || !strcmp("..", dirent->d_name))
-               return true;
+               return 0;
 
        /*
         * If we were given a dirent, open the associated file under
@@ -351,8 +354,12 @@ xfs_report_verify_dirent(
         */
        fd = openat(dir_fd, dirent->d_name,
                        O_RDONLY | O_NOATIME | O_NOFOLLOW | O_NOCTTY);
-       if (fd < 0)
-               return true;
+       if (fd < 0) {
+               if (errno == ENOENT)
+                       return 0;
+               str_errno(ctx, path);
+               return errno;
+       }
 
        /* Go find the badness. */
        moveon = xfs_report_verify_fd(ctx, path, fd, arg);
@@ -363,7 +370,7 @@ out:
        error = close(fd);
        if (error)
                str_errno(ctx, path);
-       return moveon;
+       return moveon ? 0 : -1;
 }
 
 /* Use a fsmap to report metadata lost to a media error. */
@@ -478,7 +485,6 @@ report_all_media_errors(
        struct scrub_ctx                *ctx,
        struct media_verify_state       *vs)
 {
-       bool                            moveon;
        int                             ret;
 
        ret = report_disk_ioerrs(ctx, ctx->datadev, vs);
@@ -494,9 +500,9 @@ report_all_media_errors(
        }
 
        /* Scan the directory tree to get file paths. */
-       moveon = scan_fs_tree(ctx, xfs_report_verify_dir,
+       ret = scan_fs_tree(ctx, xfs_report_verify_dir,
                        xfs_report_verify_dirent, vs);
-       if (!moveon)
+       if (ret)
                return false;
 
        /* Scan for unlinked files. */
index d7c40239b677d06a222c8096a67bf14c80c5e7e9..c807c9b921024b9f8c29d6fab4e06d269fa7f579 100644 (file)
@@ -30,7 +30,7 @@ struct scan_fs_tree {
        pthread_mutex_t         lock;
        pthread_cond_t          wakeup;
        struct stat             root_sb;
-       bool                    moveon;
+       bool                    aborted;
        scan_fs_tree_dir_fn     dir_fn;
        scan_fs_tree_dirent_fn  dirent_fn;
        void                    *arg;
@@ -138,8 +138,9 @@ scan_fs_dir(
        }
 
        /* Caller-specific directory checks. */
-       if (!sft->dir_fn(ctx, sftd->path, dir_fd, sft->arg)) {
-               sft->moveon = false;
+       error = sft->dir_fn(ctx, sftd->path, dir_fd, sft->arg);
+       if (error) {
+               sft->aborted = true;
                error = close(dir_fd);
                if (error)
                        str_errno(ctx, sftd->path);
@@ -150,11 +151,14 @@ scan_fs_dir(
        dir = fdopendir(dir_fd);
        if (!dir) {
                str_errno(ctx, sftd->path);
+               sft->aborted = true;
                close(dir_fd);
                goto out;
        }
        rewinddir(dir);
-       for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) {
+       for (dirent = readdir(dir);
+            !sft->aborted && dirent != NULL;
+            dirent = readdir(dir)) {
                snprintf(newpath, PATH_MAX, "%s/%s", sftd->path,
                                dirent->d_name);
 
@@ -171,14 +175,15 @@ scan_fs_dir(
                        continue;
 
                /* Caller-specific directory entry function. */
-               if (!sft->dirent_fn(ctx, newpath, dir_fd, dirent, &sb,
-                               sft->arg)) {
-                       sft->moveon = false;
+               error = sft->dirent_fn(ctx, newpath, dir_fd, dirent, &sb,
+                               sft->arg);
+               if (error) {
+                       sft->aborted = true;
                        break;
                }
 
                if (xfs_scrub_excessive_errors(ctx)) {
-                       sft->moveon = false;
+                       sft->aborted = true;
                        break;
                }
 
@@ -189,7 +194,7 @@ scan_fs_dir(
                        if (error) {
                                str_liberror(ctx, error,
 _("queueing subdirectory scan"));
-                               sft->moveon = false;
+                               sft->aborted = true;
                                break;
                        }
                }
@@ -206,8 +211,11 @@ out:
        free(sftd);
 }
 
-/* Scan the entire filesystem. */
-bool
+/*
+ * Scan the entire filesystem.  This function returns 0 on success; if there
+ * are errors, this function will log them and returns nonzero.
+ */
+int
 scan_fs_tree(
        struct scrub_ctx        *ctx,
        scan_fs_tree_dir_fn     dir_fn,
@@ -215,20 +223,18 @@ scan_fs_tree(
        void                    *arg)
 {
        struct workqueue        wq;
-       struct scan_fs_tree     sft;
-       bool                    moveon = false;
+       struct scan_fs_tree     sft = {
+               .root_sb        = ctx->mnt_sb,
+               .dir_fn         = dir_fn,
+               .dirent_fn      = dirent_fn,
+               .arg            = arg,
+       };
        int                     ret;
 
-       sft.moveon = true;
-       sft.nr_dirs = 0;
-       sft.root_sb = ctx->mnt_sb;
-       sft.dir_fn = dir_fn;
-       sft.dirent_fn = dirent_fn;
-       sft.arg = arg;
        ret = pthread_mutex_init(&sft.lock, NULL);
        if (ret) {
                str_liberror(ctx, ret, _("creating directory scan lock"));
-               return false;
+               return ret;
        }
        ret = pthread_cond_init(&sft.wakeup, NULL);
        if (ret) {
@@ -268,14 +274,16 @@ scan_fs_tree(
                goto out_wq;
        }
 
-       moveon = sft.moveon;
+       if (!ret && sft.aborted)
+               ret = -1;
+
 out_wq:
        workqueue_destroy(&wq);
 out_cond:
        pthread_cond_destroy(&sft.wakeup);
 out_mutex:
        pthread_mutex_destroy(&sft.lock);
-       return moveon;
+       return ret;
 }
 
 #ifndef FITRIM
index af23674a7ff403fbb46ec0b04f9ef5ec9f004070..dc1099cf18db5fd3b4833deb1197367f2288afda 100644 (file)
@@ -8,20 +8,20 @@
 
 /*
  * Visit a subdirectory prior to iterating entries in that subdirectory.
- * Return true to continue iteration or false to stop iterating and return to
- * the caller.
+ * Return 0 to continue iteration or a positive error code to stop iterating
+ * and return to the caller.
  */
-typedef bool (*scan_fs_tree_dir_fn)(struct scrub_ctx *, const char *,
+typedef int (*scan_fs_tree_dir_fn)(struct scrub_ctx *, const char *,
                int, void *);
 
 /*
- * Visit each directory entry in a directory.  Return true to continue
- * iteration or false to stop iterating and return to the caller.
+ * Visit each directory entry in a directory.  Return 0 to continue iteration
+ * or a positive error code to stop iterating and return to the caller.
  */
-typedef bool (*scan_fs_tree_dirent_fn)(struct scrub_ctx *, const char *,
+typedef int (*scan_fs_tree_dirent_fn)(struct scrub_ctx *, const char *,
                int, struct dirent *, struct stat *, void *);
 
-bool scan_fs_tree(struct scrub_ctx *ctx, scan_fs_tree_dir_fn dir_fn,
+int scan_fs_tree(struct scrub_ctx *ctx, scan_fs_tree_dir_fn dir_fn,
                scan_fs_tree_dirent_fn dirent_fn, void *arg);
 
 void fstrim(struct scrub_ctx *ctx);