VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

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