xref: /openbmc/linux/fs/9p/v9fs.c (revision 8142db4f)
11f327613SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29e82cf6aSEric Van Hensbergen /*
39e82cf6aSEric Van Hensbergen  *  This file contains functions assisting in mapping VFS to 9P2000
49e82cf6aSEric Van Hensbergen  *
58a0dc95fSEric Van Hensbergen  *  Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
69e82cf6aSEric Van Hensbergen  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
79e82cf6aSEric Van Hensbergen  */
89e82cf6aSEric Van Hensbergen 
95d385153SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
105d385153SJoe Perches 
119e82cf6aSEric Van Hensbergen #include <linux/module.h>
129e82cf6aSEric Van Hensbergen #include <linux/errno.h>
139e82cf6aSEric Van Hensbergen #include <linux/fs.h>
14914e2637SAl Viro #include <linux/sched.h>
155b825c3aSIngo Molnar #include <linux/cred.h>
169e82cf6aSEric Van Hensbergen #include <linux/parser.h>
175a0e3ad6STejun Heo #include <linux/slab.h>
18c4fac910SDavid Howells #include <linux/seq_file.h>
19bd238fb4SLatchesar Ionkov #include <net/9p/9p.h>
20bd238fb4SLatchesar Ionkov #include <net/9p/client.h>
218b81ef58SEric Van Hensbergen #include <net/9p/transport.h>
229e82cf6aSEric Van Hensbergen #include "v9fs.h"
239e82cf6aSEric Van Hensbergen #include "v9fs_vfs.h"
2460e78d2cSAbhishek Kulkarni #include "cache.h"
2560e78d2cSAbhishek Kulkarni 
2660e78d2cSAbhishek Kulkarni static DEFINE_SPINLOCK(v9fs_sessionlist_lock);
2760e78d2cSAbhishek Kulkarni static LIST_HEAD(v9fs_sessionlist);
28a78ce05dSAneesh Kumar K.V struct kmem_cache *v9fs_inode_cache;
299e82cf6aSEric Van Hensbergen 
309e82cf6aSEric Van Hensbergen /*
31a80d923eSEric Van Hensbergen  * Option Parsing (code inspired by NFS code)
32a80d923eSEric Van Hensbergen  *  NOTE: each transport will parse its own options
33a80d923eSEric Van Hensbergen  */
34a80d923eSEric Van Hensbergen 
359e82cf6aSEric Van Hensbergen enum {
369e82cf6aSEric Van Hensbergen 	/* Options that take integer arguments */
378a0dc95fSEric Van Hensbergen 	Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid,
389e82cf6aSEric Van Hensbergen 	/* String options */
39cb9af418SFabian Frederick 	Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag,
409e82cf6aSEric Van Hensbergen 	/* Options that take no arguments */
41*8142db4fSEric Van Hensbergen 	Opt_nodevmap, Opt_noxattr,
42ba17674fSLatchesar Ionkov 	/* Access options */
43e782ef71SVenkateswararao Jujjuri (JV) 	Opt_access, Opt_posixacl,
445e172f75SDinu-Razvan Chis-Serban 	/* Lock timeout option */
455e172f75SDinu-Razvan Chis-Serban 	Opt_locktimeout,
469e82cf6aSEric Van Hensbergen 	/* Error token */
479e82cf6aSEric Van Hensbergen 	Opt_err
489e82cf6aSEric Van Hensbergen };
499e82cf6aSEric Van Hensbergen 
50a447c093SSteven Whitehouse static const match_table_t tokens = {
519e2f6688SEric Van Hensbergen 	{Opt_debug, "debug=%x"},
52bd32b82dSLatchesar Ionkov 	{Opt_dfltuid, "dfltuid=%u"},
53bd32b82dSLatchesar Ionkov 	{Opt_dfltgid, "dfltgid=%u"},
549e82cf6aSEric Van Hensbergen 	{Opt_afid, "afid=%u"},
5567543e50SEric Van Hensbergen 	{Opt_uname, "uname=%s"},
569e82cf6aSEric Van Hensbergen 	{Opt_remotename, "aname=%s"},
579e82cf6aSEric Van Hensbergen 	{Opt_nodevmap, "nodevmap"},
58*8142db4fSEric Van Hensbergen 	{Opt_noxattr, "noxattr"},
5960e78d2cSAbhishek Kulkarni 	{Opt_cache, "cache=%s"},
6060e78d2cSAbhishek Kulkarni 	{Opt_cachetag, "cachetag=%s"},
61ba17674fSLatchesar Ionkov 	{Opt_access, "access=%s"},
62e782ef71SVenkateswararao Jujjuri (JV) 	{Opt_posixacl, "posixacl"},
635e172f75SDinu-Razvan Chis-Serban 	{Opt_locktimeout, "locktimeout=%u"},
649e82cf6aSEric Van Hensbergen 	{Opt_err, NULL}
659e82cf6aSEric Van Hensbergen };
669e82cf6aSEric Van Hensbergen 
67c4fac910SDavid Howells static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
68c4fac910SDavid Howells 	[CACHE_NONE]		= "none",
69d9bc0d11SEric Van Hensbergen 	[CACHE_READAHEAD]	= "readahead",
70d9bc0d11SEric Van Hensbergen 	[CACHE_WRITEBACK]	= "writeback",
71c4fac910SDavid Howells 	[CACHE_MMAP]		= "mmap",
72c4fac910SDavid Howells 	[CACHE_LOOSE]		= "loose",
73c4fac910SDavid Howells 	[CACHE_FSCACHE]		= "fscache",
74c4fac910SDavid Howells };
75c4fac910SDavid Howells 
76a2dd43bbSPrem Karat /* Interpret mount options for cache mode */
77a2dd43bbSPrem Karat static int get_cache_mode(char *s)
78a2dd43bbSPrem Karat {
79a2dd43bbSPrem Karat 	int version = -EINVAL;
80a2dd43bbSPrem Karat 
81a2dd43bbSPrem Karat 	if (!strcmp(s, "loose")) {
82a2dd43bbSPrem Karat 		version = CACHE_LOOSE;
835d385153SJoe Perches 		p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
84a2dd43bbSPrem Karat 	} else if (!strcmp(s, "fscache")) {
85a2dd43bbSPrem Karat 		version = CACHE_FSCACHE;
865d385153SJoe Perches 		p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
87fb89b45cSDominique Martinet 	} else if (!strcmp(s, "mmap")) {
88fb89b45cSDominique Martinet 		version = CACHE_MMAP;
89fb89b45cSDominique Martinet 		p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
90d9bc0d11SEric Van Hensbergen 	} else if (!strcmp(s, "writeback")) {
91d9bc0d11SEric Van Hensbergen 		version = CACHE_WRITEBACK;
92d9bc0d11SEric Van Hensbergen 		p9_debug(P9_DEBUG_9P, "Cache mode: writeback\n");
93d9bc0d11SEric Van Hensbergen 	} else if (!strcmp(s, "readahead")) {
94d9bc0d11SEric Van Hensbergen 		version = CACHE_READAHEAD;
95d9bc0d11SEric Van Hensbergen 		p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n");
96a2dd43bbSPrem Karat 	} else if (!strcmp(s, "none")) {
97a2dd43bbSPrem Karat 		version = CACHE_NONE;
985d385153SJoe Perches 		p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
99a2dd43bbSPrem Karat 	} else
1005d385153SJoe Perches 		pr_info("Unknown Cache mode %s\n", s);
101a2dd43bbSPrem Karat 	return version;
102a2dd43bbSPrem Karat }
103a2dd43bbSPrem Karat 
104c4fac910SDavid Howells /*
105c4fac910SDavid Howells  * Display the mount options in /proc/mounts.
106c4fac910SDavid Howells  */
107c4fac910SDavid Howells int v9fs_show_options(struct seq_file *m, struct dentry *root)
108c4fac910SDavid Howells {
109c4fac910SDavid Howells 	struct v9fs_session_info *v9ses = root->d_sb->s_fs_info;
110c4fac910SDavid Howells 
111c4fac910SDavid Howells 	if (v9ses->debug)
112c4fac910SDavid Howells 		seq_printf(m, ",debug=%x", v9ses->debug);
113c4fac910SDavid Howells 	if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID))
114c4fac910SDavid Howells 		seq_printf(m, ",dfltuid=%u",
115c4fac910SDavid Howells 			   from_kuid_munged(&init_user_ns, v9ses->dfltuid));
116c4fac910SDavid Howells 	if (!gid_eq(v9ses->dfltgid, V9FS_DEFGID))
117c4fac910SDavid Howells 		seq_printf(m, ",dfltgid=%u",
118c4fac910SDavid Howells 			   from_kgid_munged(&init_user_ns, v9ses->dfltgid));
119c4fac910SDavid Howells 	if (v9ses->afid != ~0)
120c4fac910SDavid Howells 		seq_printf(m, ",afid=%u", v9ses->afid);
121c4fac910SDavid Howells 	if (strcmp(v9ses->uname, V9FS_DEFUSER) != 0)
122c4fac910SDavid Howells 		seq_printf(m, ",uname=%s", v9ses->uname);
123c4fac910SDavid Howells 	if (strcmp(v9ses->aname, V9FS_DEFANAME) != 0)
124c4fac910SDavid Howells 		seq_printf(m, ",aname=%s", v9ses->aname);
125c4fac910SDavid Howells 	if (v9ses->nodev)
126c4fac910SDavid Howells 		seq_puts(m, ",nodevmap");
127c4fac910SDavid Howells 	if (v9ses->cache)
128c4fac910SDavid Howells 		seq_printf(m, ",%s", v9fs_cache_modes[v9ses->cache]);
129c4fac910SDavid Howells #ifdef CONFIG_9P_FSCACHE
130c4fac910SDavid Howells 	if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE)
131c4fac910SDavid Howells 		seq_printf(m, ",cachetag=%s", v9ses->cachetag);
132c4fac910SDavid Howells #endif
133c4fac910SDavid Howells 
134c4fac910SDavid Howells 	switch (v9ses->flags & V9FS_ACCESS_MASK) {
135c4fac910SDavid Howells 	case V9FS_ACCESS_USER:
136c4fac910SDavid Howells 		seq_puts(m, ",access=user");
137c4fac910SDavid Howells 		break;
138c4fac910SDavid Howells 	case V9FS_ACCESS_ANY:
139c4fac910SDavid Howells 		seq_puts(m, ",access=any");
140c4fac910SDavid Howells 		break;
141c4fac910SDavid Howells 	case V9FS_ACCESS_CLIENT:
142c4fac910SDavid Howells 		seq_puts(m, ",access=client");
143c4fac910SDavid Howells 		break;
144c4fac910SDavid Howells 	case V9FS_ACCESS_SINGLE:
145c4fac910SDavid Howells 		seq_printf(m, ",access=%u",
146c4fac910SDavid Howells 			   from_kuid_munged(&init_user_ns, v9ses->uid));
147c4fac910SDavid Howells 		break;
148c4fac910SDavid Howells 	}
149c4fac910SDavid Howells 
150c4fac910SDavid Howells 	if (v9ses->flags & V9FS_POSIX_ACL)
151c4fac910SDavid Howells 		seq_puts(m, ",posixacl");
152c4fac910SDavid Howells 
153*8142db4fSEric Van Hensbergen 	if (v9ses->flags & V9FS_NO_XATTR)
154*8142db4fSEric Van Hensbergen 		seq_puts(m, ",noxattr");
155*8142db4fSEric Van Hensbergen 
156c4fac910SDavid Howells 	return p9_show_client_options(m, v9ses->clnt);
157c4fac910SDavid Howells }
158c4fac910SDavid Howells 
1599e82cf6aSEric Van Hensbergen /**
1609e82cf6aSEric Van Hensbergen  * v9fs_parse_options - parse mount options into session structure
1619e82cf6aSEric Van Hensbergen  * @v9ses: existing v9fs session information
162bc868036SDavid Howells  * @opts: The mount option string
1639e82cf6aSEric Van Hensbergen  *
164ab31267dSJim Meyering  * Return 0 upon success, -ERRNO upon failure.
1659e82cf6aSEric Van Hensbergen  */
1669e82cf6aSEric Van Hensbergen 
1674b53e4b5SAbhishek Kulkarni static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
1689e82cf6aSEric Van Hensbergen {
169d8c8a9e3SEric Van Hensbergen 	char *options, *tmp_options;
1709e82cf6aSEric Van Hensbergen 	substring_t args[MAX_OPT_ARGS];
171a80d923eSEric Van Hensbergen 	char *p;
1728a0dc95fSEric Van Hensbergen 	int option = 0;
17310c69a0dSDominique Martinet 	char *s;
174ab31267dSJim Meyering 	int ret = 0;
1759e82cf6aSEric Van Hensbergen 
1769e82cf6aSEric Van Hensbergen 	/* setup defaults */
1779e82cf6aSEric Van Hensbergen 	v9ses->afid = ~0;
1789e82cf6aSEric Van Hensbergen 	v9ses->debug = 0;
179a2dd43bbSPrem Karat 	v9ses->cache = CACHE_NONE;
18060e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
18160e78d2cSAbhishek Kulkarni 	v9ses->cachetag = NULL;
18260e78d2cSAbhishek Kulkarni #endif
1835e172f75SDinu-Razvan Chis-Serban 	v9ses->session_lock_timeout = P9_LOCK_TIMEOUT;
1849e82cf6aSEric Van Hensbergen 
1854b53e4b5SAbhishek Kulkarni 	if (!opts)
186ab31267dSJim Meyering 		return 0;
1879e82cf6aSEric Van Hensbergen 
188d8c8a9e3SEric Van Hensbergen 	tmp_options = kstrdup(opts, GFP_KERNEL);
189bf2d29c6SEric Van Hensbergen 	if (!tmp_options) {
190bf2d29c6SEric Van Hensbergen 		ret = -ENOMEM;
19160e78d2cSAbhishek Kulkarni 		goto fail_option_alloc;
192bf2d29c6SEric Van Hensbergen 	}
193d8c8a9e3SEric Van Hensbergen 	options = tmp_options;
194ab31267dSJim Meyering 
1959e82cf6aSEric Van Hensbergen 	while ((p = strsep(&options, ",")) != NULL) {
1964d5077f1SAneesh Kumar K.V 		int token, r;
1976e195b0fSDominique Martinet 
1989e82cf6aSEric Van Hensbergen 		if (!*p)
1999e82cf6aSEric Van Hensbergen 			continue;
2006e195b0fSDominique Martinet 
2019e82cf6aSEric Van Hensbergen 		token = match_token(p, tokens, args);
2024d5077f1SAneesh Kumar K.V 		switch (token) {
2034d5077f1SAneesh Kumar K.V 		case Opt_debug:
2044d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
205ab31267dSJim Meyering 			if (r < 0) {
2065d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
2079e82cf6aSEric Van Hensbergen 					 "integer field, but no integer?\n");
208ab31267dSJim Meyering 				ret = r;
209478ae0caSChengguang Xu 			} else {
2109e2f6688SEric Van Hensbergen 				v9ses->debug = option;
21110fa16e7SEric Van Hensbergen #ifdef CONFIG_NET_9P_DEBUG
2129e2f6688SEric Van Hensbergen 				p9_debug_level = option;
21310fa16e7SEric Van Hensbergen #endif
214478ae0caSChengguang Xu 			}
2159e2f6688SEric Van Hensbergen 			break;
2168a0dc95fSEric Van Hensbergen 
217bd32b82dSLatchesar Ionkov 		case Opt_dfltuid:
2184d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
2194d5077f1SAneesh Kumar K.V 			if (r < 0) {
2205d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
2214d5077f1SAneesh Kumar K.V 					 "integer field, but no integer?\n");
2224d5077f1SAneesh Kumar K.V 				ret = r;
2234d5077f1SAneesh Kumar K.V 				continue;
2244d5077f1SAneesh Kumar K.V 			}
22576ed23a5SEric W. Biederman 			v9ses->dfltuid = make_kuid(current_user_ns(), option);
22676ed23a5SEric W. Biederman 			if (!uid_valid(v9ses->dfltuid)) {
22776ed23a5SEric W. Biederman 				p9_debug(P9_DEBUG_ERROR,
22876ed23a5SEric W. Biederman 					 "uid field, but not a uid?\n");
22976ed23a5SEric W. Biederman 				ret = -EINVAL;
23076ed23a5SEric W. Biederman 			}
2319e82cf6aSEric Van Hensbergen 			break;
232bd32b82dSLatchesar Ionkov 		case Opt_dfltgid:
2334d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
2344d5077f1SAneesh Kumar K.V 			if (r < 0) {
2355d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
2364d5077f1SAneesh Kumar K.V 					 "integer field, but no integer?\n");
2374d5077f1SAneesh Kumar K.V 				ret = r;
2384d5077f1SAneesh Kumar K.V 				continue;
2394d5077f1SAneesh Kumar K.V 			}
24076ed23a5SEric W. Biederman 			v9ses->dfltgid = make_kgid(current_user_ns(), option);
24176ed23a5SEric W. Biederman 			if (!gid_valid(v9ses->dfltgid)) {
24276ed23a5SEric W. Biederman 				p9_debug(P9_DEBUG_ERROR,
24376ed23a5SEric W. Biederman 					 "gid field, but not a gid?\n");
24476ed23a5SEric W. Biederman 				ret = -EINVAL;
24576ed23a5SEric W. Biederman 			}
2469e82cf6aSEric Van Hensbergen 			break;
2479e82cf6aSEric Van Hensbergen 		case Opt_afid:
2484d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
2494d5077f1SAneesh Kumar K.V 			if (r < 0) {
2505d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
2514d5077f1SAneesh Kumar K.V 					 "integer field, but no integer?\n");
2524d5077f1SAneesh Kumar K.V 				ret = r;
253478ae0caSChengguang Xu 			} else {
2549e82cf6aSEric Van Hensbergen 				v9ses->afid = option;
255478ae0caSChengguang Xu 			}
2569e82cf6aSEric Van Hensbergen 			break;
25767543e50SEric Van Hensbergen 		case Opt_uname:
258e549c133SJeff Layton 			kfree(v9ses->uname);
259e549c133SJeff Layton 			v9ses->uname = match_strdup(&args[0]);
260e549c133SJeff Layton 			if (!v9ses->uname) {
261e549c133SJeff Layton 				ret = -ENOMEM;
262e549c133SJeff Layton 				goto free_and_return;
263e549c133SJeff Layton 			}
2649e82cf6aSEric Van Hensbergen 			break;
2659e82cf6aSEric Van Hensbergen 		case Opt_remotename:
266e549c133SJeff Layton 			kfree(v9ses->aname);
267e549c133SJeff Layton 			v9ses->aname = match_strdup(&args[0]);
268e549c133SJeff Layton 			if (!v9ses->aname) {
269e549c133SJeff Layton 				ret = -ENOMEM;
270e549c133SJeff Layton 				goto free_and_return;
271e549c133SJeff Layton 			}
2729e82cf6aSEric Van Hensbergen 			break;
2739e82cf6aSEric Van Hensbergen 		case Opt_nodevmap:
2749e82cf6aSEric Van Hensbergen 			v9ses->nodev = 1;
2759e82cf6aSEric Van Hensbergen 			break;
276*8142db4fSEric Van Hensbergen 		case Opt_noxattr:
277*8142db4fSEric Van Hensbergen 			v9ses->flags |= V9FS_NO_XATTR;
278*8142db4fSEric Van Hensbergen 			break;
27960e78d2cSAbhishek Kulkarni 		case Opt_cachetag:
28060e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
281c4fac910SDavid Howells 			kfree(v9ses->cachetag);
28260e78d2cSAbhishek Kulkarni 			v9ses->cachetag = match_strdup(&args[0]);
283a25c3657SChengguang Xu 			if (!v9ses->cachetag) {
284a25c3657SChengguang Xu 				ret = -ENOMEM;
285a25c3657SChengguang Xu 				goto free_and_return;
286a25c3657SChengguang Xu 			}
28760e78d2cSAbhishek Kulkarni #endif
28860e78d2cSAbhishek Kulkarni 			break;
28960e78d2cSAbhishek Kulkarni 		case Opt_cache:
29060e78d2cSAbhishek Kulkarni 			s = match_strdup(&args[0]);
291bf2d29c6SEric Van Hensbergen 			if (!s) {
292bf2d29c6SEric Van Hensbergen 				ret = -ENOMEM;
2935d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
294bf2d29c6SEric Van Hensbergen 					 "problem allocating copy of cache arg\n");
295bf2d29c6SEric Van Hensbergen 				goto free_and_return;
296bf2d29c6SEric Van Hensbergen 			}
297478ae0caSChengguang Xu 			r = get_cache_mode(s);
298478ae0caSChengguang Xu 			if (r < 0)
299478ae0caSChengguang Xu 				ret = r;
300478ae0caSChengguang Xu 			else
301478ae0caSChengguang Xu 				v9ses->cache = r;
30260e78d2cSAbhishek Kulkarni 
30360e78d2cSAbhishek Kulkarni 			kfree(s);
30460e78d2cSAbhishek Kulkarni 			break;
305ba17674fSLatchesar Ionkov 
306ba17674fSLatchesar Ionkov 		case Opt_access:
307ba17674fSLatchesar Ionkov 			s = match_strdup(&args[0]);
308bf2d29c6SEric Van Hensbergen 			if (!s) {
309bf2d29c6SEric Van Hensbergen 				ret = -ENOMEM;
3105d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
311bf2d29c6SEric Van Hensbergen 					 "problem allocating copy of access arg\n");
312bf2d29c6SEric Van Hensbergen 				goto free_and_return;
313bf2d29c6SEric Van Hensbergen 			}
31460e78d2cSAbhishek Kulkarni 
315ba17674fSLatchesar Ionkov 			v9ses->flags &= ~V9FS_ACCESS_MASK;
316ba17674fSLatchesar Ionkov 			if (strcmp(s, "user") == 0)
317ba17674fSLatchesar Ionkov 				v9ses->flags |= V9FS_ACCESS_USER;
318ba17674fSLatchesar Ionkov 			else if (strcmp(s, "any") == 0)
319ba17674fSLatchesar Ionkov 				v9ses->flags |= V9FS_ACCESS_ANY;
32076381a42SAneesh Kumar K.V 			else if (strcmp(s, "client") == 0) {
32176381a42SAneesh Kumar K.V 				v9ses->flags |= V9FS_ACCESS_CLIENT;
32276381a42SAneesh Kumar K.V 			} else {
32376ed23a5SEric W. Biederman 				uid_t uid;
32410c69a0dSDominique Martinet 
325ba17674fSLatchesar Ionkov 				v9ses->flags |= V9FS_ACCESS_SINGLE;
32610c69a0dSDominique Martinet 				r = kstrtouint(s, 10, &uid);
32710c69a0dSDominique Martinet 				if (r) {
32810c69a0dSDominique Martinet 					ret = r;
32910c69a0dSDominique Martinet 					pr_info("Unknown access argument %s: %d\n",
33010c69a0dSDominique Martinet 						s, r);
331a2dd43bbSPrem Karat 					kfree(s);
332478ae0caSChengguang Xu 					continue;
333ba17674fSLatchesar Ionkov 				}
33476ed23a5SEric W. Biederman 				v9ses->uid = make_kuid(current_user_ns(), uid);
33576ed23a5SEric W. Biederman 				if (!uid_valid(v9ses->uid)) {
33676ed23a5SEric W. Biederman 					ret = -EINVAL;
3376baaac09SColin Ian King 					pr_info("Unknown uid %s\n", s);
33876ed23a5SEric W. Biederman 				}
339a2dd43bbSPrem Karat 			}
340a2dd43bbSPrem Karat 
3410a976297SAdrian Bunk 			kfree(s);
342ba17674fSLatchesar Ionkov 			break;
343ba17674fSLatchesar Ionkov 
344e782ef71SVenkateswararao Jujjuri (JV) 		case Opt_posixacl:
345e782ef71SVenkateswararao Jujjuri (JV) #ifdef CONFIG_9P_FS_POSIX_ACL
346e782ef71SVenkateswararao Jujjuri (JV) 			v9ses->flags |= V9FS_POSIX_ACL;
347e782ef71SVenkateswararao Jujjuri (JV) #else
3485d385153SJoe Perches 			p9_debug(P9_DEBUG_ERROR,
3495d385153SJoe Perches 				 "Not defined CONFIG_9P_FS_POSIX_ACL. Ignoring posixacl option\n");
350e782ef71SVenkateswararao Jujjuri (JV) #endif
351e782ef71SVenkateswararao Jujjuri (JV) 			break;
352e782ef71SVenkateswararao Jujjuri (JV) 
3535e172f75SDinu-Razvan Chis-Serban 		case Opt_locktimeout:
3545e172f75SDinu-Razvan Chis-Serban 			r = match_int(&args[0], &option);
3555e172f75SDinu-Razvan Chis-Serban 			if (r < 0) {
3565e172f75SDinu-Razvan Chis-Serban 				p9_debug(P9_DEBUG_ERROR,
3575e172f75SDinu-Razvan Chis-Serban 					 "integer field, but no integer?\n");
3585e172f75SDinu-Razvan Chis-Serban 				ret = r;
3595e172f75SDinu-Razvan Chis-Serban 				continue;
3605e172f75SDinu-Razvan Chis-Serban 			}
3615e172f75SDinu-Razvan Chis-Serban 			if (option < 1) {
3625e172f75SDinu-Razvan Chis-Serban 				p9_debug(P9_DEBUG_ERROR,
3635e172f75SDinu-Razvan Chis-Serban 					 "locktimeout must be a greater than zero integer.\n");
3645e172f75SDinu-Razvan Chis-Serban 				ret = -EINVAL;
3655e172f75SDinu-Razvan Chis-Serban 				continue;
3665e172f75SDinu-Razvan Chis-Serban 			}
3675e172f75SDinu-Razvan Chis-Serban 			v9ses->session_lock_timeout = (long)option * HZ;
3685e172f75SDinu-Razvan Chis-Serban 			break;
3695e172f75SDinu-Razvan Chis-Serban 
3709e82cf6aSEric Van Hensbergen 		default:
3719e82cf6aSEric Van Hensbergen 			continue;
3729e82cf6aSEric Van Hensbergen 		}
3739e82cf6aSEric Van Hensbergen 	}
374d8c8a9e3SEric Van Hensbergen 
375bf2d29c6SEric Van Hensbergen free_and_return:
376d8c8a9e3SEric Van Hensbergen 	kfree(tmp_options);
37760e78d2cSAbhishek Kulkarni fail_option_alloc:
378bf2d29c6SEric Van Hensbergen 	return ret;
3799e82cf6aSEric Van Hensbergen }
3809e82cf6aSEric Van Hensbergen 
3819e82cf6aSEric Van Hensbergen /**
3829e82cf6aSEric Van Hensbergen  * v9fs_session_init - initialize session
3839e82cf6aSEric Van Hensbergen  * @v9ses: session information structure
3849e82cf6aSEric Van Hensbergen  * @dev_name: device being mounted
3859e82cf6aSEric Van Hensbergen  * @data: options
3869e82cf6aSEric Van Hensbergen  *
3879e82cf6aSEric Van Hensbergen  */
3889e82cf6aSEric Van Hensbergen 
389bd238fb4SLatchesar Ionkov struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
3909e82cf6aSEric Van Hensbergen 		  const char *dev_name, char *data)
3919e82cf6aSEric Van Hensbergen {
392bd238fb4SLatchesar Ionkov 	struct p9_fid *fid;
393412a19b6STejun Heo 	int rc = -ENOMEM;
3949e82cf6aSEric Van Hensbergen 
395e549c133SJeff Layton 	v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
396ba17674fSLatchesar Ionkov 	if (!v9ses->uname)
397412a19b6STejun Heo 		goto err_names;
3989e82cf6aSEric Van Hensbergen 
399e549c133SJeff Layton 	v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
400412a19b6STejun Heo 	if (!v9ses->aname)
401412a19b6STejun Heo 		goto err_names;
402a534c8d1SAneesh Kumar K.V 	init_rwsem(&v9ses->rename_sem);
4039e82cf6aSEric Van Hensbergen 
40476ed23a5SEric W. Biederman 	v9ses->uid = INVALID_UID;
405bd32b82dSLatchesar Ionkov 	v9ses->dfltuid = V9FS_DEFUID;
406bd32b82dSLatchesar Ionkov 	v9ses->dfltgid = V9FS_DEFGID;
407ab31267dSJim Meyering 
4084b53e4b5SAbhishek Kulkarni 	v9ses->clnt = p9_client_create(dev_name, data);
409bd238fb4SLatchesar Ionkov 	if (IS_ERR(v9ses->clnt)) {
410412a19b6STejun Heo 		rc = PTR_ERR(v9ses->clnt);
4115d385153SJoe Perches 		p9_debug(P9_DEBUG_ERROR, "problem initializing 9p client\n");
41271304febSJan Kara 		goto err_names;
4139e82cf6aSEric Van Hensbergen 	}
4149e82cf6aSEric Van Hensbergen 
4156752a1ebSVenkateswararao Jujjuri (JV) 	v9ses->flags = V9FS_ACCESS_USER;
4166752a1ebSVenkateswararao Jujjuri (JV) 
4176752a1ebSVenkateswararao Jujjuri (JV) 	if (p9_is_proto_dotl(v9ses->clnt)) {
4186752a1ebSVenkateswararao Jujjuri (JV) 		v9ses->flags = V9FS_ACCESS_CLIENT;
419476ada04SSripathi Kodi 		v9ses->flags |= V9FS_PROTO_2000L;
4206752a1ebSVenkateswararao Jujjuri (JV) 	} else if (p9_is_proto_dotu(v9ses->clnt)) {
421476ada04SSripathi Kodi 		v9ses->flags |= V9FS_PROTO_2000U;
4226752a1ebSVenkateswararao Jujjuri (JV) 	}
4236752a1ebSVenkateswararao Jujjuri (JV) 
4246752a1ebSVenkateswararao Jujjuri (JV) 	rc = v9fs_parse_options(v9ses, data);
425412a19b6STejun Heo 	if (rc < 0)
426412a19b6STejun Heo 		goto err_clnt;
427ba17674fSLatchesar Ionkov 
428fbedadc1SEric Van Hensbergen 	v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
4298a0dc95fSEric Van Hensbergen 
43076381a42SAneesh Kumar K.V 	if (!v9fs_proto_dotl(v9ses) &&
43176381a42SAneesh Kumar K.V 	    ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
43276381a42SAneesh Kumar K.V 		/*
43376381a42SAneesh Kumar K.V 		 * We support ACCESS_CLIENT only for dotl.
43476381a42SAneesh Kumar K.V 		 * Fall back to ACCESS_USER
43576381a42SAneesh Kumar K.V 		 */
43676381a42SAneesh Kumar K.V 		v9ses->flags &= ~V9FS_ACCESS_MASK;
43776381a42SAneesh Kumar K.V 		v9ses->flags |= V9FS_ACCESS_USER;
43876381a42SAneesh Kumar K.V 	}
43976381a42SAneesh Kumar K.V 	/*FIXME !! */
440ba17674fSLatchesar Ionkov 	/* for legacy mode, fall back to V9FS_ACCESS_ANY */
4419ffaf63eSAneesh Kumar K.V 	if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
442ba17674fSLatchesar Ionkov 		((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
443ba17674fSLatchesar Ionkov 
444ba17674fSLatchesar Ionkov 		v9ses->flags &= ~V9FS_ACCESS_MASK;
445ba17674fSLatchesar Ionkov 		v9ses->flags |= V9FS_ACCESS_ANY;
44676ed23a5SEric W. Biederman 		v9ses->uid = INVALID_UID;
447ba17674fSLatchesar Ionkov 	}
448e782ef71SVenkateswararao Jujjuri (JV) 	if (!v9fs_proto_dotl(v9ses) ||
449e782ef71SVenkateswararao Jujjuri (JV) 		!((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
450e782ef71SVenkateswararao Jujjuri (JV) 		/*
451e782ef71SVenkateswararao Jujjuri (JV) 		 * We support ACL checks on clinet only if the protocol is
452e782ef71SVenkateswararao Jujjuri (JV) 		 * 9P2000.L and access is V9FS_ACCESS_CLIENT.
453e782ef71SVenkateswararao Jujjuri (JV) 		 */
454e782ef71SVenkateswararao Jujjuri (JV) 		v9ses->flags &= ~V9FS_ACL_MASK;
455e782ef71SVenkateswararao Jujjuri (JV) 	}
456ba17674fSLatchesar Ionkov 
457f791f7c5SEric W. Biederman 	fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
458ba17674fSLatchesar Ionkov 							v9ses->aname);
459bd238fb4SLatchesar Ionkov 	if (IS_ERR(fid)) {
460412a19b6STejun Heo 		rc = PTR_ERR(fid);
4615d385153SJoe Perches 		p9_debug(P9_DEBUG_ERROR, "cannot attach\n");
462412a19b6STejun Heo 		goto err_clnt;
4639e82cf6aSEric Van Hensbergen 	}
4649e82cf6aSEric Van Hensbergen 
465ba17674fSLatchesar Ionkov 	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
466ba17674fSLatchesar Ionkov 		fid->uid = v9ses->uid;
467ba17674fSLatchesar Ionkov 	else
468b4642556SEric W. Biederman 		fid->uid = INVALID_UID;
469ba17674fSLatchesar Ionkov 
47060e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
47160e78d2cSAbhishek Kulkarni 	/* register the session for caching */
472344504e9SEric Van Hensbergen 	if (v9ses->cache == CACHE_FSCACHE) {
47324e42e32SDavid Howells 		rc = v9fs_cache_session_get_cookie(v9ses, dev_name);
47424e42e32SDavid Howells 		if (rc < 0)
47524e42e32SDavid Howells 			goto err_clnt;
47624e42e32SDavid Howells 	}
47760e78d2cSAbhishek Kulkarni #endif
478412a19b6STejun Heo 	spin_lock(&v9fs_sessionlist_lock);
479412a19b6STejun Heo 	list_add(&v9ses->slist, &v9fs_sessionlist);
480412a19b6STejun Heo 	spin_unlock(&v9fs_sessionlist_lock);
48160e78d2cSAbhishek Kulkarni 
482bd238fb4SLatchesar Ionkov 	return fid;
4839e82cf6aSEric Van Hensbergen 
484412a19b6STejun Heo err_clnt:
485a25c3657SChengguang Xu #ifdef CONFIG_9P_FSCACHE
486a25c3657SChengguang Xu 	kfree(v9ses->cachetag);
487a25c3657SChengguang Xu #endif
488412a19b6STejun Heo 	p9_client_destroy(v9ses->clnt);
489412a19b6STejun Heo err_names:
490412a19b6STejun Heo 	kfree(v9ses->uname);
491412a19b6STejun Heo 	kfree(v9ses->aname);
492412a19b6STejun Heo 	return ERR_PTR(rc);
4939e82cf6aSEric Van Hensbergen }
4949e82cf6aSEric Van Hensbergen 
4959e82cf6aSEric Van Hensbergen /**
4969e82cf6aSEric Van Hensbergen  * v9fs_session_close - shutdown a session
4979e82cf6aSEric Van Hensbergen  * @v9ses: session information structure
4989e82cf6aSEric Van Hensbergen  *
4999e82cf6aSEric Van Hensbergen  */
5009e82cf6aSEric Van Hensbergen 
5019e82cf6aSEric Van Hensbergen void v9fs_session_close(struct v9fs_session_info *v9ses)
5029e82cf6aSEric Van Hensbergen {
503bd238fb4SLatchesar Ionkov 	if (v9ses->clnt) {
504bd238fb4SLatchesar Ionkov 		p9_client_destroy(v9ses->clnt);
505bd238fb4SLatchesar Ionkov 		v9ses->clnt = NULL;
5063cf6429aSLatchesar Ionkov 	}
5079e82cf6aSEric Van Hensbergen 
50860e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
50924e42e32SDavid Howells 	fscache_relinquish_volume(v9fs_session_cache(v9ses), NULL, false);
51060e78d2cSAbhishek Kulkarni 	kfree(v9ses->cachetag);
51160e78d2cSAbhishek Kulkarni #endif
512e549c133SJeff Layton 	kfree(v9ses->uname);
513e549c133SJeff Layton 	kfree(v9ses->aname);
51460e78d2cSAbhishek Kulkarni 
51560e78d2cSAbhishek Kulkarni 	spin_lock(&v9fs_sessionlist_lock);
51660e78d2cSAbhishek Kulkarni 	list_del(&v9ses->slist);
51760e78d2cSAbhishek Kulkarni 	spin_unlock(&v9fs_sessionlist_lock);
5189e82cf6aSEric Van Hensbergen }
5199e82cf6aSEric Van Hensbergen 
520322b329aSEric Van Hensbergen /**
521ee443996SEric Van Hensbergen  * v9fs_session_cancel - terminate a session
522ee443996SEric Van Hensbergen  * @v9ses: session to terminate
523ee443996SEric Van Hensbergen  *
524ee443996SEric Van Hensbergen  * mark transport as disconnected and cancel all pending requests.
525322b329aSEric Van Hensbergen  */
526ee443996SEric Van Hensbergen 
527e4eeefbaSSohaib Mohamed void v9fs_session_cancel(struct v9fs_session_info *v9ses)
528e4eeefbaSSohaib Mohamed {
5295d385153SJoe Perches 	p9_debug(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
530bd238fb4SLatchesar Ionkov 	p9_client_disconnect(v9ses->clnt);
531322b329aSEric Van Hensbergen }
532322b329aSEric Van Hensbergen 
5336d96d3abSAneesh Kumar K.V /**
5346d96d3abSAneesh Kumar K.V  * v9fs_session_begin_cancel - Begin terminate of a session
5356d96d3abSAneesh Kumar K.V  * @v9ses: session to terminate
5366d96d3abSAneesh Kumar K.V  *
5376d96d3abSAneesh Kumar K.V  * After this call we don't allow any request other than clunk.
5386d96d3abSAneesh Kumar K.V  */
5396d96d3abSAneesh Kumar K.V 
5406d96d3abSAneesh Kumar K.V void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
5416d96d3abSAneesh Kumar K.V {
5425d385153SJoe Perches 	p9_debug(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
5436d96d3abSAneesh Kumar K.V 	p9_client_begin_disconnect(v9ses->clnt);
5446d96d3abSAneesh Kumar K.V }
5456d96d3abSAneesh Kumar K.V 
5469e82cf6aSEric Van Hensbergen extern int v9fs_error_init(void);
5479e82cf6aSEric Van Hensbergen 
54860e78d2cSAbhishek Kulkarni static struct kobject *v9fs_kobj;
54960e78d2cSAbhishek Kulkarni 
55060e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
551bc868036SDavid Howells /*
552bc868036SDavid Howells  * List caches associated with a session
55360e78d2cSAbhishek Kulkarni  */
55460e78d2cSAbhishek Kulkarni static ssize_t caches_show(struct kobject *kobj,
55560e78d2cSAbhishek Kulkarni 			   struct kobj_attribute *attr,
55660e78d2cSAbhishek Kulkarni 			   char *buf)
55760e78d2cSAbhishek Kulkarni {
55860e78d2cSAbhishek Kulkarni 	ssize_t n = 0, count = 0, limit = PAGE_SIZE;
55960e78d2cSAbhishek Kulkarni 	struct v9fs_session_info *v9ses;
56060e78d2cSAbhishek Kulkarni 
56160e78d2cSAbhishek Kulkarni 	spin_lock(&v9fs_sessionlist_lock);
56260e78d2cSAbhishek Kulkarni 	list_for_each_entry(v9ses, &v9fs_sessionlist, slist) {
56360e78d2cSAbhishek Kulkarni 		if (v9ses->cachetag) {
56460e78d2cSAbhishek Kulkarni 			n = snprintf(buf, limit, "%s\n", v9ses->cachetag);
56560e78d2cSAbhishek Kulkarni 			if (n < 0) {
56660e78d2cSAbhishek Kulkarni 				count = n;
56760e78d2cSAbhishek Kulkarni 				break;
56860e78d2cSAbhishek Kulkarni 			}
56960e78d2cSAbhishek Kulkarni 
57060e78d2cSAbhishek Kulkarni 			count += n;
57160e78d2cSAbhishek Kulkarni 			limit -= n;
57260e78d2cSAbhishek Kulkarni 		}
57360e78d2cSAbhishek Kulkarni 	}
57460e78d2cSAbhishek Kulkarni 
57560e78d2cSAbhishek Kulkarni 	spin_unlock(&v9fs_sessionlist_lock);
57660e78d2cSAbhishek Kulkarni 	return count;
57760e78d2cSAbhishek Kulkarni }
57860e78d2cSAbhishek Kulkarni 
57960e78d2cSAbhishek Kulkarni static struct kobj_attribute v9fs_attr_cache = __ATTR_RO(caches);
58060e78d2cSAbhishek Kulkarni #endif /* CONFIG_9P_FSCACHE */
58160e78d2cSAbhishek Kulkarni 
58260e78d2cSAbhishek Kulkarni static struct attribute *v9fs_attrs[] = {
58360e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
58460e78d2cSAbhishek Kulkarni 	&v9fs_attr_cache.attr,
58560e78d2cSAbhishek Kulkarni #endif
58660e78d2cSAbhishek Kulkarni 	NULL,
58760e78d2cSAbhishek Kulkarni };
58860e78d2cSAbhishek Kulkarni 
5890dae5228SRikard Falkeborn static const struct attribute_group v9fs_attr_group = {
59060e78d2cSAbhishek Kulkarni 	.attrs = v9fs_attrs,
59160e78d2cSAbhishek Kulkarni };
59260e78d2cSAbhishek Kulkarni 
59360e78d2cSAbhishek Kulkarni /**
59460e78d2cSAbhishek Kulkarni  * v9fs_sysfs_init - Initialize the v9fs sysfs interface
59560e78d2cSAbhishek Kulkarni  *
59660e78d2cSAbhishek Kulkarni  */
59760e78d2cSAbhishek Kulkarni 
598bdbeacdeSFabian Frederick static int __init v9fs_sysfs_init(void)
59960e78d2cSAbhishek Kulkarni {
60060e78d2cSAbhishek Kulkarni 	v9fs_kobj = kobject_create_and_add("9p", fs_kobj);
60160e78d2cSAbhishek Kulkarni 	if (!v9fs_kobj)
60260e78d2cSAbhishek Kulkarni 		return -ENOMEM;
60360e78d2cSAbhishek Kulkarni 
60460e78d2cSAbhishek Kulkarni 	if (sysfs_create_group(v9fs_kobj, &v9fs_attr_group)) {
60560e78d2cSAbhishek Kulkarni 		kobject_put(v9fs_kobj);
60660e78d2cSAbhishek Kulkarni 		return -ENOMEM;
60760e78d2cSAbhishek Kulkarni 	}
60860e78d2cSAbhishek Kulkarni 
60960e78d2cSAbhishek Kulkarni 	return 0;
61060e78d2cSAbhishek Kulkarni }
61160e78d2cSAbhishek Kulkarni 
61260e78d2cSAbhishek Kulkarni /**
61360e78d2cSAbhishek Kulkarni  * v9fs_sysfs_cleanup - Unregister the v9fs sysfs interface
61460e78d2cSAbhishek Kulkarni  *
61560e78d2cSAbhishek Kulkarni  */
61660e78d2cSAbhishek Kulkarni 
61760e78d2cSAbhishek Kulkarni static void v9fs_sysfs_cleanup(void)
61860e78d2cSAbhishek Kulkarni {
61960e78d2cSAbhishek Kulkarni 	sysfs_remove_group(v9fs_kobj, &v9fs_attr_group);
62060e78d2cSAbhishek Kulkarni 	kobject_put(v9fs_kobj);
62160e78d2cSAbhishek Kulkarni }
62260e78d2cSAbhishek Kulkarni 
623a78ce05dSAneesh Kumar K.V static void v9fs_inode_init_once(void *foo)
624a78ce05dSAneesh Kumar K.V {
625a78ce05dSAneesh Kumar K.V 	struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
626bc899ee1SDavid Howells 
627fd2421f5SAneesh Kumar K.V 	memset(&v9inode->qid, 0, sizeof(v9inode->qid));
628874c8ca1SDavid Howells 	inode_init_once(&v9inode->netfs.inode);
629a78ce05dSAneesh Kumar K.V }
630a78ce05dSAneesh Kumar K.V 
631a78ce05dSAneesh Kumar K.V /**
632a78ce05dSAneesh Kumar K.V  * v9fs_init_inode_cache - initialize a cache for 9P
633a78ce05dSAneesh Kumar K.V  * Returns 0 on success.
634a78ce05dSAneesh Kumar K.V  */
635a78ce05dSAneesh Kumar K.V static int v9fs_init_inode_cache(void)
636a78ce05dSAneesh Kumar K.V {
637a78ce05dSAneesh Kumar K.V 	v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache",
638a78ce05dSAneesh Kumar K.V 					  sizeof(struct v9fs_inode),
639a78ce05dSAneesh Kumar K.V 					  0, (SLAB_RECLAIM_ACCOUNT|
6405d097056SVladimir Davydov 					      SLAB_MEM_SPREAD|SLAB_ACCOUNT),
641a78ce05dSAneesh Kumar K.V 					  v9fs_inode_init_once);
642a78ce05dSAneesh Kumar K.V 	if (!v9fs_inode_cache)
643a78ce05dSAneesh Kumar K.V 		return -ENOMEM;
644a78ce05dSAneesh Kumar K.V 
645a78ce05dSAneesh Kumar K.V 	return 0;
646a78ce05dSAneesh Kumar K.V }
647a78ce05dSAneesh Kumar K.V 
648a78ce05dSAneesh Kumar K.V /**
649a78ce05dSAneesh Kumar K.V  * v9fs_destroy_inode_cache - destroy the cache of 9P inode
650a78ce05dSAneesh Kumar K.V  *
651a78ce05dSAneesh Kumar K.V  */
652a78ce05dSAneesh Kumar K.V static void v9fs_destroy_inode_cache(void)
653a78ce05dSAneesh Kumar K.V {
6548c0a8537SKirill A. Shutemov 	/*
6558c0a8537SKirill A. Shutemov 	 * Make sure all delayed rcu free inodes are flushed before we
6568c0a8537SKirill A. Shutemov 	 * destroy cache.
6578c0a8537SKirill A. Shutemov 	 */
6588c0a8537SKirill A. Shutemov 	rcu_barrier();
659a78ce05dSAneesh Kumar K.V 	kmem_cache_destroy(v9fs_inode_cache);
660a78ce05dSAneesh Kumar K.V }
661a78ce05dSAneesh Kumar K.V 
662a78ce05dSAneesh Kumar K.V static int v9fs_cache_register(void)
663a78ce05dSAneesh Kumar K.V {
664a78ce05dSAneesh Kumar K.V 	int ret;
6656e195b0fSDominique Martinet 
666a78ce05dSAneesh Kumar K.V 	ret = v9fs_init_inode_cache();
667a78ce05dSAneesh Kumar K.V 	if (ret < 0)
668a78ce05dSAneesh Kumar K.V 		return ret;
6698061a6faSAl Viro 	return ret;
670a78ce05dSAneesh Kumar K.V }
671a78ce05dSAneesh Kumar K.V 
672a78ce05dSAneesh Kumar K.V static void v9fs_cache_unregister(void)
673a78ce05dSAneesh Kumar K.V {
674a78ce05dSAneesh Kumar K.V 	v9fs_destroy_inode_cache();
675a78ce05dSAneesh Kumar K.V }
676a78ce05dSAneesh Kumar K.V 
67760e78d2cSAbhishek Kulkarni /**
67860e78d2cSAbhishek Kulkarni  * init_v9fs - Initialize module
6799e82cf6aSEric Van Hensbergen  *
6809e82cf6aSEric Van Hensbergen  */
6819e82cf6aSEric Van Hensbergen 
6829e82cf6aSEric Van Hensbergen static int __init init_v9fs(void)
6839e82cf6aSEric Van Hensbergen {
68460e78d2cSAbhishek Kulkarni 	int err;
6856e195b0fSDominique Martinet 
6865d385153SJoe Perches 	pr_info("Installing v9fs 9p2000 file system support\n");
687a80d923eSEric Van Hensbergen 	/* TODO: Setup list of registered trasnport modules */
68860e78d2cSAbhishek Kulkarni 
68960e78d2cSAbhishek Kulkarni 	err = v9fs_cache_register();
69060e78d2cSAbhishek Kulkarni 	if (err < 0) {
6915d385153SJoe Perches 		pr_err("Failed to register v9fs for caching\n");
6922226a288SAl Viro 		return err;
69360e78d2cSAbhishek Kulkarni 	}
69460e78d2cSAbhishek Kulkarni 
69560e78d2cSAbhishek Kulkarni 	err = v9fs_sysfs_init();
69660e78d2cSAbhishek Kulkarni 	if (err < 0) {
6975d385153SJoe Perches 		pr_err("Failed to register with sysfs\n");
6982226a288SAl Viro 		goto out_cache;
6992226a288SAl Viro 	}
7002226a288SAl Viro 	err = register_filesystem(&v9fs_fs_type);
7012226a288SAl Viro 	if (err < 0) {
7022226a288SAl Viro 		pr_err("Failed to register filesystem\n");
70360e78d2cSAbhishek Kulkarni 		goto out_sysfs_cleanup;
70460e78d2cSAbhishek Kulkarni 	}
70560e78d2cSAbhishek Kulkarni 
70660e78d2cSAbhishek Kulkarni 	return 0;
70760e78d2cSAbhishek Kulkarni 
70860e78d2cSAbhishek Kulkarni out_sysfs_cleanup:
70960e78d2cSAbhishek Kulkarni 	v9fs_sysfs_cleanup();
71060e78d2cSAbhishek Kulkarni 
7112226a288SAl Viro out_cache:
7122226a288SAl Viro 	v9fs_cache_unregister();
71360e78d2cSAbhishek Kulkarni 
71460e78d2cSAbhishek Kulkarni 	return err;
7159e82cf6aSEric Van Hensbergen }
7169e82cf6aSEric Van Hensbergen 
7179e82cf6aSEric Van Hensbergen /**
71860e78d2cSAbhishek Kulkarni  * exit_v9fs - shutdown module
7199e82cf6aSEric Van Hensbergen  *
7209e82cf6aSEric Van Hensbergen  */
7219e82cf6aSEric Van Hensbergen 
7229e82cf6aSEric Van Hensbergen static void __exit exit_v9fs(void)
7239e82cf6aSEric Van Hensbergen {
72460e78d2cSAbhishek Kulkarni 	v9fs_sysfs_cleanup();
72560e78d2cSAbhishek Kulkarni 	v9fs_cache_unregister();
7269e82cf6aSEric Van Hensbergen 	unregister_filesystem(&v9fs_fs_type);
7279e82cf6aSEric Van Hensbergen }
7289e82cf6aSEric Van Hensbergen 
7299e82cf6aSEric Van Hensbergen module_init(init_v9fs)
7309e82cf6aSEric Van Hensbergen module_exit(exit_v9fs)
7319e82cf6aSEric Van Hensbergen 
732bd238fb4SLatchesar Ionkov MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
7339e82cf6aSEric Van Hensbergen MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
7349e82cf6aSEric Van Hensbergen MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
7359e82cf6aSEric Van Hensbergen MODULE_LICENSE("GPL");
736