1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 1998-2022 Erez Zadok
4 * Copyright (c) 2009 Shrikar Archak
5 * Copyright (c) 2003-2022 Stony Brook University
6 * Copyright (c) 2003-2022 The Research Foundation of SUNY
7 */
8 #include <linux/backing-dev-defs.h>
9 #include <linux/ratelimit.h>
10 #include <linux/slab.h>
11 #include <linux/parser.h>
12 #include "sharefs.h"
13
14 enum {
15 OPT_USER_ID,
16 OPT_ERR,
17 };
18
19 static match_table_t sharefs_tokens = {
20 { OPT_USER_ID, "user_id=%s" },
21 { OPT_ERR, NULL }
22 };
23
sharefs_parse_options(struct sharefs_sb_info * sbi,const char * data)24 int sharefs_parse_options(struct sharefs_sb_info *sbi, const char *data)
25 {
26 char *p = NULL;
27 char *name = NULL;
28 char *options = NULL;
29 char *options_src = NULL;
30 substring_t args[MAX_OPT_ARGS];
31 unsigned int user_id = 0;
32 int err = 0;
33
34 options = kstrdup(data, GFP_KERNEL);
35 if (data && !options) {
36 err = -ENOMEM;
37 goto out;
38 }
39 options_src = options;
40
41 while ((p = strsep(&options_src, ",")) != NULL) {
42 int token;
43
44 if (!*p)
45 continue;
46 args[0].to = args[0].from = NULL;
47 token = match_token(p, sharefs_tokens, args);
48
49 switch (token) {
50 case OPT_USER_ID:
51 name = match_strdup(&args[0]);
52 if (name) {
53 err = kstrtouint(name, 10, &user_id);
54 kfree(name);
55 name = NULL;
56 if (err)
57 goto out;
58 sbi->user_id = user_id;
59 }
60 break;
61 default:
62 err = -EINVAL;
63 goto out;
64 }
65 }
66 out:
67 kfree(options);
68
69 return err;
70 }
71
72 /*
73 * The inode cache is used with alloc_inode for both our inode info and the
74 * vfs inode.
75 */
76 static struct kmem_cache *sharefs_inode_cachep;
77
78 /* final actions when unmounting a file system */
sharefs_put_super(struct super_block * sb)79 static void sharefs_put_super(struct super_block *sb)
80 {
81 struct sharefs_sb_info *spd;
82 struct super_block *s;
83
84 spd = SHAREFS_SB(sb);
85 if (!spd)
86 return;
87
88 /* decrement lower super references */
89 s = sharefs_lower_super(sb);
90 sharefs_set_lower_super(sb, NULL);
91 atomic_dec(&s->s_active);
92
93 kfree(spd);
94 sb->s_fs_info = NULL;
95 }
96
sharefs_statfs(struct dentry * dentry,struct kstatfs * buf)97 static int sharefs_statfs(struct dentry *dentry, struct kstatfs *buf)
98 {
99 int err;
100 struct path lower_path;
101
102 sharefs_get_lower_path(dentry, &lower_path);
103 err = vfs_statfs(&lower_path, buf);
104 sharefs_put_lower_path(dentry, &lower_path);
105
106 /* set return buf to our f/s to avoid confusing user-level utils */
107 buf->f_type = SHAREFS_SUPER_MAGIC;
108
109 return err;
110 }
111
112 /*
113 * Called by iput() when the inode reference count reached zero
114 * and the inode is not hashed anywhere. Used to clear anything
115 * that needs to be, before the inode is completely destroyed and put
116 * on the inode free list.
117 */
sharefs_evict_inode(struct inode * inode)118 static void sharefs_evict_inode(struct inode *inode)
119 {
120 struct inode *lower_inode;
121
122 truncate_inode_pages(&inode->i_data, 0);
123 clear_inode(inode);
124 /*
125 * Decrement a reference to a lower_inode, which was incremented
126 * by our read_inode when it was created initially.
127 */
128 lower_inode = sharefs_lower_inode(inode);
129 sharefs_set_lower_inode(inode, NULL);
130 iput(lower_inode);
131 }
132
__sharefs_log(const char * level,const bool ratelimited,const char * function,const char * fmt,...)133 void __sharefs_log(const char *level, const bool ratelimited,
134 const char *function, const char *fmt, ...)
135 {
136 struct va_format vaf;
137 va_list args;
138
139 va_start(args, fmt);
140 vaf.fmt = fmt;
141 vaf.va = &args;
142 if (ratelimited)
143 printk_ratelimited("%s sharefs: %s() %pV\n", level,
144 function, &vaf);
145 else
146 printk("%s sharefs: %s() %pV\n", level, function, &vaf);
147 va_end(args);
148 }
149
sharefs_alloc_inode(struct super_block * sb)150 static struct inode *sharefs_alloc_inode(struct super_block *sb)
151 {
152 struct sharefs_inode_info *i;
153
154 i = kmem_cache_alloc(sharefs_inode_cachep, GFP_KERNEL);
155 if (!i)
156 return NULL;
157
158 /* memset everything up to the inode to 0 */
159 memset(i, 0, offsetof(struct sharefs_inode_info, vfs_inode));
160
161 atomic64_set(&i->vfs_inode.i_version, 1);
162 return &i->vfs_inode;
163 }
164
sharefs_destroy_inode(struct inode * inode)165 static void sharefs_destroy_inode(struct inode *inode)
166 {
167 kmem_cache_free(sharefs_inode_cachep, SHAREFS_I(inode));
168 }
169
170 /* sharefs inode cache constructor */
init_once(void * obj)171 static void init_once(void *obj)
172 {
173 struct sharefs_inode_info *i = obj;
174
175 inode_init_once(&i->vfs_inode);
176 }
177
sharefs_init_inode_cache(void)178 int sharefs_init_inode_cache(void)
179 {
180 int err = 0;
181
182 sharefs_inode_cachep =
183 kmem_cache_create("sharefs_inode_cache",
184 sizeof(struct sharefs_inode_info), 0,
185 SLAB_RECLAIM_ACCOUNT, init_once);
186 if (!sharefs_inode_cachep)
187 err = -ENOMEM;
188 return err;
189 }
190
191 /* sharefs inode cache destructor */
sharefs_destroy_inode_cache(void)192 void sharefs_destroy_inode_cache(void)
193 {
194 if (sharefs_inode_cachep)
195 kmem_cache_destroy(sharefs_inode_cachep);
196 }
197
198 const struct super_operations sharefs_sops = {
199 .put_super = sharefs_put_super,
200 .statfs = sharefs_statfs,
201 .evict_inode = sharefs_evict_inode,
202 .alloc_inode = sharefs_alloc_inode,
203 .destroy_inode = sharefs_destroy_inode,
204 };
205