]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
tree-wide: ensure that file information is set even with legacy fuse
authorChristian Brauner (Microsoft) <christian.brauner@ubuntu.com>
Sat, 12 Mar 2022 10:38:06 +0000 (11:38 +0100)
committerChristian Brauner (Microsoft) <christian.brauner@ubuntu.com>
Sat, 12 Mar 2022 10:41:30 +0000 (11:41 +0100)
Fixes: #522
Signed-off-by: Christian Brauner (Microsoft) <christian.brauner@ubuntu.com>
src/lxcfs_fuse_compat.h
src/sysfs_fuse.c

index 4562b156edc4e0986d8e347043fea36daaa27624..d12ecef35239e6ecafb0f498fcc4a7811e76bace 100644 (file)
@@ -5,18 +5,66 @@
 
 #include "config.h"
 
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "memory_utils.h"
+
 #if HAVE_FUSE3
 static inline int dir_filler(fuse_fill_dir_t filler, void *buf,
                             const char *name, off_t off)
 {
        return filler(buf, name, NULL, off, FUSE_FILL_DIR_PLUS);
 }
+
+static inline int dirent_filler(fuse_fill_dir_t filler, const char *path,
+                               const char *name, void *buf, off_t off)
+{
+       return filler(buf, name, NULL, off, FUSE_FILL_DIR_PLUS);
+}
+
+static inline int dirent_fillerat(fuse_fill_dir_t filler, DIR *dp,
+                                 struct dirent *dentry, void *buf, off_t off)
+{
+       return filler(buf, dentry->d_name, NULL, off, FUSE_FILL_DIR_PLUS);
+}
 #else
 static inline int dir_filler(fuse_fill_dir_t filler, void *buf,
                             const char *name, off_t off)
 {
        return filler(buf, name, NULL, off);
 }
+
+static inline int dirent_filler(fuse_fill_dir_t filler, const char *path,
+                               const char *name, void *buf, off_t off)
+{
+       __do_closedir DIR *dirp = NULL;
+       struct stat st;
+
+       dirp = opendir(path);
+       if (dirp && !fstatat(dirfd(dirp), name, &st, AT_SYMLINK_NOFOLLOW))
+               return filler(buf, name, &st, off);
+
+       return filler(buf, name, NULL, off);
+}
+
+static inline int dirent_fillerat(fuse_fill_dir_t filler, DIR *dp,
+                                 struct dirent *dentry, void *buf, off_t off)
+{
+       struct stat st;
+       int ret;
+
+       ret = fstatat(dirfd(dp), dentry->d_name, &st, AT_SYMLINK_NOFOLLOW);
+       if (ret) {
+               st = (struct stat){
+                       .st_ino  = dentry->d_ino,
+                       .st_mode = dentry->d_type << 12,
+               };
+       }
+
+       return filler(buf, dentry->d_name, &st, off);
+}
 #endif
 
 #endif /* __LXCFS_FUSE_COMPAT_H */
index ea7b8967a4080c2277d8baaf0b32e82ab1325fca..17b93c1118e0b6d0ce76a8d273eaf2dedc533b2a 100644 (file)
@@ -322,7 +322,7 @@ static int filler_sys_devices_system_cpu(const char *path, void *buf,
                if (isdigit(*entry))
                        continue;
 
-               if (dir_filler(filler, buf, dirent->d_name, 0) != 0)
+               if (dirent_fillerat(filler, dir, dirent, buf, 0) != 0)
                        return -ENOENT;
        }
 
@@ -479,7 +479,7 @@ static int sys_readdir_legacy(const char *path, void *buf, fuse_fill_dir_t fille
        if (strcmp(path, "/sys") == 0) {
                if (dir_filler(filler, buf, ".",        0) != 0 ||
                    dir_filler(filler, buf, "..",       0) != 0 ||
-                   dir_filler(filler, buf, "devices",  0) != 0)
+                   dirent_filler(filler, path, "devices", buf,  0) != 0)
                        return -ENOENT;
 
                return 0;
@@ -487,7 +487,7 @@ static int sys_readdir_legacy(const char *path, void *buf, fuse_fill_dir_t fille
        if (strcmp(path, "/sys/devices") == 0) {
                if (dir_filler(filler, buf, ".",        0) != 0 ||
                    dir_filler(filler, buf, "..",       0) != 0 ||
-                   dir_filler(filler, buf, "system",   0) != 0)
+                   dirent_filler(filler, path, "system", buf,  0) != 0)
                        return -ENOENT;
 
                return 0;
@@ -495,7 +495,7 @@ static int sys_readdir_legacy(const char *path, void *buf, fuse_fill_dir_t fille
        if (strcmp(path, "/sys/devices/system") == 0) {
                if (dir_filler(filler, buf, ".",        0) != 0 ||
                    dir_filler(filler, buf, "..",       0) != 0 ||
-                   dir_filler(filler, buf, "cpu",      0) != 0)
+                   dirent_filler(filler, path, "cpu", buf,  0) != 0)
                        return -ENOENT;
 
                return 0;
@@ -503,7 +503,7 @@ static int sys_readdir_legacy(const char *path, void *buf, fuse_fill_dir_t fille
        if (strcmp(path, "/sys/devices/system/cpu") == 0) {
                if (dir_filler(filler, buf, ".",        0) != 0 ||
                    dir_filler(filler, buf, "..",       0) != 0 ||
-                   dir_filler(filler, buf, "online",   0) != 0)
+                   dirent_filler(filler, path, "online", buf,  0) != 0)
                        return -ENOENT;
 
                return 0;
@@ -539,7 +539,7 @@ __lxcfs_fuse_ops int sys_readdir(const char *path, void *buf,
        case LXC_TYPE_SYS: {
                        if (dir_filler(filler, buf, ".",        0) != 0 ||
                            dir_filler(filler, buf, "..",       0) != 0 ||
-                           dir_filler(filler, buf, "devices",  0) != 0)
+                           dirent_filler(filler, path, "devices", buf,  0) != 0)
                                        return -ENOENT;
 
                        return 0;
@@ -547,7 +547,7 @@ __lxcfs_fuse_ops int sys_readdir(const char *path, void *buf,
        case LXC_TYPE_SYS_DEVICES: {
                        if (dir_filler(filler, buf, ".",        0) != 0 ||
                            dir_filler(filler, buf, "..",       0) != 0 ||
-                           dir_filler(filler, buf, "system",   0) != 0)
+                           dirent_filler(filler, path, "system", buf,  0) != 0)
                                        return -ENOENT;
 
                        return 0;
@@ -555,7 +555,7 @@ __lxcfs_fuse_ops int sys_readdir(const char *path, void *buf,
        case LXC_TYPE_SYS_DEVICES_SYSTEM: {
                        if (dir_filler(filler, buf, ".",    0) != 0 ||
                            dir_filler(filler, buf, "..",   0) != 0 ||
-                           dir_filler(filler, buf, "cpu",  0) != 0)
+                           dirent_filler(filler, path, "cpu", buf,  0) != 0)
                                        return -ENOENT;
 
                        return 0;
@@ -572,7 +572,7 @@ __lxcfs_fuse_ops int sys_readdir(const char *path, void *buf,
                                return -ENOENT;
 
                        while ((dirent = readdir(dir))) {
-                               if (dir_filler(filler, buf, dirent->d_name, 0) != 0)
+                               if (dirent_fillerat(filler, dir, dirent, buf, 0) != 0)
                                        return -ENOENT;
                        }