xref: /openbmc/linux/fs/9p/v9fs.c (revision cb9af418)
19e82cf6aSEric Van Hensbergen /*
29e82cf6aSEric Van Hensbergen  *  linux/fs/9p/v9fs.c
39e82cf6aSEric Van Hensbergen  *
49e82cf6aSEric Van Hensbergen  *  This file contains functions assisting in mapping VFS to 9P2000
59e82cf6aSEric Van Hensbergen  *
68a0dc95fSEric Van Hensbergen  *  Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
79e82cf6aSEric Van Hensbergen  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
89e82cf6aSEric Van Hensbergen  *
99e82cf6aSEric Van Hensbergen  *  This program is free software; you can redistribute it and/or modify
1042e8c509SEric Van Hensbergen  *  it under the terms of the GNU General Public License version 2
1142e8c509SEric Van Hensbergen  *  as published by the Free Software Foundation.
129e82cf6aSEric Van Hensbergen  *
139e82cf6aSEric Van Hensbergen  *  This program is distributed in the hope that it will be useful,
149e82cf6aSEric Van Hensbergen  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
159e82cf6aSEric Van Hensbergen  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
169e82cf6aSEric Van Hensbergen  *  GNU General Public License for more details.
179e82cf6aSEric Van Hensbergen  *
189e82cf6aSEric Van Hensbergen  *  You should have received a copy of the GNU General Public License
199e82cf6aSEric Van Hensbergen  *  along with this program; if not, write to:
209e82cf6aSEric Van Hensbergen  *  Free Software Foundation
219e82cf6aSEric Van Hensbergen  *  51 Franklin Street, Fifth Floor
229e82cf6aSEric Van Hensbergen  *  Boston, MA  02111-1301  USA
239e82cf6aSEric Van Hensbergen  *
249e82cf6aSEric Van Hensbergen  */
259e82cf6aSEric Van Hensbergen 
265d385153SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
275d385153SJoe Perches 
289e82cf6aSEric Van Hensbergen #include <linux/module.h>
299e82cf6aSEric Van Hensbergen #include <linux/errno.h>
309e82cf6aSEric Van Hensbergen #include <linux/fs.h>
31914e2637SAl Viro #include <linux/sched.h>
329e82cf6aSEric Van Hensbergen #include <linux/parser.h>
339e82cf6aSEric Van Hensbergen #include <linux/idr.h>
345a0e3ad6STejun Heo #include <linux/slab.h>
35bd238fb4SLatchesar Ionkov #include <net/9p/9p.h>
36bd238fb4SLatchesar Ionkov #include <net/9p/client.h>
378b81ef58SEric Van Hensbergen #include <net/9p/transport.h>
389e82cf6aSEric Van Hensbergen #include "v9fs.h"
399e82cf6aSEric Van Hensbergen #include "v9fs_vfs.h"
4060e78d2cSAbhishek Kulkarni #include "cache.h"
4160e78d2cSAbhishek Kulkarni 
4260e78d2cSAbhishek Kulkarni static DEFINE_SPINLOCK(v9fs_sessionlist_lock);
4360e78d2cSAbhishek Kulkarni static LIST_HEAD(v9fs_sessionlist);
44a78ce05dSAneesh Kumar K.V struct kmem_cache *v9fs_inode_cache;
459e82cf6aSEric Van Hensbergen 
469e82cf6aSEric Van Hensbergen /*
47a80d923eSEric Van Hensbergen  * Option Parsing (code inspired by NFS code)
48a80d923eSEric Van Hensbergen  *  NOTE: each transport will parse its own options
49a80d923eSEric Van Hensbergen  */
50a80d923eSEric Van Hensbergen 
519e82cf6aSEric Van Hensbergen enum {
529e82cf6aSEric Van Hensbergen 	/* Options that take integer arguments */
538a0dc95fSEric Van Hensbergen 	Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid,
549e82cf6aSEric Van Hensbergen 	/* String options */
55cb9af418SFabian Frederick 	Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag,
569e82cf6aSEric Van Hensbergen 	/* Options that take no arguments */
578a0dc95fSEric Van Hensbergen 	Opt_nodevmap,
58e03abc0cSEric Van Hensbergen 	/* Cache options */
59fb89b45cSDominique Martinet 	Opt_cache_loose, Opt_fscache, Opt_mmap,
60ba17674fSLatchesar Ionkov 	/* Access options */
61e782ef71SVenkateswararao Jujjuri (JV) 	Opt_access, Opt_posixacl,
629e82cf6aSEric Van Hensbergen 	/* Error token */
639e82cf6aSEric Van Hensbergen 	Opt_err
649e82cf6aSEric Van Hensbergen };
659e82cf6aSEric Van Hensbergen 
66a447c093SSteven Whitehouse static const match_table_t tokens = {
679e2f6688SEric Van Hensbergen 	{Opt_debug, "debug=%x"},
68bd32b82dSLatchesar Ionkov 	{Opt_dfltuid, "dfltuid=%u"},
69bd32b82dSLatchesar Ionkov 	{Opt_dfltgid, "dfltgid=%u"},
709e82cf6aSEric Van Hensbergen 	{Opt_afid, "afid=%u"},
7167543e50SEric Van Hensbergen 	{Opt_uname, "uname=%s"},
729e82cf6aSEric Van Hensbergen 	{Opt_remotename, "aname=%s"},
739e82cf6aSEric Van Hensbergen 	{Opt_nodevmap, "nodevmap"},
7460e78d2cSAbhishek Kulkarni 	{Opt_cache, "cache=%s"},
75e03abc0cSEric Van Hensbergen 	{Opt_cache_loose, "loose"},
7660e78d2cSAbhishek Kulkarni 	{Opt_fscache, "fscache"},
77fb89b45cSDominique Martinet 	{Opt_mmap, "mmap"},
7860e78d2cSAbhishek Kulkarni 	{Opt_cachetag, "cachetag=%s"},
79ba17674fSLatchesar Ionkov 	{Opt_access, "access=%s"},
80e782ef71SVenkateswararao Jujjuri (JV) 	{Opt_posixacl, "posixacl"},
819e82cf6aSEric Van Hensbergen 	{Opt_err, NULL}
829e82cf6aSEric Van Hensbergen };
839e82cf6aSEric Van Hensbergen 
84a2dd43bbSPrem Karat /* Interpret mount options for cache mode */
85a2dd43bbSPrem Karat static int get_cache_mode(char *s)
86a2dd43bbSPrem Karat {
87a2dd43bbSPrem Karat 	int version = -EINVAL;
88a2dd43bbSPrem Karat 
89a2dd43bbSPrem Karat 	if (!strcmp(s, "loose")) {
90a2dd43bbSPrem Karat 		version = CACHE_LOOSE;
915d385153SJoe Perches 		p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
92a2dd43bbSPrem Karat 	} else if (!strcmp(s, "fscache")) {
93a2dd43bbSPrem Karat 		version = CACHE_FSCACHE;
945d385153SJoe Perches 		p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
95fb89b45cSDominique Martinet 	} else if (!strcmp(s, "mmap")) {
96fb89b45cSDominique Martinet 		version = CACHE_MMAP;
97fb89b45cSDominique Martinet 		p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
98a2dd43bbSPrem Karat 	} else if (!strcmp(s, "none")) {
99a2dd43bbSPrem Karat 		version = CACHE_NONE;
1005d385153SJoe Perches 		p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
101a2dd43bbSPrem Karat 	} else
1025d385153SJoe Perches 		pr_info("Unknown Cache mode %s\n", s);
103a2dd43bbSPrem Karat 	return version;
104a2dd43bbSPrem Karat }
105a2dd43bbSPrem Karat 
1069e82cf6aSEric Van Hensbergen /**
1079e82cf6aSEric Van Hensbergen  * v9fs_parse_options - parse mount options into session structure
1089e82cf6aSEric Van Hensbergen  * @v9ses: existing v9fs session information
1099e82cf6aSEric Van Hensbergen  *
110ab31267dSJim Meyering  * Return 0 upon success, -ERRNO upon failure.
1119e82cf6aSEric Van Hensbergen  */
1129e82cf6aSEric Van Hensbergen 
1134b53e4b5SAbhishek Kulkarni static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
1149e82cf6aSEric Van Hensbergen {
115d8c8a9e3SEric Van Hensbergen 	char *options, *tmp_options;
1169e82cf6aSEric Van Hensbergen 	substring_t args[MAX_OPT_ARGS];
117a80d923eSEric Van Hensbergen 	char *p;
1188a0dc95fSEric Van Hensbergen 	int option = 0;
119ba17674fSLatchesar Ionkov 	char *s, *e;
120ab31267dSJim Meyering 	int ret = 0;
1219e82cf6aSEric Van Hensbergen 
1229e82cf6aSEric Van Hensbergen 	/* setup defaults */
1239e82cf6aSEric Van Hensbergen 	v9ses->afid = ~0;
1249e82cf6aSEric Van Hensbergen 	v9ses->debug = 0;
125a2dd43bbSPrem Karat 	v9ses->cache = CACHE_NONE;
12660e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
12760e78d2cSAbhishek Kulkarni 	v9ses->cachetag = NULL;
12860e78d2cSAbhishek Kulkarni #endif
1299e82cf6aSEric Van Hensbergen 
1304b53e4b5SAbhishek Kulkarni 	if (!opts)
131ab31267dSJim Meyering 		return 0;
1329e82cf6aSEric Van Hensbergen 
133d8c8a9e3SEric Van Hensbergen 	tmp_options = kstrdup(opts, GFP_KERNEL);
134bf2d29c6SEric Van Hensbergen 	if (!tmp_options) {
135bf2d29c6SEric Van Hensbergen 		ret = -ENOMEM;
13660e78d2cSAbhishek Kulkarni 		goto fail_option_alloc;
137bf2d29c6SEric Van Hensbergen 	}
138d8c8a9e3SEric Van Hensbergen 	options = tmp_options;
139ab31267dSJim Meyering 
1409e82cf6aSEric Van Hensbergen 	while ((p = strsep(&options, ",")) != NULL) {
1414d5077f1SAneesh Kumar K.V 		int token, r;
1429e82cf6aSEric Van Hensbergen 		if (!*p)
1439e82cf6aSEric Van Hensbergen 			continue;
1449e82cf6aSEric Van Hensbergen 		token = match_token(p, tokens, args);
1454d5077f1SAneesh Kumar K.V 		switch (token) {
1464d5077f1SAneesh Kumar K.V 		case Opt_debug:
1474d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
148ab31267dSJim Meyering 			if (r < 0) {
1495d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
1509e82cf6aSEric Van Hensbergen 					 "integer field, but no integer?\n");
151ab31267dSJim Meyering 				ret = r;
1529e82cf6aSEric Van Hensbergen 				continue;
1539e82cf6aSEric Van Hensbergen 			}
1549e2f6688SEric Van Hensbergen 			v9ses->debug = option;
15510fa16e7SEric Van Hensbergen #ifdef CONFIG_NET_9P_DEBUG
1569e2f6688SEric Van Hensbergen 			p9_debug_level = option;
15710fa16e7SEric Van Hensbergen #endif
1589e2f6688SEric Van Hensbergen 			break;
1598a0dc95fSEric Van Hensbergen 
160bd32b82dSLatchesar Ionkov 		case Opt_dfltuid:
1614d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
1624d5077f1SAneesh Kumar K.V 			if (r < 0) {
1635d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
1644d5077f1SAneesh Kumar K.V 					 "integer field, but no integer?\n");
1654d5077f1SAneesh Kumar K.V 				ret = r;
1664d5077f1SAneesh Kumar K.V 				continue;
1674d5077f1SAneesh Kumar K.V 			}
16876ed23a5SEric W. Biederman 			v9ses->dfltuid = make_kuid(current_user_ns(), option);
16976ed23a5SEric W. Biederman 			if (!uid_valid(v9ses->dfltuid)) {
17076ed23a5SEric W. Biederman 				p9_debug(P9_DEBUG_ERROR,
17176ed23a5SEric W. Biederman 					 "uid field, but not a uid?\n");
17276ed23a5SEric W. Biederman 				ret = -EINVAL;
17376ed23a5SEric W. Biederman 				continue;
17476ed23a5SEric W. Biederman 			}
1759e82cf6aSEric Van Hensbergen 			break;
176bd32b82dSLatchesar Ionkov 		case Opt_dfltgid:
1774d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
1784d5077f1SAneesh Kumar K.V 			if (r < 0) {
1795d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
1804d5077f1SAneesh Kumar K.V 					 "integer field, but no integer?\n");
1814d5077f1SAneesh Kumar K.V 				ret = r;
1824d5077f1SAneesh Kumar K.V 				continue;
1834d5077f1SAneesh Kumar K.V 			}
18476ed23a5SEric W. Biederman 			v9ses->dfltgid = make_kgid(current_user_ns(), option);
18576ed23a5SEric W. Biederman 			if (!gid_valid(v9ses->dfltgid)) {
18676ed23a5SEric W. Biederman 				p9_debug(P9_DEBUG_ERROR,
18776ed23a5SEric W. Biederman 					 "gid field, but not a gid?\n");
18876ed23a5SEric W. Biederman 				ret = -EINVAL;
18976ed23a5SEric W. Biederman 				continue;
19076ed23a5SEric W. Biederman 			}
1919e82cf6aSEric Van Hensbergen 			break;
1929e82cf6aSEric Van Hensbergen 		case Opt_afid:
1934d5077f1SAneesh Kumar K.V 			r = match_int(&args[0], &option);
1944d5077f1SAneesh Kumar K.V 			if (r < 0) {
1955d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
1964d5077f1SAneesh Kumar K.V 					 "integer field, but no integer?\n");
1974d5077f1SAneesh Kumar K.V 				ret = r;
1984d5077f1SAneesh Kumar K.V 				continue;
1994d5077f1SAneesh Kumar K.V 			}
2009e82cf6aSEric Van Hensbergen 			v9ses->afid = option;
2019e82cf6aSEric Van Hensbergen 			break;
20267543e50SEric Van Hensbergen 		case Opt_uname:
203e549c133SJeff Layton 			kfree(v9ses->uname);
204e549c133SJeff Layton 			v9ses->uname = match_strdup(&args[0]);
205e549c133SJeff Layton 			if (!v9ses->uname) {
206e549c133SJeff Layton 				ret = -ENOMEM;
207e549c133SJeff Layton 				goto free_and_return;
208e549c133SJeff Layton 			}
2099e82cf6aSEric Van Hensbergen 			break;
2109e82cf6aSEric Van Hensbergen 		case Opt_remotename:
211e549c133SJeff Layton 			kfree(v9ses->aname);
212e549c133SJeff Layton 			v9ses->aname = match_strdup(&args[0]);
213e549c133SJeff Layton 			if (!v9ses->aname) {
214e549c133SJeff Layton 				ret = -ENOMEM;
215e549c133SJeff Layton 				goto free_and_return;
216e549c133SJeff Layton 			}
2179e82cf6aSEric Van Hensbergen 			break;
2189e82cf6aSEric Van Hensbergen 		case Opt_nodevmap:
2199e82cf6aSEric Van Hensbergen 			v9ses->nodev = 1;
2209e82cf6aSEric Van Hensbergen 			break;
221e03abc0cSEric Van Hensbergen 		case Opt_cache_loose:
222e03abc0cSEric Van Hensbergen 			v9ses->cache = CACHE_LOOSE;
223e03abc0cSEric Van Hensbergen 			break;
22460e78d2cSAbhishek Kulkarni 		case Opt_fscache:
22560e78d2cSAbhishek Kulkarni 			v9ses->cache = CACHE_FSCACHE;
22660e78d2cSAbhishek Kulkarni 			break;
227fb89b45cSDominique Martinet 		case Opt_mmap:
228fb89b45cSDominique Martinet 			v9ses->cache = CACHE_MMAP;
229fb89b45cSDominique Martinet 			break;
23060e78d2cSAbhishek Kulkarni 		case Opt_cachetag:
23160e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
23260e78d2cSAbhishek Kulkarni 			v9ses->cachetag = match_strdup(&args[0]);
23360e78d2cSAbhishek Kulkarni #endif
23460e78d2cSAbhishek Kulkarni 			break;
23560e78d2cSAbhishek Kulkarni 		case Opt_cache:
23660e78d2cSAbhishek Kulkarni 			s = match_strdup(&args[0]);
237bf2d29c6SEric Van Hensbergen 			if (!s) {
238bf2d29c6SEric Van Hensbergen 				ret = -ENOMEM;
2395d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
240bf2d29c6SEric Van Hensbergen 					 "problem allocating copy of cache arg\n");
241bf2d29c6SEric Van Hensbergen 				goto free_and_return;
242bf2d29c6SEric Van Hensbergen 			}
243a2dd43bbSPrem Karat 			ret = get_cache_mode(s);
244a2dd43bbSPrem Karat 			if (ret == -EINVAL) {
245a2dd43bbSPrem Karat 				kfree(s);
246a2dd43bbSPrem Karat 				goto free_and_return;
247a2dd43bbSPrem Karat 			}
24860e78d2cSAbhishek Kulkarni 
249a2dd43bbSPrem Karat 			v9ses->cache = ret;
25060e78d2cSAbhishek Kulkarni 			kfree(s);
25160e78d2cSAbhishek Kulkarni 			break;
252ba17674fSLatchesar Ionkov 
253ba17674fSLatchesar Ionkov 		case Opt_access:
254ba17674fSLatchesar Ionkov 			s = match_strdup(&args[0]);
255bf2d29c6SEric Van Hensbergen 			if (!s) {
256bf2d29c6SEric Van Hensbergen 				ret = -ENOMEM;
2575d385153SJoe Perches 				p9_debug(P9_DEBUG_ERROR,
258bf2d29c6SEric Van Hensbergen 					 "problem allocating copy of access arg\n");
259bf2d29c6SEric Van Hensbergen 				goto free_and_return;
260bf2d29c6SEric Van Hensbergen 			}
26160e78d2cSAbhishek Kulkarni 
262ba17674fSLatchesar Ionkov 			v9ses->flags &= ~V9FS_ACCESS_MASK;
263ba17674fSLatchesar Ionkov 			if (strcmp(s, "user") == 0)
264ba17674fSLatchesar Ionkov 				v9ses->flags |= V9FS_ACCESS_USER;
265ba17674fSLatchesar Ionkov 			else if (strcmp(s, "any") == 0)
266ba17674fSLatchesar Ionkov 				v9ses->flags |= V9FS_ACCESS_ANY;
26776381a42SAneesh Kumar K.V 			else if (strcmp(s, "client") == 0) {
26876381a42SAneesh Kumar K.V 				v9ses->flags |= V9FS_ACCESS_CLIENT;
26976381a42SAneesh Kumar K.V 			} else {
27076ed23a5SEric W. Biederman 				uid_t uid;
271ba17674fSLatchesar Ionkov 				v9ses->flags |= V9FS_ACCESS_SINGLE;
27276ed23a5SEric W. Biederman 				uid = simple_strtoul(s, &e, 10);
273a2dd43bbSPrem Karat 				if (*e != '\0') {
274a2dd43bbSPrem Karat 					ret = -EINVAL;
2755d385153SJoe Perches 					pr_info("Unknown access argument %s\n",
2765d385153SJoe Perches 						s);
277a2dd43bbSPrem Karat 					kfree(s);
278a2dd43bbSPrem Karat 					goto free_and_return;
279ba17674fSLatchesar Ionkov 				}
28076ed23a5SEric W. Biederman 				v9ses->uid = make_kuid(current_user_ns(), uid);
28176ed23a5SEric W. Biederman 				if (!uid_valid(v9ses->uid)) {
28276ed23a5SEric W. Biederman 					ret = -EINVAL;
28376ed23a5SEric W. Biederman 					pr_info("Uknown uid %s\n", s);
28476ed23a5SEric W. Biederman 					kfree(s);
28576ed23a5SEric W. Biederman 					goto free_and_return;
28676ed23a5SEric W. Biederman 				}
287a2dd43bbSPrem Karat 			}
288a2dd43bbSPrem Karat 
2890a976297SAdrian Bunk 			kfree(s);
290ba17674fSLatchesar Ionkov 			break;
291ba17674fSLatchesar Ionkov 
292e782ef71SVenkateswararao Jujjuri (JV) 		case Opt_posixacl:
293e782ef71SVenkateswararao Jujjuri (JV) #ifdef CONFIG_9P_FS_POSIX_ACL
294e782ef71SVenkateswararao Jujjuri (JV) 			v9ses->flags |= V9FS_POSIX_ACL;
295e782ef71SVenkateswararao Jujjuri (JV) #else
2965d385153SJoe Perches 			p9_debug(P9_DEBUG_ERROR,
2975d385153SJoe Perches 				 "Not defined CONFIG_9P_FS_POSIX_ACL. Ignoring posixacl option\n");
298e782ef71SVenkateswararao Jujjuri (JV) #endif
299e782ef71SVenkateswararao Jujjuri (JV) 			break;
300e782ef71SVenkateswararao Jujjuri (JV) 
3019e82cf6aSEric Van Hensbergen 		default:
3029e82cf6aSEric Van Hensbergen 			continue;
3039e82cf6aSEric Van Hensbergen 		}
3049e82cf6aSEric Van Hensbergen 	}
305d8c8a9e3SEric Van Hensbergen 
306bf2d29c6SEric Van Hensbergen free_and_return:
307d8c8a9e3SEric Van Hensbergen 	kfree(tmp_options);
30860e78d2cSAbhishek Kulkarni fail_option_alloc:
309bf2d29c6SEric Van Hensbergen 	return ret;
3109e82cf6aSEric Van Hensbergen }
3119e82cf6aSEric Van Hensbergen 
3129e82cf6aSEric Van Hensbergen /**
3139e82cf6aSEric Van Hensbergen  * v9fs_session_init - initialize session
3149e82cf6aSEric Van Hensbergen  * @v9ses: session information structure
3159e82cf6aSEric Van Hensbergen  * @dev_name: device being mounted
3169e82cf6aSEric Van Hensbergen  * @data: options
3179e82cf6aSEric Van Hensbergen  *
3189e82cf6aSEric Van Hensbergen  */
3199e82cf6aSEric Van Hensbergen 
320bd238fb4SLatchesar Ionkov struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
3219e82cf6aSEric Van Hensbergen 		  const char *dev_name, char *data)
3229e82cf6aSEric Van Hensbergen {
323bd238fb4SLatchesar Ionkov 	struct p9_fid *fid;
324412a19b6STejun Heo 	int rc = -ENOMEM;
3259e82cf6aSEric Van Hensbergen 
326e549c133SJeff Layton 	v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
327ba17674fSLatchesar Ionkov 	if (!v9ses->uname)
328412a19b6STejun Heo 		goto err_names;
3299e82cf6aSEric Van Hensbergen 
330e549c133SJeff Layton 	v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
331412a19b6STejun Heo 	if (!v9ses->aname)
332412a19b6STejun Heo 		goto err_names;
333a534c8d1SAneesh Kumar K.V 	init_rwsem(&v9ses->rename_sem);
3349e82cf6aSEric Van Hensbergen 
335b4caecd4SChristoph Hellwig 	rc = bdi_setup_and_register(&v9ses->bdi, "9p");
336412a19b6STejun Heo 	if (rc)
337412a19b6STejun Heo 		goto err_names;
33860e78d2cSAbhishek Kulkarni 
33976ed23a5SEric W. Biederman 	v9ses->uid = INVALID_UID;
340bd32b82dSLatchesar Ionkov 	v9ses->dfltuid = V9FS_DEFUID;
341bd32b82dSLatchesar Ionkov 	v9ses->dfltgid = V9FS_DEFGID;
342ab31267dSJim Meyering 
3434b53e4b5SAbhishek Kulkarni 	v9ses->clnt = p9_client_create(dev_name, data);
344bd238fb4SLatchesar Ionkov 	if (IS_ERR(v9ses->clnt)) {
345412a19b6STejun Heo 		rc = PTR_ERR(v9ses->clnt);
3465d385153SJoe Perches 		p9_debug(P9_DEBUG_ERROR, "problem initializing 9p client\n");
347412a19b6STejun Heo 		goto err_bdi;
3489e82cf6aSEric Van Hensbergen 	}
3499e82cf6aSEric Van Hensbergen 
3506752a1ebSVenkateswararao Jujjuri (JV) 	v9ses->flags = V9FS_ACCESS_USER;
3516752a1ebSVenkateswararao Jujjuri (JV) 
3526752a1ebSVenkateswararao Jujjuri (JV) 	if (p9_is_proto_dotl(v9ses->clnt)) {
3536752a1ebSVenkateswararao Jujjuri (JV) 		v9ses->flags = V9FS_ACCESS_CLIENT;
354476ada04SSripathi Kodi 		v9ses->flags |= V9FS_PROTO_2000L;
3556752a1ebSVenkateswararao Jujjuri (JV) 	} else if (p9_is_proto_dotu(v9ses->clnt)) {
356476ada04SSripathi Kodi 		v9ses->flags |= V9FS_PROTO_2000U;
3576752a1ebSVenkateswararao Jujjuri (JV) 	}
3586752a1ebSVenkateswararao Jujjuri (JV) 
3596752a1ebSVenkateswararao Jujjuri (JV) 	rc = v9fs_parse_options(v9ses, data);
360412a19b6STejun Heo 	if (rc < 0)
361412a19b6STejun Heo 		goto err_clnt;
362ba17674fSLatchesar Ionkov 
363fbedadc1SEric Van Hensbergen 	v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
3648a0dc95fSEric Van Hensbergen 
36576381a42SAneesh Kumar K.V 	if (!v9fs_proto_dotl(v9ses) &&
36676381a42SAneesh Kumar K.V 	    ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
36776381a42SAneesh Kumar K.V 		/*
36876381a42SAneesh Kumar K.V 		 * We support ACCESS_CLIENT only for dotl.
36976381a42SAneesh Kumar K.V 		 * Fall back to ACCESS_USER
37076381a42SAneesh Kumar K.V 		 */
37176381a42SAneesh Kumar K.V 		v9ses->flags &= ~V9FS_ACCESS_MASK;
37276381a42SAneesh Kumar K.V 		v9ses->flags |= V9FS_ACCESS_USER;
37376381a42SAneesh Kumar K.V 	}
37476381a42SAneesh Kumar K.V 	/*FIXME !! */
375ba17674fSLatchesar Ionkov 	/* for legacy mode, fall back to V9FS_ACCESS_ANY */
3769ffaf63eSAneesh Kumar K.V 	if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
377ba17674fSLatchesar Ionkov 		((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
378ba17674fSLatchesar Ionkov 
379ba17674fSLatchesar Ionkov 		v9ses->flags &= ~V9FS_ACCESS_MASK;
380ba17674fSLatchesar Ionkov 		v9ses->flags |= V9FS_ACCESS_ANY;
38176ed23a5SEric W. Biederman 		v9ses->uid = INVALID_UID;
382ba17674fSLatchesar Ionkov 	}
383e782ef71SVenkateswararao Jujjuri (JV) 	if (!v9fs_proto_dotl(v9ses) ||
384e782ef71SVenkateswararao Jujjuri (JV) 		!((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
385e782ef71SVenkateswararao Jujjuri (JV) 		/*
386e782ef71SVenkateswararao Jujjuri (JV) 		 * We support ACL checks on clinet only if the protocol is
387e782ef71SVenkateswararao Jujjuri (JV) 		 * 9P2000.L and access is V9FS_ACCESS_CLIENT.
388e782ef71SVenkateswararao Jujjuri (JV) 		 */
389e782ef71SVenkateswararao Jujjuri (JV) 		v9ses->flags &= ~V9FS_ACL_MASK;
390e782ef71SVenkateswararao Jujjuri (JV) 	}
391ba17674fSLatchesar Ionkov 
392f791f7c5SEric W. Biederman 	fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
393ba17674fSLatchesar Ionkov 							v9ses->aname);
394bd238fb4SLatchesar Ionkov 	if (IS_ERR(fid)) {
395412a19b6STejun Heo 		rc = PTR_ERR(fid);
3965d385153SJoe Perches 		p9_debug(P9_DEBUG_ERROR, "cannot attach\n");
397412a19b6STejun Heo 		goto err_clnt;
3989e82cf6aSEric Van Hensbergen 	}
3999e82cf6aSEric Van Hensbergen 
400ba17674fSLatchesar Ionkov 	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
401ba17674fSLatchesar Ionkov 		fid->uid = v9ses->uid;
402ba17674fSLatchesar Ionkov 	else
403b4642556SEric W. Biederman 		fid->uid = INVALID_UID;
404ba17674fSLatchesar Ionkov 
40560e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
40660e78d2cSAbhishek Kulkarni 	/* register the session for caching */
40760e78d2cSAbhishek Kulkarni 	v9fs_cache_session_get_cookie(v9ses);
40860e78d2cSAbhishek Kulkarni #endif
409412a19b6STejun Heo 	spin_lock(&v9fs_sessionlist_lock);
410412a19b6STejun Heo 	list_add(&v9ses->slist, &v9fs_sessionlist);
411412a19b6STejun Heo 	spin_unlock(&v9fs_sessionlist_lock);
41260e78d2cSAbhishek Kulkarni 
413bd238fb4SLatchesar Ionkov 	return fid;
4149e82cf6aSEric Van Hensbergen 
415412a19b6STejun Heo err_clnt:
416412a19b6STejun Heo 	p9_client_destroy(v9ses->clnt);
417412a19b6STejun Heo err_bdi:
4180ed07ddbSJens Axboe 	bdi_destroy(&v9ses->bdi);
419412a19b6STejun Heo err_names:
420412a19b6STejun Heo 	kfree(v9ses->uname);
421412a19b6STejun Heo 	kfree(v9ses->aname);
422412a19b6STejun Heo 	return ERR_PTR(rc);
4239e82cf6aSEric Van Hensbergen }
4249e82cf6aSEric Van Hensbergen 
4259e82cf6aSEric Van Hensbergen /**
4269e82cf6aSEric Van Hensbergen  * v9fs_session_close - shutdown a session
4279e82cf6aSEric Van Hensbergen  * @v9ses: session information structure
4289e82cf6aSEric Van Hensbergen  *
4299e82cf6aSEric Van Hensbergen  */
4309e82cf6aSEric Van Hensbergen 
4319e82cf6aSEric Van Hensbergen void v9fs_session_close(struct v9fs_session_info *v9ses)
4329e82cf6aSEric Van Hensbergen {
433bd238fb4SLatchesar Ionkov 	if (v9ses->clnt) {
434bd238fb4SLatchesar Ionkov 		p9_client_destroy(v9ses->clnt);
435bd238fb4SLatchesar Ionkov 		v9ses->clnt = NULL;
4363cf6429aSLatchesar Ionkov 	}
4379e82cf6aSEric Van Hensbergen 
43860e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
43960e78d2cSAbhishek Kulkarni 	if (v9ses->fscache) {
44060e78d2cSAbhishek Kulkarni 		v9fs_cache_session_put_cookie(v9ses);
44160e78d2cSAbhishek Kulkarni 		kfree(v9ses->cachetag);
44260e78d2cSAbhishek Kulkarni 	}
44360e78d2cSAbhishek Kulkarni #endif
444e549c133SJeff Layton 	kfree(v9ses->uname);
445e549c133SJeff Layton 	kfree(v9ses->aname);
44660e78d2cSAbhishek Kulkarni 
4470ed07ddbSJens Axboe 	bdi_destroy(&v9ses->bdi);
4480ed07ddbSJens Axboe 
44960e78d2cSAbhishek Kulkarni 	spin_lock(&v9fs_sessionlist_lock);
45060e78d2cSAbhishek Kulkarni 	list_del(&v9ses->slist);
45160e78d2cSAbhishek Kulkarni 	spin_unlock(&v9fs_sessionlist_lock);
4529e82cf6aSEric Van Hensbergen }
4539e82cf6aSEric Van Hensbergen 
454322b329aSEric Van Hensbergen /**
455ee443996SEric Van Hensbergen  * v9fs_session_cancel - terminate a session
456ee443996SEric Van Hensbergen  * @v9ses: session to terminate
457ee443996SEric Van Hensbergen  *
458ee443996SEric Van Hensbergen  * mark transport as disconnected and cancel all pending requests.
459322b329aSEric Van Hensbergen  */
460ee443996SEric Van Hensbergen 
461322b329aSEric Van Hensbergen void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
4625d385153SJoe Perches 	p9_debug(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
463bd238fb4SLatchesar Ionkov 	p9_client_disconnect(v9ses->clnt);
464322b329aSEric Van Hensbergen }
465322b329aSEric Van Hensbergen 
4666d96d3abSAneesh Kumar K.V /**
4676d96d3abSAneesh Kumar K.V  * v9fs_session_begin_cancel - Begin terminate of a session
4686d96d3abSAneesh Kumar K.V  * @v9ses: session to terminate
4696d96d3abSAneesh Kumar K.V  *
4706d96d3abSAneesh Kumar K.V  * After this call we don't allow any request other than clunk.
4716d96d3abSAneesh Kumar K.V  */
4726d96d3abSAneesh Kumar K.V 
4736d96d3abSAneesh Kumar K.V void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
4746d96d3abSAneesh Kumar K.V {
4755d385153SJoe Perches 	p9_debug(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
4766d96d3abSAneesh Kumar K.V 	p9_client_begin_disconnect(v9ses->clnt);
4776d96d3abSAneesh Kumar K.V }
4786d96d3abSAneesh Kumar K.V 
4799e82cf6aSEric Van Hensbergen extern int v9fs_error_init(void);
4809e82cf6aSEric Van Hensbergen 
48160e78d2cSAbhishek Kulkarni static struct kobject *v9fs_kobj;
48260e78d2cSAbhishek Kulkarni 
48360e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
4849e82cf6aSEric Van Hensbergen /**
48560e78d2cSAbhishek Kulkarni  * caches_show - list caches associated with a session
48660e78d2cSAbhishek Kulkarni  *
48760e78d2cSAbhishek Kulkarni  * Returns the size of buffer written.
48860e78d2cSAbhishek Kulkarni  */
48960e78d2cSAbhishek Kulkarni 
49060e78d2cSAbhishek Kulkarni static ssize_t caches_show(struct kobject *kobj,
49160e78d2cSAbhishek Kulkarni 			   struct kobj_attribute *attr,
49260e78d2cSAbhishek Kulkarni 			   char *buf)
49360e78d2cSAbhishek Kulkarni {
49460e78d2cSAbhishek Kulkarni 	ssize_t n = 0, count = 0, limit = PAGE_SIZE;
49560e78d2cSAbhishek Kulkarni 	struct v9fs_session_info *v9ses;
49660e78d2cSAbhishek Kulkarni 
49760e78d2cSAbhishek Kulkarni 	spin_lock(&v9fs_sessionlist_lock);
49860e78d2cSAbhishek Kulkarni 	list_for_each_entry(v9ses, &v9fs_sessionlist, slist) {
49960e78d2cSAbhishek Kulkarni 		if (v9ses->cachetag) {
50060e78d2cSAbhishek Kulkarni 			n = snprintf(buf, limit, "%s\n", v9ses->cachetag);
50160e78d2cSAbhishek Kulkarni 			if (n < 0) {
50260e78d2cSAbhishek Kulkarni 				count = n;
50360e78d2cSAbhishek Kulkarni 				break;
50460e78d2cSAbhishek Kulkarni 			}
50560e78d2cSAbhishek Kulkarni 
50660e78d2cSAbhishek Kulkarni 			count += n;
50760e78d2cSAbhishek Kulkarni 			limit -= n;
50860e78d2cSAbhishek Kulkarni 		}
50960e78d2cSAbhishek Kulkarni 	}
51060e78d2cSAbhishek Kulkarni 
51160e78d2cSAbhishek Kulkarni 	spin_unlock(&v9fs_sessionlist_lock);
51260e78d2cSAbhishek Kulkarni 	return count;
51360e78d2cSAbhishek Kulkarni }
51460e78d2cSAbhishek Kulkarni 
51560e78d2cSAbhishek Kulkarni static struct kobj_attribute v9fs_attr_cache = __ATTR_RO(caches);
51660e78d2cSAbhishek Kulkarni #endif /* CONFIG_9P_FSCACHE */
51760e78d2cSAbhishek Kulkarni 
51860e78d2cSAbhishek Kulkarni static struct attribute *v9fs_attrs[] = {
51960e78d2cSAbhishek Kulkarni #ifdef CONFIG_9P_FSCACHE
52060e78d2cSAbhishek Kulkarni 	&v9fs_attr_cache.attr,
52160e78d2cSAbhishek Kulkarni #endif
52260e78d2cSAbhishek Kulkarni 	NULL,
52360e78d2cSAbhishek Kulkarni };
52460e78d2cSAbhishek Kulkarni 
52560e78d2cSAbhishek Kulkarni static struct attribute_group v9fs_attr_group = {
52660e78d2cSAbhishek Kulkarni 	.attrs = v9fs_attrs,
52760e78d2cSAbhishek Kulkarni };
52860e78d2cSAbhishek Kulkarni 
52960e78d2cSAbhishek Kulkarni /**
53060e78d2cSAbhishek Kulkarni  * v9fs_sysfs_init - Initialize the v9fs sysfs interface
53160e78d2cSAbhishek Kulkarni  *
53260e78d2cSAbhishek Kulkarni  */
53360e78d2cSAbhishek Kulkarni 
534bdbeacdeSFabian Frederick static int __init v9fs_sysfs_init(void)
53560e78d2cSAbhishek Kulkarni {
53660e78d2cSAbhishek Kulkarni 	v9fs_kobj = kobject_create_and_add("9p", fs_kobj);
53760e78d2cSAbhishek Kulkarni 	if (!v9fs_kobj)
53860e78d2cSAbhishek Kulkarni 		return -ENOMEM;
53960e78d2cSAbhishek Kulkarni 
54060e78d2cSAbhishek Kulkarni 	if (sysfs_create_group(v9fs_kobj, &v9fs_attr_group)) {
54160e78d2cSAbhishek Kulkarni 		kobject_put(v9fs_kobj);
54260e78d2cSAbhishek Kulkarni 		return -ENOMEM;
54360e78d2cSAbhishek Kulkarni 	}
54460e78d2cSAbhishek Kulkarni 
54560e78d2cSAbhishek Kulkarni 	return 0;
54660e78d2cSAbhishek Kulkarni }
54760e78d2cSAbhishek Kulkarni 
54860e78d2cSAbhishek Kulkarni /**
54960e78d2cSAbhishek Kulkarni  * v9fs_sysfs_cleanup - Unregister the v9fs sysfs interface
55060e78d2cSAbhishek Kulkarni  *
55160e78d2cSAbhishek Kulkarni  */
55260e78d2cSAbhishek Kulkarni 
55360e78d2cSAbhishek Kulkarni static void v9fs_sysfs_cleanup(void)
55460e78d2cSAbhishek Kulkarni {
55560e78d2cSAbhishek Kulkarni 	sysfs_remove_group(v9fs_kobj, &v9fs_attr_group);
55660e78d2cSAbhishek Kulkarni 	kobject_put(v9fs_kobj);
55760e78d2cSAbhishek Kulkarni }
55860e78d2cSAbhishek Kulkarni 
559a78ce05dSAneesh Kumar K.V static void v9fs_inode_init_once(void *foo)
560a78ce05dSAneesh Kumar K.V {
561a78ce05dSAneesh Kumar K.V 	struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
562a78ce05dSAneesh Kumar K.V #ifdef CONFIG_9P_FSCACHE
563a78ce05dSAneesh Kumar K.V 	v9inode->fscache = NULL;
564a78ce05dSAneesh Kumar K.V #endif
565fd2421f5SAneesh Kumar K.V 	memset(&v9inode->qid, 0, sizeof(v9inode->qid));
566a78ce05dSAneesh Kumar K.V 	inode_init_once(&v9inode->vfs_inode);
567a78ce05dSAneesh Kumar K.V }
568a78ce05dSAneesh Kumar K.V 
569a78ce05dSAneesh Kumar K.V /**
570a78ce05dSAneesh Kumar K.V  * v9fs_init_inode_cache - initialize a cache for 9P
571a78ce05dSAneesh Kumar K.V  * Returns 0 on success.
572a78ce05dSAneesh Kumar K.V  */
573a78ce05dSAneesh Kumar K.V static int v9fs_init_inode_cache(void)
574a78ce05dSAneesh Kumar K.V {
575a78ce05dSAneesh Kumar K.V 	v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache",
576a78ce05dSAneesh Kumar K.V 					  sizeof(struct v9fs_inode),
577a78ce05dSAneesh Kumar K.V 					  0, (SLAB_RECLAIM_ACCOUNT|
578a78ce05dSAneesh Kumar K.V 					      SLAB_MEM_SPREAD),
579a78ce05dSAneesh Kumar K.V 					  v9fs_inode_init_once);
580a78ce05dSAneesh Kumar K.V 	if (!v9fs_inode_cache)
581a78ce05dSAneesh Kumar K.V 		return -ENOMEM;
582a78ce05dSAneesh Kumar K.V 
583a78ce05dSAneesh Kumar K.V 	return 0;
584a78ce05dSAneesh Kumar K.V }
585a78ce05dSAneesh Kumar K.V 
586a78ce05dSAneesh Kumar K.V /**
587a78ce05dSAneesh Kumar K.V  * v9fs_destroy_inode_cache - destroy the cache of 9P inode
588a78ce05dSAneesh Kumar K.V  *
589a78ce05dSAneesh Kumar K.V  */
590a78ce05dSAneesh Kumar K.V static void v9fs_destroy_inode_cache(void)
591a78ce05dSAneesh Kumar K.V {
5928c0a8537SKirill A. Shutemov 	/*
5938c0a8537SKirill A. Shutemov 	 * Make sure all delayed rcu free inodes are flushed before we
5948c0a8537SKirill A. Shutemov 	 * destroy cache.
5958c0a8537SKirill A. Shutemov 	 */
5968c0a8537SKirill A. Shutemov 	rcu_barrier();
597a78ce05dSAneesh Kumar K.V 	kmem_cache_destroy(v9fs_inode_cache);
598a78ce05dSAneesh Kumar K.V }
599a78ce05dSAneesh Kumar K.V 
600a78ce05dSAneesh Kumar K.V static int v9fs_cache_register(void)
601a78ce05dSAneesh Kumar K.V {
602a78ce05dSAneesh Kumar K.V 	int ret;
603a78ce05dSAneesh Kumar K.V 	ret = v9fs_init_inode_cache();
604a78ce05dSAneesh Kumar K.V 	if (ret < 0)
605a78ce05dSAneesh Kumar K.V 		return ret;
606a78ce05dSAneesh Kumar K.V #ifdef CONFIG_9P_FSCACHE
6078061a6faSAl Viro 	ret = fscache_register_netfs(&v9fs_cache_netfs);
6088061a6faSAl Viro 	if (ret < 0)
6098061a6faSAl Viro 		v9fs_destroy_inode_cache();
610a78ce05dSAneesh Kumar K.V #endif
6118061a6faSAl Viro 	return ret;
612a78ce05dSAneesh Kumar K.V }
613a78ce05dSAneesh Kumar K.V 
614a78ce05dSAneesh Kumar K.V static void v9fs_cache_unregister(void)
615a78ce05dSAneesh Kumar K.V {
616a78ce05dSAneesh Kumar K.V 	v9fs_destroy_inode_cache();
617a78ce05dSAneesh Kumar K.V #ifdef CONFIG_9P_FSCACHE
618a78ce05dSAneesh Kumar K.V 	fscache_unregister_netfs(&v9fs_cache_netfs);
619a78ce05dSAneesh Kumar K.V #endif
620a78ce05dSAneesh Kumar K.V }
621a78ce05dSAneesh Kumar K.V 
62260e78d2cSAbhishek Kulkarni /**
62360e78d2cSAbhishek Kulkarni  * init_v9fs - Initialize module
6249e82cf6aSEric Van Hensbergen  *
6259e82cf6aSEric Van Hensbergen  */
6269e82cf6aSEric Van Hensbergen 
6279e82cf6aSEric Van Hensbergen static int __init init_v9fs(void)
6289e82cf6aSEric Van Hensbergen {
62960e78d2cSAbhishek Kulkarni 	int err;
6305d385153SJoe Perches 	pr_info("Installing v9fs 9p2000 file system support\n");
631a80d923eSEric Van Hensbergen 	/* TODO: Setup list of registered trasnport modules */
63260e78d2cSAbhishek Kulkarni 
63360e78d2cSAbhishek Kulkarni 	err = v9fs_cache_register();
63460e78d2cSAbhishek Kulkarni 	if (err < 0) {
6355d385153SJoe Perches 		pr_err("Failed to register v9fs for caching\n");
6362226a288SAl Viro 		return err;
63760e78d2cSAbhishek Kulkarni 	}
63860e78d2cSAbhishek Kulkarni 
63960e78d2cSAbhishek Kulkarni 	err = v9fs_sysfs_init();
64060e78d2cSAbhishek Kulkarni 	if (err < 0) {
6415d385153SJoe Perches 		pr_err("Failed to register with sysfs\n");
6422226a288SAl Viro 		goto out_cache;
6432226a288SAl Viro 	}
6442226a288SAl Viro 	err = register_filesystem(&v9fs_fs_type);
6452226a288SAl Viro 	if (err < 0) {
6462226a288SAl Viro 		pr_err("Failed to register filesystem\n");
64760e78d2cSAbhishek Kulkarni 		goto out_sysfs_cleanup;
64860e78d2cSAbhishek Kulkarni 	}
64960e78d2cSAbhishek Kulkarni 
65060e78d2cSAbhishek Kulkarni 	return 0;
65160e78d2cSAbhishek Kulkarni 
65260e78d2cSAbhishek Kulkarni out_sysfs_cleanup:
65360e78d2cSAbhishek Kulkarni 	v9fs_sysfs_cleanup();
65460e78d2cSAbhishek Kulkarni 
6552226a288SAl Viro out_cache:
6562226a288SAl Viro 	v9fs_cache_unregister();
65760e78d2cSAbhishek Kulkarni 
65860e78d2cSAbhishek Kulkarni 	return err;
6599e82cf6aSEric Van Hensbergen }
6609e82cf6aSEric Van Hensbergen 
6619e82cf6aSEric Van Hensbergen /**
66260e78d2cSAbhishek Kulkarni  * exit_v9fs - shutdown module
6639e82cf6aSEric Van Hensbergen  *
6649e82cf6aSEric Van Hensbergen  */
6659e82cf6aSEric Van Hensbergen 
6669e82cf6aSEric Van Hensbergen static void __exit exit_v9fs(void)
6679e82cf6aSEric Van Hensbergen {
66860e78d2cSAbhishek Kulkarni 	v9fs_sysfs_cleanup();
66960e78d2cSAbhishek Kulkarni 	v9fs_cache_unregister();
6709e82cf6aSEric Van Hensbergen 	unregister_filesystem(&v9fs_fs_type);
6719e82cf6aSEric Van Hensbergen }
6729e82cf6aSEric Van Hensbergen 
6739e82cf6aSEric Van Hensbergen module_init(init_v9fs)
6749e82cf6aSEric Van Hensbergen module_exit(exit_v9fs)
6759e82cf6aSEric Van Hensbergen 
676bd238fb4SLatchesar Ionkov MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
6779e82cf6aSEric Van Hensbergen MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
6789e82cf6aSEric Van Hensbergen MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
6799e82cf6aSEric Van Hensbergen MODULE_LICENSE("GPL");
680