]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_io: make ls/chattr work with special files
authorAndrey Albershteyn <aalbersh@redhat.com>
Tue, 9 Sep 2025 15:24:38 +0000 (17:24 +0200)
committerAndrey Albershteyn <aalbersh@kernel.org>
Mon, 15 Sep 2025 09:10:05 +0000 (11:10 +0200)
With new file_getattr/file_setattr syscalls we can now list/change file
attributes on special files instead for ignoring them.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
io/attr.c
io/io.h
io/stat.c

index fd82a2e73801809e222bbca17c11eae0cd1d2941..022ca5f1df1b7c8bbc54517f69a5d9812e74e896 100644 (file)
--- a/io/attr.c
+++ b/io/attr.c
@@ -8,6 +8,7 @@
 #include "input.h"
 #include "init.h"
 #include "io.h"
+#include "libfrog/file_attr.h"
 
 static cmdinfo_t chattr_cmd;
 static cmdinfo_t lsattr_cmd;
@@ -113,7 +114,7 @@ chattr_help(void)
 }
 
 void
-printxattr(
+print_xflags(
        uint            flags,
        int             verbose,
        int             dofname,
@@ -156,36 +157,36 @@ lsattr_callback(
        int                     status,
        struct FTW              *data)
 {
-       struct fsxattr          fsx;
-       int                     fd;
+       struct file_attr        fa;
+       int                     error;
 
        if (recurse_dir && !S_ISDIR(stat->st_mode))
                return 0;
 
-       if ((fd = open(path, O_RDONLY)) == -1) {
-               fprintf(stderr, _("%s: cannot open %s: %s\n"),
-                       progname, path, strerror(errno));
-               exitcode = 1;
-       } else if ((xfsctl(path, fd, FS_IOC_FSGETXATTR, &fsx)) < 0) {
+       error = xfrog_file_getattr(AT_FDCWD, path, stat, &fa,
+                                  AT_SYMLINK_NOFOLLOW);
+       if (error) {
                fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
                        progname, path, strerror(errno));
                exitcode = 1;
-       } else
-               printxattr(fsx.fsx_xflags, 0, 1, path, 0, 1);
+               return 0;
+       }
+
+       print_xflags(fa.fa_xflags, 0, 1, path, 0, 1);
 
-       if (fd != -1)
-               close(fd);
        return 0;
 }
 
 static int
 lsattr_f(
-       int             argc,
-       char            **argv)
+       int                     argc,
+       char                    **argv)
 {
-       struct fsxattr  fsx;
-       char            *name = file->name;
-       int             c, aflag = 0, vflag = 0;
+       struct file_attr        fa;
+       char                    *name = file->name;
+       int                     c, aflag = 0, vflag = 0;
+       struct stat             st;
+       int                     error;
 
        recurse_all = recurse_dir = 0;
        while ((c = getopt(argc, argv, "DRav")) != EOF) {
@@ -211,17 +212,28 @@ lsattr_f(
        if (recurse_all || recurse_dir) {
                nftw(name, lsattr_callback,
                        100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
-       } else if ((xfsctl(name, file->fd, FS_IOC_FSGETXATTR, &fsx)) < 0) {
+               return 0;
+       }
+
+       error = stat(name, &st);
+       if (error)
+               return error;
+
+       error = xfrog_file_getattr(AT_FDCWD, name, &st, &fa,
+                                  AT_SYMLINK_NOFOLLOW);
+       if (error) {
                fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
                        progname, name, strerror(errno));
                exitcode = 1;
-       } else {
-               printxattr(fsx.fsx_xflags, vflag, !aflag, name, vflag, !aflag);
-               if (aflag) {
-                       fputs("/", stdout);
-                       printxattr(-1, 0, 1, name, 0, 1);
-               }
+               return 0;
+       }
+
+       print_xflags(fa.fa_xflags, vflag, !aflag, name, vflag, !aflag);
+       if (aflag) {
+               fputs("/", stdout);
+               print_xflags(-1, 0, 1, name, 0, 1);
        }
+
        return 0;
 }
 
@@ -232,44 +244,45 @@ chattr_callback(
        int                     status,
        struct FTW              *data)
 {
-       struct fsxattr          attr;
-       int                     fd;
+       struct file_attr        attr;
+       int                     error;
 
        if (recurse_dir && !S_ISDIR(stat->st_mode))
                return 0;
 
-       if ((fd = open(path, O_RDONLY)) == -1) {
-               fprintf(stderr, _("%s: cannot open %s: %s\n"),
+       error = xfrog_file_getattr(AT_FDCWD, path, stat, &attr,
+                                  AT_SYMLINK_NOFOLLOW);
+       if (error) {
+               fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
                        progname, path, strerror(errno));
                exitcode = 1;
-       } else if (xfsctl(path, fd, FS_IOC_FSGETXATTR, &attr) < 0) {
-               fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
+               return 0;
+       }
+
+       attr.fa_xflags |= orflags;
+       attr.fa_xflags &= ~andflags;
+       error = xfrog_file_setattr(AT_FDCWD, path, stat, &attr,
+                                  AT_SYMLINK_NOFOLLOW);
+       if (error) {
+               fprintf(stderr, _("%s: cannot set flags on %s: %s\n"),
                        progname, path, strerror(errno));
                exitcode = 1;
-       } else {
-               attr.fsx_xflags |= orflags;
-               attr.fsx_xflags &= ~andflags;
-               if (xfsctl(path, fd, FS_IOC_FSSETXATTR, &attr) < 0) {
-                       fprintf(stderr, _("%s: cannot set flags on %s: %s\n"),
-                               progname, path, strerror(errno));
-                       exitcode = 1;
-               }
        }
 
-       if (fd != -1)
-               close(fd);
        return 0;
 }
 
 static int
 chattr_f(
-       int             argc,
-       char            **argv)
+       int                     argc,
+       char                    **argv)
 {
-       struct fsxattr  attr;
-       struct xflags   *p;
-       unsigned int    i = 0;
-       char            *c, *name = file->name;
+       struct file_attr        attr;
+       struct xflags           *p;
+       unsigned int            i = 0;
+       char                    *c, *name = file->name;
+       struct stat             st;
+       int                     error;
 
        orflags = andflags = 0;
        recurse_all = recurse_dir = 0;
@@ -326,19 +339,32 @@ chattr_f(
        if (recurse_all || recurse_dir) {
                nftw(name, chattr_callback,
                        100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
-       } else if (xfsctl(name, file->fd, FS_IOC_FSGETXATTR, &attr) < 0) {
+               return 0;
+       }
+
+       error = stat(name, &st);
+       if (error)
+               return error;
+
+       error = xfrog_file_getattr(AT_FDCWD, name, &st, &attr,
+                                  AT_SYMLINK_NOFOLLOW);
+       if (error) {
                fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
                        progname, name, strerror(errno));
                exitcode = 1;
-       } else {
-               attr.fsx_xflags |= orflags;
-               attr.fsx_xflags &= ~andflags;
-               if (xfsctl(name, file->fd, FS_IOC_FSSETXATTR, &attr) < 0) {
-                       fprintf(stderr, _("%s: cannot set flags on %s: %s\n"),
-                               progname, name, strerror(errno));
-                       exitcode = 1;
-               }
+               return 0;
+       }
+
+       attr.fa_xflags |= orflags;
+       attr.fa_xflags &= ~andflags;
+       error = xfrog_file_setattr(AT_FDCWD, name, &st, &attr,
+                                  AT_SYMLINK_NOFOLLOW);
+       if (error) {
+               fprintf(stderr, _("%s: cannot set flags on %s: %s\n"),
+                       progname, name, strerror(errno));
+               exitcode = 1;
        }
+
        return 0;
 }
 
diff --git a/io/io.h b/io/io.h
index 259c034931b8d3fa3e692e4357e86f59462669b7..35fb8339eeb5aa3a3ea487a50895373fdaba6872 100644 (file)
--- a/io/io.h
+++ b/io/io.h
@@ -78,7 +78,7 @@ extern int            openfile(char *, struct xfs_fsop_geom *, int, mode_t,
 extern int             addfile(char *, int , struct xfs_fsop_geom *, int,
                                struct fs_path *);
 extern int             closefile(void);
-extern void            printxattr(uint, int, int, const char *, int, int);
+extern void            print_xflags(uint, int, int, const char *, int, int);
 
 extern unsigned int    recurse_all;
 extern unsigned int    recurse_dir;
index c257037aa8eec3f2f658ee8e8d7a10fee148b821..c1085f14eade93ff76b4694bb000a8ea11d5f92c 100644 (file)
--- a/io/stat.c
+++ b/io/stat.c
@@ -112,7 +112,7 @@ print_extended_info(int verbose)
        }
 
        printf(_("fsxattr.xflags = 0x%x "), fsx.fsx_xflags);
-       printxattr(fsx.fsx_xflags, verbose, 0, file->name, 1, 1);
+       print_xflags(fsx.fsx_xflags, verbose, 0, file->name, 1, 1);
        printf(_("fsxattr.projid = %u\n"), fsx.fsx_projid);
        printf(_("fsxattr.extsize = %u\n"), fsx.fsx_extsize);
        printf(_("fsxattr.cowextsize = %u\n"), fsx.fsx_cowextsize);