• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
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   */
27  static struct kmem_cache *sdcardfs_inode_cachep;
28  
29  /*
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   */
36  static struct kmem_cache *sdcardfs_inode_data_cachep;
37  
data_release(struct kref * ref)38  void 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  
46  /* final actions when unmounting a file system */
sdcardfs_put_super(struct super_block * sb)47  static 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  
56  	if (spd->obbpath_s) {
57  		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  
66  	kfree(spd);
67  	sb->s_fs_info = NULL;
68  }
69  
sdcardfs_statfs(struct dentry * dentry,struct kstatfs * buf)70  static 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) {
84  			pr_err("Returned block size is zero.\n");
85  			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   */
sdcardfs_remount_fs(struct super_block * sb,int * flags,char * options)110  static 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) {
120  		pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
121  		err = -EINVAL;
122  	}
123  
124  	return err;
125  }
126  
127  /*
128   * @mnt: mount point we are remounting
129   * @sb: superblock we are remounting
130   * @flags: numeric mount options
131   * @options: mount options string
132   */
sdcardfs_remount_fs2(struct vfsmount * mnt,struct super_block * sb,int * flags,char * options)133  static 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) {
144  		pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
145  		err = -EINVAL;
146  	}
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);
149  
150  
151  	return err;
152  }
153  
sdcardfs_clone_mnt_data(void * data)154  static 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;
161  	opt->gid = old->gid;
162  	opt->mask = old->mask;
163  	return opt;
164  }
165  
sdcardfs_copy_mnt_data(void * data,void * newdata)166  static 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  
171  	old->gid = new->gid;
172  	old->mask = new->mask;
173  }
174  
175  /*
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.
180   */
sdcardfs_evict_inode(struct inode * inode)181  static void sdcardfs_evict_inode(struct inode *inode)
182  {
183  	struct inode *lower_inode;
184  
185  	truncate_inode_pages(&inode->i_data, 0);
186  	set_top(SDCARDFS_I(inode), NULL);
187  	clear_inode(inode);
188  	/*
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  
sdcardfs_alloc_inode(struct super_block * sb)197  static struct inode *sdcardfs_alloc_inode(struct super_block *sb)
198  {
199  	struct sdcardfs_inode_info *i;
200  	struct sdcardfs_inode_data *d;
201  
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  
209  	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);
218  	i->top_data = d;
219  	spin_lock_init(&i->top_lock);
220  	kref_get(&d->refcount);
221  
222  	i->vfs_inode.i_version = 1;
223  	return &i->vfs_inode;
224  }
225  
i_callback(struct rcu_head * head)226  static void i_callback(struct rcu_head *head)
227  {
228  	struct inode *inode = container_of(head, struct inode, i_rcu);
229  
230  	release_own_data(SDCARDFS_I(inode));
231  	kmem_cache_free(sdcardfs_inode_cachep, SDCARDFS_I(inode));
232  }
233  
sdcardfs_destroy_inode(struct inode * inode)234  static void sdcardfs_destroy_inode(struct inode *inode)
235  {
236  	call_rcu(&inode->i_rcu, i_callback);
237  }
238  
239  /* sdcardfs inode cache constructor */
init_once(void * obj)240  static void init_once(void *obj)
241  {
242  	struct sdcardfs_inode_info *i = obj;
243  
244  	inode_init_once(&i->vfs_inode);
245  }
246  
sdcardfs_init_inode_cache(void)247  int sdcardfs_init_inode_cache(void)
248  {
249  	sdcardfs_inode_cachep =
250  		kmem_cache_create("sdcardfs_inode_cache",
251  				  sizeof(struct sdcardfs_inode_info), 0,
252  				  SLAB_RECLAIM_ACCOUNT, init_once);
253  
254  	if (!sdcardfs_inode_cachep)
255  		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;
267  }
268  
269  /* sdcardfs inode cache destructor */
sdcardfs_destroy_inode_cache(void)270  void sdcardfs_destroy_inode_cache(void)
271  {
272  	kmem_cache_destroy(sdcardfs_inode_data_cachep);
273  	kmem_cache_destroy(sdcardfs_inode_cachep);
274  }
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   */
sdcardfs_umount_begin(struct super_block * sb)280  static 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  
sdcardfs_show_options(struct vfsmount * mnt,struct seq_file * m,struct dentry * root)289  static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
290  			struct dentry *root)
291  {
292  	struct sdcardfs_sb_info *sbi = SDCARDFS_SB(root->d_sb);
293  	struct sdcardfs_mount_options *opts = &sbi->options;
294  	struct sdcardfs_vfsmount_options *vfsopts = mnt->data;
295  
296  	if (opts->fs_low_uid != 0)
297  		seq_printf(m, ",fsuid=%u", opts->fs_low_uid);
298  	if (opts->fs_low_gid != 0)
299  		seq_printf(m, ",fsgid=%u", opts->fs_low_gid);
300  	if (vfsopts->gid != 0)
301  		seq_printf(m, ",gid=%u", vfsopts->gid);
302  	if (opts->multiuser)
303  		seq_puts(m, ",multiuser");
304  	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);
308  	if (opts->gid_derivation)
309  		seq_puts(m, ",derive_gid");
310  	if (opts->default_normal)
311  		seq_puts(m, ",default_normal");
312  	if (opts->reserved_mb != 0)
313  		seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
314  
315  	return 0;
316  };
317  
318  const struct super_operations sdcardfs_sops = {
319  	.put_super	= sdcardfs_put_super,
320  	.statfs		= sdcardfs_statfs,
321  	.remount_fs	= sdcardfs_remount_fs,
322  	.remount_fs2	= sdcardfs_remount_fs2,
323  	.clone_mnt_data	= sdcardfs_clone_mnt_data,
324  	.copy_mnt_data	= sdcardfs_copy_mnt_data,
325  	.evict_inode	= sdcardfs_evict_inode,
326  	.umount_begin	= sdcardfs_umount_begin,
327  	.show_options2	= sdcardfs_show_options,
328  	.alloc_inode	= sdcardfs_alloc_inode,
329  	.destroy_inode	= sdcardfs_destroy_inode,
330  	.drop_inode	= generic_delete_inode,
331  };
332