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