Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");