4 * Copyright (c) 2013 Samsung Electronics Co. Ltd
5 * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
6 * Sunghwan Yun, Sungjong Seo
8 * This program has been developed as a stackable file system based on
9 * the WrapFS which written by
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
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.
24 * The inode cache is used with alloc_inode for both our inode info and the
27 static struct kmem_cache *sdcardfs_inode_cachep;
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.
36 static struct kmem_cache *sdcardfs_inode_data_cachep;
38 void data_release(struct kref *ref)
40 struct sdcardfs_inode_data *data =
41 container_of(ref, struct sdcardfs_inode_data, refcount);
43 kmem_cache_free(sdcardfs_inode_data_cachep, data);
46 /* final actions when unmounting a file system */
47 static void sdcardfs_put_super(struct super_block *sb)
49 struct sdcardfs_sb_info *spd;
50 struct super_block *s;
52 spd = SDCARDFS_SB(sb);
57 kfree(spd->obbpath_s);
58 path_put(&spd->obbpath);
61 /* decrement lower super references */
62 s = sdcardfs_lower_super(sb);
63 sdcardfs_set_lower_super(sb, NULL);
64 atomic_dec(&s->s_active);
70 static int sdcardfs_statfs(struct dentry *dentry, struct kstatfs *buf)
73 struct path lower_path;
75 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
77 sdcardfs_get_lower_path(dentry, &lower_path);
78 err = vfs_statfs(&lower_path, buf);
79 sdcardfs_put_lower_path(dentry, &lower_path);
81 if (sbi->options.reserved_mb) {
82 /* Invalid statfs informations. */
83 if (buf->f_bsize == 0) {
84 pr_err("Returned block size is zero.\n");
88 min_blocks = ((sbi->options.reserved_mb * 1024 * 1024)/buf->f_bsize);
89 buf->f_blocks -= min_blocks;
91 if (buf->f_bavail > min_blocks)
92 buf->f_bavail -= min_blocks;
96 /* Make reserved blocks invisiable to media storage */
97 buf->f_bfree = buf->f_bavail;
100 /* set return buf to our f/s to avoid confusing user-level utils */
101 buf->f_type = SDCARDFS_SUPER_MAGIC;
107 * @flags: numeric mount options
108 * @options: mount options string
110 static int sdcardfs_remount_fs(struct super_block *sb, int *flags, char *options)
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.
119 if ((*flags & ~(MS_RDONLY | MS_MANDLOCK | MS_SILENT)) != 0) {
120 pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
128 * @mnt: mount point we are remounting
129 * @sb: superblock we are remounting
130 * @flags: numeric mount options
131 * @options: mount options string
133 static int sdcardfs_remount_fs2(struct vfsmount *mnt, struct super_block *sb,
134 int *flags, char *options)
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.
143 if ((*flags & ~(MS_RDONLY | MS_MANDLOCK | MS_SILENT | MS_REMOUNT)) != 0) {
144 pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
147 pr_info("Remount options were %s for vfsmnt %p.\n", options, mnt);
148 err = parse_options_remount(sb, options, *flags & ~MS_SILENT, mnt->data);
154 static void *sdcardfs_clone_mnt_data(void *data)
156 struct sdcardfs_vfsmount_options *opt = kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL);
157 struct sdcardfs_vfsmount_options *old = data;
162 opt->mask = old->mask;
166 static void sdcardfs_copy_mnt_data(void *data, void *newdata)
168 struct sdcardfs_vfsmount_options *old = data;
169 struct sdcardfs_vfsmount_options *new = newdata;
172 old->mask = new->mask;
176 * 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.
181 static void sdcardfs_evict_inode(struct inode *inode)
183 struct inode *lower_inode;
185 truncate_inode_pages(&inode->i_data, 0);
186 set_top(SDCARDFS_I(inode), NULL);
189 * Decrement a reference to a lower_inode, which was incremented
190 * by our read_inode when it was created initially.
192 lower_inode = sdcardfs_lower_inode(inode);
193 sdcardfs_set_lower_inode(inode, NULL);
197 static struct inode *sdcardfs_alloc_inode(struct super_block *sb)
199 struct sdcardfs_inode_info *i;
200 struct sdcardfs_inode_data *d;
202 i = kmem_cache_alloc(sdcardfs_inode_cachep, GFP_KERNEL);
206 /* memset everything up to the inode to 0 */
207 memset(i, 0, offsetof(struct sdcardfs_inode_info, vfs_inode));
209 d = kmem_cache_alloc(sdcardfs_inode_data_cachep,
210 GFP_KERNEL | __GFP_ZERO);
212 kmem_cache_free(sdcardfs_inode_cachep, i);
217 kref_init(&d->refcount);
219 i->vfs_inode.i_version = 1;
220 return &i->vfs_inode;
223 static void i_callback(struct rcu_head *head)
225 struct inode *inode = container_of(head, struct inode, i_rcu);
227 release_own_data(SDCARDFS_I(inode));
228 kmem_cache_free(sdcardfs_inode_cachep, SDCARDFS_I(inode));
231 static void sdcardfs_destroy_inode(struct inode *inode)
233 call_rcu(&inode->i_rcu, i_callback);
236 /* sdcardfs inode cache constructor */
237 static void init_once(void *obj)
239 struct sdcardfs_inode_info *i = obj;
241 inode_init_once(&i->vfs_inode);
244 int sdcardfs_init_inode_cache(void)
246 sdcardfs_inode_cachep =
247 kmem_cache_create("sdcardfs_inode_cache",
248 sizeof(struct sdcardfs_inode_info), 0,
249 SLAB_RECLAIM_ACCOUNT, init_once);
251 if (!sdcardfs_inode_cachep)
254 sdcardfs_inode_data_cachep =
255 kmem_cache_create("sdcardfs_inode_data_cache",
256 sizeof(struct sdcardfs_inode_data), 0,
257 SLAB_RECLAIM_ACCOUNT, NULL);
258 if (!sdcardfs_inode_data_cachep) {
259 kmem_cache_destroy(sdcardfs_inode_cachep);
266 /* sdcardfs inode cache destructor */
267 void sdcardfs_destroy_inode_cache(void)
269 kmem_cache_destroy(sdcardfs_inode_data_cachep);
270 kmem_cache_destroy(sdcardfs_inode_cachep);
274 * Used only in nfs, to kill any pending RPC tasks, so that subsequent
275 * code can actually succeed and won't leave tasks that need handling.
277 static void sdcardfs_umount_begin(struct super_block *sb)
279 struct super_block *lower_sb;
281 lower_sb = sdcardfs_lower_super(sb);
282 if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin)
283 lower_sb->s_op->umount_begin(lower_sb);
286 static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
289 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(root->d_sb);
290 struct sdcardfs_mount_options *opts = &sbi->options;
291 struct sdcardfs_vfsmount_options *vfsopts = mnt->data;
293 if (opts->fs_low_uid != 0)
294 seq_printf(m, ",fsuid=%u", opts->fs_low_uid);
295 if (opts->fs_low_gid != 0)
296 seq_printf(m, ",fsgid=%u", opts->fs_low_gid);
297 if (vfsopts->gid != 0)
298 seq_printf(m, ",gid=%u", vfsopts->gid);
300 seq_puts(m, ",multiuser");
302 seq_printf(m, ",mask=%u", vfsopts->mask);
303 if (opts->fs_user_id)
304 seq_printf(m, ",userid=%u", opts->fs_user_id);
305 if (opts->reserved_mb != 0)
306 seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
311 const struct super_operations sdcardfs_sops = {
312 .put_super = sdcardfs_put_super,
313 .statfs = sdcardfs_statfs,
314 .remount_fs = sdcardfs_remount_fs,
315 .remount_fs2 = sdcardfs_remount_fs2,
316 .clone_mnt_data = sdcardfs_clone_mnt_data,
317 .copy_mnt_data = sdcardfs_copy_mnt_data,
318 .evict_inode = sdcardfs_evict_inode,
319 .umount_begin = sdcardfs_umount_begin,
320 .show_options2 = sdcardfs_show_options,
321 .alloc_inode = sdcardfs_alloc_inode,
322 .destroy_inode = sdcardfs_destroy_inode,
323 .drop_inode = generic_delete_inode,