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