blob: 72d89b957bb51e9420321ad83c8306eee8629246 [file] [log] [blame]
Daniel Campello35c9e242015-07-20 16:23:50 -07001/*
2 * fs/sdcardfs/super.c
3 *
4 * Copyright (c) 2013 Samsung Electronics Co. Ltd
5 * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
6 * Sunghwan Yun, Sungjong Seo
7 *
8 * This program has been developed as a stackable file system based on
9 * the WrapFS which written by
10 *
11 * Copyright (c) 1998-2011 Erez Zadok
12 * Copyright (c) 2009 Shrikar Archak
13 * Copyright (c) 2003-2011 Stony Brook University
14 * Copyright (c) 2003-2011 The Research Foundation of SUNY
15 *
16 * This file is dual licensed. It may be redistributed and/or modified
17 * under the terms of the Apache 2.0 License OR version 2 of the GNU
18 * General Public License.
19 */
20
21#include "sdcardfs.h"
22
23/*
24 * The inode cache is used with alloc_inode for both our inode info and the
25 * vfs inode.
26 */
27static struct kmem_cache *sdcardfs_inode_cachep;
28
Daniel Rosenberga56a1052017-05-15 14:03:15 -070029/*
30 * To support the top references, we must track some data separately.
31 * An sdcardfs_inode_info always has a reference to its data, and once set up,
32 * also has a reference to its top. The top may be itself, in which case it
33 * holds two references to its data. When top is changed, it takes a ref to the
34 * new data and then drops the ref to the old data.
35 */
36static struct kmem_cache *sdcardfs_inode_data_cachep;
37
38void data_release(struct kref *ref)
39{
40 struct sdcardfs_inode_data *data =
41 container_of(ref, struct sdcardfs_inode_data, refcount);
42
43 kmem_cache_free(sdcardfs_inode_data_cachep, data);
44}
45
Daniel Campello35c9e242015-07-20 16:23:50 -070046/* final actions when unmounting a file system */
47static void sdcardfs_put_super(struct super_block *sb)
48{
49 struct sdcardfs_sb_info *spd;
50 struct super_block *s;
51
52 spd = SDCARDFS_SB(sb);
53 if (!spd)
54 return;
55
Daniel Rosenberg5e024f62017-03-16 17:42:58 -070056 if (spd->obbpath_s) {
Daniel Campello35c9e242015-07-20 16:23:50 -070057 kfree(spd->obbpath_s);
58 path_put(&spd->obbpath);
59 }
60
61 /* decrement lower super references */
62 s = sdcardfs_lower_super(sb);
63 sdcardfs_set_lower_super(sb, NULL);
64 atomic_dec(&s->s_active);
65
Daniel Campello35c9e242015-07-20 16:23:50 -070066 kfree(spd);
67 sb->s_fs_info = NULL;
68}
69
70static int sdcardfs_statfs(struct dentry *dentry, struct kstatfs *buf)
71{
72 int err;
73 struct path lower_path;
74 u32 min_blocks;
75 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
76
77 sdcardfs_get_lower_path(dentry, &lower_path);
78 err = vfs_statfs(&lower_path, buf);
79 sdcardfs_put_lower_path(dentry, &lower_path);
80
81 if (sbi->options.reserved_mb) {
82 /* Invalid statfs informations. */
83 if (buf->f_bsize == 0) {
Daniel Rosenberg77ecf212017-03-16 17:46:13 -070084 pr_err("Returned block size is zero.\n");
Daniel Campello35c9e242015-07-20 16:23:50 -070085 return -EINVAL;
86 }
87
88 min_blocks = ((sbi->options.reserved_mb * 1024 * 1024)/buf->f_bsize);
89 buf->f_blocks -= min_blocks;
90
91 if (buf->f_bavail > min_blocks)
92 buf->f_bavail -= min_blocks;
93 else
94 buf->f_bavail = 0;
95
96 /* Make reserved blocks invisiable to media storage */
97 buf->f_bfree = buf->f_bavail;
98 }
99
100 /* set return buf to our f/s to avoid confusing user-level utils */
101 buf->f_type = SDCARDFS_SUPER_MAGIC;
102
103 return err;
104}
105
106/*
107 * @flags: numeric mount options
108 * @options: mount options string
109 */
110static int sdcardfs_remount_fs(struct super_block *sb, int *flags, char *options)
111{
112 int err = 0;
113
114 /*
115 * The VFS will take care of "ro" and "rw" flags among others. We
116 * can safely accept a few flags (RDONLY, MANDLOCK), and honor
117 * SILENT, but anything else left over is an error.
118 */
119 if ((*flags & ~(MS_RDONLY | MS_MANDLOCK | MS_SILENT)) != 0) {
Daniel Rosenberg77ecf212017-03-16 17:46:13 -0700120 pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
Daniel Campello35c9e242015-07-20 16:23:50 -0700121 err = -EINVAL;
122 }
123
124 return err;
125}
126
127/*
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700128 * @mnt: mount point we are remounting
129 * @sb: superblock we are remounting
130 * @flags: numeric mount options
131 * @options: mount options string
132 */
133static int sdcardfs_remount_fs2(struct vfsmount *mnt, struct super_block *sb,
134 int *flags, char *options)
135{
136 int err = 0;
137
138 /*
139 * The VFS will take care of "ro" and "rw" flags among others. We
140 * can safely accept a few flags (RDONLY, MANDLOCK), and honor
141 * SILENT, but anything else left over is an error.
142 */
143 if ((*flags & ~(MS_RDONLY | MS_MANDLOCK | MS_SILENT | MS_REMOUNT)) != 0) {
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700144 pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700145 err = -EINVAL;
146 }
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700147 pr_info("Remount options were %s for vfsmnt %p.\n", options, mnt);
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700148 err = parse_options_remount(sb, options, *flags & ~MS_SILENT, mnt->data);
149
150
151 return err;
152}
153
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700154static void *sdcardfs_clone_mnt_data(void *data)
155{
156 struct sdcardfs_vfsmount_options *opt = kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL);
157 struct sdcardfs_vfsmount_options *old = data;
158
159 if (!opt)
160 return NULL;
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700161 opt->gid = old->gid;
162 opt->mask = old->mask;
163 return opt;
164}
165
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700166static void sdcardfs_copy_mnt_data(void *data, void *newdata)
167{
168 struct sdcardfs_vfsmount_options *old = data;
169 struct sdcardfs_vfsmount_options *new = newdata;
170
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700171 old->gid = new->gid;
172 old->mask = new->mask;
173}
174
175/*
Daniel Campello35c9e242015-07-20 16:23:50 -0700176 * Called by iput() when the inode reference count reached zero
177 * and the inode is not hashed anywhere. Used to clear anything
178 * that needs to be, before the inode is completely destroyed and put
179 * on the inode free list.
180 */
181static void sdcardfs_evict_inode(struct inode *inode)
182{
183 struct inode *lower_inode;
184
185 truncate_inode_pages(&inode->i_data, 0);
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700186 set_top(SDCARDFS_I(inode), NULL);
Daniel Campellod1d080c2015-07-20 16:27:37 -0700187 clear_inode(inode);
Daniel Campello35c9e242015-07-20 16:23:50 -0700188 /*
189 * Decrement a reference to a lower_inode, which was incremented
190 * by our read_inode when it was created initially.
191 */
192 lower_inode = sdcardfs_lower_inode(inode);
193 sdcardfs_set_lower_inode(inode, NULL);
194 iput(lower_inode);
195}
196
197static struct inode *sdcardfs_alloc_inode(struct super_block *sb)
198{
199 struct sdcardfs_inode_info *i;
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700200 struct sdcardfs_inode_data *d;
Daniel Campello35c9e242015-07-20 16:23:50 -0700201
202 i = kmem_cache_alloc(sdcardfs_inode_cachep, GFP_KERNEL);
203 if (!i)
204 return NULL;
205
206 /* memset everything up to the inode to 0 */
207 memset(i, 0, offsetof(struct sdcardfs_inode_info, vfs_inode));
208
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700209 d = kmem_cache_alloc(sdcardfs_inode_data_cachep,
210 GFP_KERNEL | __GFP_ZERO);
211 if (!d) {
212 kmem_cache_free(sdcardfs_inode_cachep, i);
213 return NULL;
214 }
215
216 i->data = d;
217 kref_init(&d->refcount);
Daniel Rosenbergc9cd4d32018-02-01 16:52:22 -0800218 i->top_data = d;
219 spin_lock_init(&i->top_lock);
220 kref_get(&d->refcount);
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700221
Daniel Campello35c9e242015-07-20 16:23:50 -0700222 i->vfs_inode.i_version = 1;
223 return &i->vfs_inode;
224}
225
Gao Xiang13fb0932017-05-10 23:01:15 +0800226static void i_callback(struct rcu_head *head)
227{
228 struct inode *inode = container_of(head, struct inode, i_rcu);
229
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700230 release_own_data(SDCARDFS_I(inode));
Gao Xiang13fb0932017-05-10 23:01:15 +0800231 kmem_cache_free(sdcardfs_inode_cachep, SDCARDFS_I(inode));
232}
233
Daniel Campello35c9e242015-07-20 16:23:50 -0700234static void sdcardfs_destroy_inode(struct inode *inode)
235{
Gao Xiang13fb0932017-05-10 23:01:15 +0800236 call_rcu(&inode->i_rcu, i_callback);
Daniel Campello35c9e242015-07-20 16:23:50 -0700237}
238
239/* sdcardfs inode cache constructor */
240static void init_once(void *obj)
241{
242 struct sdcardfs_inode_info *i = obj;
243
244 inode_init_once(&i->vfs_inode);
245}
246
247int sdcardfs_init_inode_cache(void)
248{
Daniel Campello35c9e242015-07-20 16:23:50 -0700249 sdcardfs_inode_cachep =
250 kmem_cache_create("sdcardfs_inode_cache",
251 sizeof(struct sdcardfs_inode_info), 0,
252 SLAB_RECLAIM_ACCOUNT, init_once);
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700253
Daniel Campello35c9e242015-07-20 16:23:50 -0700254 if (!sdcardfs_inode_cachep)
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700255 return -ENOMEM;
256
257 sdcardfs_inode_data_cachep =
258 kmem_cache_create("sdcardfs_inode_data_cache",
259 sizeof(struct sdcardfs_inode_data), 0,
260 SLAB_RECLAIM_ACCOUNT, NULL);
261 if (!sdcardfs_inode_data_cachep) {
262 kmem_cache_destroy(sdcardfs_inode_cachep);
263 return -ENOMEM;
264 }
265
266 return 0;
Daniel Campello35c9e242015-07-20 16:23:50 -0700267}
268
269/* sdcardfs inode cache destructor */
270void sdcardfs_destroy_inode_cache(void)
271{
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700272 kmem_cache_destroy(sdcardfs_inode_data_cachep);
Daniel Rosenbergb6704a82017-03-21 16:29:13 -0700273 kmem_cache_destroy(sdcardfs_inode_cachep);
Daniel Campello35c9e242015-07-20 16:23:50 -0700274}
275
276/*
277 * Used only in nfs, to kill any pending RPC tasks, so that subsequent
278 * code can actually succeed and won't leave tasks that need handling.
279 */
280static void sdcardfs_umount_begin(struct super_block *sb)
281{
282 struct super_block *lower_sb;
283
284 lower_sb = sdcardfs_lower_super(sb);
285 if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin)
286 lower_sb->s_op->umount_begin(lower_sb);
287}
288
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700289static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
290 struct dentry *root)
Daniel Campello35c9e242015-07-20 16:23:50 -0700291{
Daniel Campellod1d080c2015-07-20 16:27:37 -0700292 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(root->d_sb);
Daniel Campello35c9e242015-07-20 16:23:50 -0700293 struct sdcardfs_mount_options *opts = &sbi->options;
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700294 struct sdcardfs_vfsmount_options *vfsopts = mnt->data;
Daniel Campello35c9e242015-07-20 16:23:50 -0700295
296 if (opts->fs_low_uid != 0)
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700297 seq_printf(m, ",fsuid=%u", opts->fs_low_uid);
Daniel Campello35c9e242015-07-20 16:23:50 -0700298 if (opts->fs_low_gid != 0)
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700299 seq_printf(m, ",fsgid=%u", opts->fs_low_gid);
300 if (vfsopts->gid != 0)
301 seq_printf(m, ",gid=%u", vfsopts->gid);
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800302 if (opts->multiuser)
Daniel Rosenberg6ae39e82017-03-21 17:27:40 -0700303 seq_puts(m, ",multiuser");
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700304 if (vfsopts->mask)
305 seq_printf(m, ",mask=%u", vfsopts->mask);
306 if (opts->fs_user_id)
307 seq_printf(m, ",userid=%u", opts->fs_user_id);
Daniel Rosenberg7d10e432017-07-19 17:25:07 -0700308 if (opts->gid_derivation)
309 seq_puts(m, ",derive_gid");
Daniel Campello35c9e242015-07-20 16:23:50 -0700310 if (opts->reserved_mb != 0)
311 seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
312
313 return 0;
314};
315
316const struct super_operations sdcardfs_sops = {
317 .put_super = sdcardfs_put_super,
318 .statfs = sdcardfs_statfs,
319 .remount_fs = sdcardfs_remount_fs,
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700320 .remount_fs2 = sdcardfs_remount_fs2,
321 .clone_mnt_data = sdcardfs_clone_mnt_data,
322 .copy_mnt_data = sdcardfs_copy_mnt_data,
Daniel Campello35c9e242015-07-20 16:23:50 -0700323 .evict_inode = sdcardfs_evict_inode,
324 .umount_begin = sdcardfs_umount_begin,
Daniel Rosenberg317e7702016-10-26 17:36:05 -0700325 .show_options2 = sdcardfs_show_options,
Daniel Campello35c9e242015-07-20 16:23:50 -0700326 .alloc_inode = sdcardfs_alloc_inode,
327 .destroy_inode = sdcardfs_destroy_inode,
328 .drop_inode = generic_delete_inode,
329};