Included sdcardfs source code for kernel 3.0
[firefly-linux-kernel-4.4.55.git] / fs / sdcardfs / super.c
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 /* final actions when unmounting a file system */
30 static void sdcardfs_put_super(struct super_block *sb)
31 {
32         struct sdcardfs_sb_info *spd;
33         struct super_block *s;
34
35         spd = SDCARDFS_SB(sb);
36         if (!spd)
37                 return;
38
39         if(spd->obbpath_s) {
40                 kfree(spd->obbpath_s);
41                 path_put(&spd->obbpath);
42         }
43
44         /* decrement lower super references */
45         s = sdcardfs_lower_super(sb);
46         sdcardfs_set_lower_super(sb, NULL);
47         atomic_dec(&s->s_active);
48
49         if(spd->pkgl_id)
50                 packagelist_destroy(spd->pkgl_id);
51
52         kfree(spd);
53         sb->s_fs_info = NULL;
54 }
55
56 static int sdcardfs_statfs(struct dentry *dentry, struct kstatfs *buf)
57 {
58         int err;
59         struct path lower_path;
60         u32 min_blocks;
61         struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
62
63         sdcardfs_get_lower_path(dentry, &lower_path);
64         err = vfs_statfs(&lower_path, buf);
65         sdcardfs_put_lower_path(dentry, &lower_path);
66
67         if (sbi->options.reserved_mb) {
68                 /* Invalid statfs informations. */
69                 if (buf->f_bsize == 0) {
70                         printk(KERN_ERR "Returned block size is zero.\n");
71                         return -EINVAL;
72                 }
73
74                 min_blocks = ((sbi->options.reserved_mb * 1024 * 1024)/buf->f_bsize);
75                 buf->f_blocks -= min_blocks;
76
77                 if (buf->f_bavail > min_blocks)
78                         buf->f_bavail -= min_blocks;
79                 else
80                         buf->f_bavail = 0;
81
82                 /* Make reserved blocks invisiable to media storage */
83                 buf->f_bfree = buf->f_bavail;
84         }
85
86         /* set return buf to our f/s to avoid confusing user-level utils */
87         buf->f_type = SDCARDFS_SUPER_MAGIC;
88
89         return err;
90 }
91
92 /*
93  * @flags: numeric mount options
94  * @options: mount options string
95  */
96 static int sdcardfs_remount_fs(struct super_block *sb, int *flags, char *options)
97 {
98         int err = 0;
99
100         /*
101          * The VFS will take care of "ro" and "rw" flags among others.  We
102          * can safely accept a few flags (RDONLY, MANDLOCK), and honor
103          * SILENT, but anything else left over is an error.
104          */
105         if ((*flags & ~(MS_RDONLY | MS_MANDLOCK | MS_SILENT)) != 0) {
106                 printk(KERN_ERR
107                        "sdcardfs: remount flags 0x%x unsupported\n", *flags);
108                 err = -EINVAL;
109         }
110
111         return err;
112 }
113
114 /*
115  * Called by iput() when the inode reference count reached zero
116  * and the inode is not hashed anywhere.  Used to clear anything
117  * that needs to be, before the inode is completely destroyed and put
118  * on the inode free list.
119  */
120 static void sdcardfs_evict_inode(struct inode *inode)
121 {
122         struct inode *lower_inode;
123
124         truncate_inode_pages(&inode->i_data, 0);
125         end_writeback(inode);
126         /*
127          * Decrement a reference to a lower_inode, which was incremented
128          * by our read_inode when it was created initially.
129          */
130         lower_inode = sdcardfs_lower_inode(inode);
131         sdcardfs_set_lower_inode(inode, NULL);
132         iput(lower_inode);
133 }
134
135 static struct inode *sdcardfs_alloc_inode(struct super_block *sb)
136 {
137         struct sdcardfs_inode_info *i;
138
139         i = kmem_cache_alloc(sdcardfs_inode_cachep, GFP_KERNEL);
140         if (!i)
141                 return NULL;
142
143         /* memset everything up to the inode to 0 */
144         memset(i, 0, offsetof(struct sdcardfs_inode_info, vfs_inode));
145
146         i->vfs_inode.i_version = 1;
147         return &i->vfs_inode;
148 }
149
150 static void sdcardfs_destroy_inode(struct inode *inode)
151 {
152         kmem_cache_free(sdcardfs_inode_cachep, SDCARDFS_I(inode));
153 }
154
155 /* sdcardfs inode cache constructor */
156 static void init_once(void *obj)
157 {
158         struct sdcardfs_inode_info *i = obj;
159
160         inode_init_once(&i->vfs_inode);
161 }
162
163 int sdcardfs_init_inode_cache(void)
164 {
165         int err = 0;
166
167         sdcardfs_inode_cachep =
168                 kmem_cache_create("sdcardfs_inode_cache",
169                                   sizeof(struct sdcardfs_inode_info), 0,
170                                   SLAB_RECLAIM_ACCOUNT, init_once);
171         if (!sdcardfs_inode_cachep)
172                 err = -ENOMEM;
173         return err;
174 }
175
176 /* sdcardfs inode cache destructor */
177 void sdcardfs_destroy_inode_cache(void)
178 {
179         if (sdcardfs_inode_cachep)
180                 kmem_cache_destroy(sdcardfs_inode_cachep);
181 }
182
183 /*
184  * Used only in nfs, to kill any pending RPC tasks, so that subsequent
185  * code can actually succeed and won't leave tasks that need handling.
186  */
187 static void sdcardfs_umount_begin(struct super_block *sb)
188 {
189         struct super_block *lower_sb;
190
191         lower_sb = sdcardfs_lower_super(sb);
192         if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin)
193                 lower_sb->s_op->umount_begin(lower_sb);
194 }
195
196 static int sdcardfs_show_options(struct seq_file *m, struct vfsmount *mnt)
197 {
198         struct sdcardfs_sb_info *sbi = SDCARDFS_SB(mnt->mnt_sb);
199         struct sdcardfs_mount_options *opts = &sbi->options;
200
201         if (opts->fs_low_uid != 0)
202                 seq_printf(m, ",uid=%u", opts->fs_low_uid);
203         if (opts->fs_low_gid != 0)
204                 seq_printf(m, ",gid=%u", opts->fs_low_gid);
205
206         if (opts->derive == DERIVE_NONE)
207                 seq_printf(m, ",derive=none");
208         else if (opts->derive == DERIVE_LEGACY)
209                 seq_printf(m, ",derive=legacy");
210         else if (opts->derive == DERIVE_UNIFIED)
211                 seq_printf(m, ",derive=unified");
212
213         if (opts->reserved_mb != 0)
214                 seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
215
216         return 0;
217 };
218
219 const struct super_operations sdcardfs_sops = {
220         .put_super      = sdcardfs_put_super,
221         .statfs         = sdcardfs_statfs,
222         .remount_fs     = sdcardfs_remount_fs,
223         .evict_inode    = sdcardfs_evict_inode,
224         .umount_begin   = sdcardfs_umount_begin,
225         .show_options   = sdcardfs_show_options,
226         .alloc_inode    = sdcardfs_alloc_inode,
227         .destroy_inode  = sdcardfs_destroy_inode,
228         .drop_inode     = generic_delete_inode,
229 };