^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Licensed under the GPL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Ported the filesystem routines to 2.5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * 2003-02-10 Petr Baudis <pasky@ucw.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/statfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "hostfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <kern.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct hostfs_inode_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) fmode_t mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct inode vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct mutex open_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return list_entry(inode, struct hostfs_inode_info, vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define FILE_HOSTFS_I(file) HOSTFS_I(file_inode(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Changed in hostfs_args before the kernel starts running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static char *root_ino = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int append = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static const struct inode_operations hostfs_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const struct inode_operations hostfs_dir_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static const struct inode_operations hostfs_link_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int __init hostfs_args(char *options, int *add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ptr = strchr(options, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (ptr != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *ptr++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (*options != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) root_ino = options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) options = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) while (options) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ptr = strchr(options, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ptr != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *ptr++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (*options != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (!strcmp(options, "append"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) append = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) else printf("hostfs_args - unsupported option - %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) options = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) __uml_setup("hostfs=", hostfs_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "hostfs=<root dir>,<flags>,...\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) " This is used to set hostfs parameters. The root directory argument\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) " is used to confine all hostfs mounts to within the specified directory\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) " tree on the host. If this isn't specified, then a user inside UML can\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) " mount anything on the host that's accessible to the user that's running\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) " it.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) " The only flag currently supported is 'append', which specifies that all\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) " files opened by hostfs will be opened in append mode.\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static char *__dentry_name(struct dentry *dentry, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) char *p = dentry_path_raw(dentry, name, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) char *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) root = dentry->d_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) len = strlen(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (IS_ERR(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * This function relies on the fact that dentry_path_raw() will place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * the path name at the end of the provided buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) BUG_ON(p + strlen(p) + 1 != name + PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) strlcpy(name, root, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (len > p - name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (p > name + len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) strcpy(name + len, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static char *dentry_name(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) char *name = __getname();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return __dentry_name(dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static char *inode_name(struct inode *ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dentry = d_find_alias(ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) name = dentry_name(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static char *follow_link(char *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) char *name, *resolved, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) name = kmalloc(PATH_MAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) n = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) n = hostfs_do_readlink(link, name, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) else if (n == PATH_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) n = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (*name == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) end = strrchr(link, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (end == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *(end + 1) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) resolved = kasprintf(GFP_KERNEL, "%s%s", link, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (resolved == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) n = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return resolved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ERR_PTR(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static struct inode *hostfs_iget(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct inode *inode = new_inode(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * do_statfs uses struct statfs64 internally, but the linux kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * struct statfs still has 32-bit versions for most of these fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * so we convert them here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) long long f_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) long long f_bfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) long long f_bavail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) long long f_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) long long f_ffree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) err = do_statfs(dentry->d_sb->s_fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) &sf->f_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) sf->f_blocks = f_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) sf->f_bfree = f_bfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) sf->f_bavail = f_bavail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) sf->f_files = f_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) sf->f_ffree = f_ffree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) sf->f_type = HOSTFS_SUPER_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static struct inode *hostfs_alloc_inode(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct hostfs_inode_info *hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) hi = kmalloc(sizeof(*hi), GFP_KERNEL_ACCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (hi == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) hi->fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) hi->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) inode_init_once(&hi->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mutex_init(&hi->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return &hi->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void hostfs_evict_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) truncate_inode_pages_final(&inode->i_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) clear_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (HOSTFS_I(inode)->fd != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) close_file(&HOSTFS_I(inode)->fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) HOSTFS_I(inode)->fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void hostfs_free_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) kfree(HOSTFS_I(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) const char *root_path = root->d_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) size_t offset = strlen(root_ino) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (strlen(root_path) > offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) seq_show_option(seq, root_path + offset, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (append)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) seq_puts(seq, ",append");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static const struct super_operations hostfs_sbops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .alloc_inode = hostfs_alloc_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .free_inode = hostfs_free_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .evict_inode = hostfs_evict_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .statfs = hostfs_statfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .show_options = hostfs_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int hostfs_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) void *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) unsigned long long next, ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int error, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) name = dentry_name(file->f_path.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) dir = open_dir(name, &error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (dir == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return -error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) next = ctx->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) seek_dir(dir, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!dir_emit(ctx, name, len, ino, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ctx->pos = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) close_dir(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int hostfs_open(struct inode *ino, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fmode_t mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int r, w, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if ((mode & HOSTFS_I(ino)->mode) == mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) mode |= HOSTFS_I(ino)->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) r = w = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (mode & FMODE_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) r = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (mode & FMODE_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) r = w = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) name = dentry_name(file->f_path.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) fd = open_file(name, r, w, append);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mutex_lock(&HOSTFS_I(ino)->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* somebody else had handled it first? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if ((mode & HOSTFS_I(ino)->mode) == mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mutex_unlock(&HOSTFS_I(ino)->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) close_file(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if ((mode | HOSTFS_I(ino)->mode) != mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mode |= HOSTFS_I(ino)->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) mutex_unlock(&HOSTFS_I(ino)->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) close_file(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (HOSTFS_I(ino)->fd == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) HOSTFS_I(ino)->fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) err = replace_file(fd, HOSTFS_I(ino)->fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) close_file(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mutex_unlock(&HOSTFS_I(ino)->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) HOSTFS_I(ino)->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mutex_unlock(&HOSTFS_I(ino)->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int hostfs_file_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) filemap_write_and_wait(inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct inode *inode = file->f_mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = file_write_and_wait_range(file, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static const struct file_operations hostfs_file_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .splice_read = generic_file_splice_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .read_iter = generic_file_read_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .write_iter = generic_file_write_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .mmap = generic_file_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .open = hostfs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .release = hostfs_file_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .fsync = hostfs_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static const struct file_operations hostfs_dir_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .iterate_shared = hostfs_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .read = generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .open = hostfs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .fsync = hostfs_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct address_space *mapping = page->mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct inode *inode = mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) loff_t base = page_offset(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int count = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int end_index = inode->i_size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (page->index >= end_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) count = inode->i_size & (PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) buffer = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (err != count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ClearPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (base > inode->i_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) inode->i_size = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (PageError(page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ClearPageError(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int hostfs_readpage(struct file *file, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) loff_t start = page_offset(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int bytes_read, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) buffer = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (bytes_read < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ClearPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) SetPageError(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ret = bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) memset(buffer + bytes_read, 0, PAGE_SIZE - bytes_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ClearPageError(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static int hostfs_write_begin(struct file *file, struct address_space *mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) loff_t pos, unsigned len, unsigned flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct page **pagep, void **fsdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) pgoff_t index = pos >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) *pagep = grab_cache_page_write_begin(mapping, index, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!*pagep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int hostfs_write_end(struct file *file, struct address_space *mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) loff_t pos, unsigned len, unsigned copied,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct page *page, void *fsdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct inode *inode = mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) void *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned from = pos & (PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) buffer = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (!PageUptodate(page) && err == PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * If err > 0, write_file has added err to pos, so we are comparing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * i_size against the last byte written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (err > 0 && (pos > inode->i_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) inode->i_size = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static const struct address_space_operations hostfs_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .writepage = hostfs_writepage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .readpage = hostfs_readpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .set_page_dirty = __set_page_dirty_nobuffers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .write_begin = hostfs_write_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .write_end = hostfs_write_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static int read_name(struct inode *ino, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dev_t rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct hostfs_stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int err = stat_file(name, &st, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* Reencode maj and min with the kernel encoding.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) rdev = MKDEV(st.maj, st.min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) switch (st.mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ino->i_op = &hostfs_link_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) case S_IFDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ino->i_op = &hostfs_dir_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ino->i_fop = &hostfs_dir_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) case S_IFCHR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case S_IFBLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case S_IFIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) case S_IFSOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) init_special_inode(ino, st.mode & S_IFMT, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ino->i_op = &hostfs_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ino->i_op = &hostfs_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ino->i_fop = &hostfs_file_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ino->i_mapping->a_ops = &hostfs_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ino->i_ino = st.ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ino->i_mode = st.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) set_nlink(ino, st.nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) i_uid_write(ino, st.uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) i_gid_write(ino, st.gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ino->i_atime = (struct timespec64){ st.atime.tv_sec, st.atime.tv_nsec };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ino->i_mtime = (struct timespec64){ st.mtime.tv_sec, st.mtime.tv_nsec };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ino->i_ctime = (struct timespec64){ st.ctime.tv_sec, st.ctime.tv_nsec };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ino->i_size = st.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ino->i_blocks = st.blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int error, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) inode = hostfs_iget(dir->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) error = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) name = dentry_name(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) fd = file_create(name, mode & 0777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) error = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) error = read_name(inode, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) HOSTFS_I(inode)->fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) inode = hostfs_iget(ino->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) name = dentry_name(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) err = read_name(inode, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) inode = (err == -ENOENT) ? NULL : ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int hostfs_link(struct dentry *to, struct inode *ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct dentry *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) char *from_name, *to_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if ((from_name = dentry_name(from)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) to_name = dentry_name(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (to_name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) __putname(from_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) err = link_file(to_name, from_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) __putname(from_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) __putname(to_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (append)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if ((file = dentry_name(dentry)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) err = unlink_file(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) __putname(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int hostfs_symlink(struct inode *ino, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) const char *to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if ((file = dentry_name(dentry)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) err = make_symlink(file, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) __putname(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if ((file = dentry_name(dentry)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) err = do_mkdir(file, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) __putname(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if ((file = dentry_name(dentry)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) err = hostfs_do_rmdir(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) __putname(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) inode = hostfs_iget(dir->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) err = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) name = dentry_name(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) init_special_inode(inode, mode, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) err = read_name(inode, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) char *old_name, *new_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) old_name = dentry_name(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (old_name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) new_name = dentry_name(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (new_name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) __putname(old_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (!flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) err = rename_file(old_name, new_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) err = rename2_file(old_name, new_name, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) __putname(old_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) __putname(new_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int hostfs_permission(struct inode *ino, int desired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int r = 0, w = 0, x = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (desired & MAY_NOT_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (desired & MAY_READ) r = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (desired & MAY_WRITE) w = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (desired & MAY_EXEC) x = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) name = inode_name(ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) err = access_file(name, r, w, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) err = generic_permission(ino, desired);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct hostfs_iattr attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) int fd = HOSTFS_I(inode)->fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) err = setattr_prepare(dentry, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (append)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) attr->ia_valid &= ~ATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) attrs.ia_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (attr->ia_valid & ATTR_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) attrs.ia_valid |= HOSTFS_ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) attrs.ia_mode = attr->ia_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (attr->ia_valid & ATTR_UID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) attrs.ia_valid |= HOSTFS_ATTR_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) attrs.ia_uid = from_kuid(&init_user_ns, attr->ia_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (attr->ia_valid & ATTR_GID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) attrs.ia_valid |= HOSTFS_ATTR_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) attrs.ia_gid = from_kgid(&init_user_ns, attr->ia_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (attr->ia_valid & ATTR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) attrs.ia_valid |= HOSTFS_ATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) attrs.ia_size = attr->ia_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (attr->ia_valid & ATTR_ATIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) attrs.ia_valid |= HOSTFS_ATTR_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) attrs.ia_atime = (struct hostfs_timespec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) { attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (attr->ia_valid & ATTR_MTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) attrs.ia_valid |= HOSTFS_ATTR_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) attrs.ia_mtime = (struct hostfs_timespec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) { attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (attr->ia_valid & ATTR_CTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) attrs.ia_valid |= HOSTFS_ATTR_CTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) attrs.ia_ctime = (struct hostfs_timespec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) { attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (attr->ia_valid & ATTR_ATIME_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (attr->ia_valid & ATTR_MTIME_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) name = dentry_name(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) err = set_attr(name, &attrs, fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) __putname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if ((attr->ia_valid & ATTR_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) attr->ia_size != i_size_read(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) truncate_setsize(inode, attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) setattr_copy(inode, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static const struct inode_operations hostfs_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .permission = hostfs_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .setattr = hostfs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static const struct inode_operations hostfs_dir_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .create = hostfs_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .lookup = hostfs_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) .link = hostfs_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) .unlink = hostfs_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .symlink = hostfs_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .mkdir = hostfs_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .rmdir = hostfs_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .mknod = hostfs_mknod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .rename = hostfs_rename2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .permission = hostfs_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .setattr = hostfs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static const char *hostfs_get_link(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) char *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return ERR_PTR(-ECHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) link = kmalloc(PATH_MAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) char *path = dentry_name(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) err = hostfs_do_readlink(path, link, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (err == PATH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) err = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) __putname(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) kfree(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) set_delayed_call(done, kfree_link, link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static const struct inode_operations hostfs_link_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .get_link = hostfs_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct inode *root_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) char *host_root_path, *req_root = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) sb->s_blocksize = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) sb->s_blocksize_bits = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) sb->s_magic = HOSTFS_SUPER_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) sb->s_op = &hostfs_sbops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) sb->s_d_op = &simple_dentry_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) sb->s_maxbytes = MAX_LFS_FILESIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* NULL is printed as '(null)' by printf(): avoid that. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (req_root == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) req_root = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) sb->s_fs_info = host_root_path =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) kasprintf(GFP_KERNEL, "%s/%s", root_ino, req_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (host_root_path == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) root_inode = new_inode(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!root_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) err = read_name(root_inode, host_root_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (S_ISLNK(root_inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) char *name = follow_link(host_root_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (IS_ERR(name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) err = PTR_ERR(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) err = read_name(root_inode, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) sb->s_root = d_make_root(root_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (sb->s_root == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) iput(root_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static struct dentry *hostfs_read_sb(struct file_system_type *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) int flags, const char *dev_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return mount_nodev(type, flags, data, hostfs_fill_sb_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static void hostfs_kill_sb(struct super_block *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) kill_anon_super(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) kfree(s->s_fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static struct file_system_type hostfs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .name = "hostfs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .mount = hostfs_read_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .kill_sb = hostfs_kill_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .fs_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) MODULE_ALIAS_FS("hostfs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int __init init_hostfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return register_filesystem(&hostfs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static void __exit exit_hostfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) unregister_filesystem(&hostfs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) module_init(init_hostfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) module_exit(exit_hostfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) MODULE_LICENSE("GPL");