a4b94df99f3200b45454210e0f77c62ab2558d3f
[firefly-linux-kernel-4.4.55.git] / fs / sdcardfs / lookup.c
1 /*
2  * fs/sdcardfs/lookup.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 #include "linux/delay.h"
23
24 /* The dentry cache is just so we have properly sized dentries */
25 static struct kmem_cache *sdcardfs_dentry_cachep;
26
27 int sdcardfs_init_dentry_cache(void)
28 {
29         sdcardfs_dentry_cachep =
30                 kmem_cache_create("sdcardfs_dentry",
31                                   sizeof(struct sdcardfs_dentry_info),
32                                   0, SLAB_RECLAIM_ACCOUNT, NULL);
33
34         return sdcardfs_dentry_cachep ? 0 : -ENOMEM;
35 }
36
37 void sdcardfs_destroy_dentry_cache(void)
38 {
39         if (sdcardfs_dentry_cachep)
40                 kmem_cache_destroy(sdcardfs_dentry_cachep);
41 }
42
43 void free_dentry_private_data(struct dentry *dentry)
44 {
45         if (!dentry || !dentry->d_fsdata)
46                 return;
47         kmem_cache_free(sdcardfs_dentry_cachep, dentry->d_fsdata);
48         dentry->d_fsdata = NULL;
49 }
50
51 /* allocate new dentry private data */
52 int new_dentry_private_data(struct dentry *dentry)
53 {
54         struct sdcardfs_dentry_info *info = SDCARDFS_D(dentry);
55
56         /* use zalloc to init dentry_info.lower_path */
57         info = kmem_cache_zalloc(sdcardfs_dentry_cachep, GFP_ATOMIC);
58         if (!info)
59                 return -ENOMEM;
60
61         spin_lock_init(&info->lock);
62         dentry->d_fsdata = info;
63
64         return 0;
65 }
66
67 static int sdcardfs_inode_test(struct inode *inode, void *candidate_lower_inode)
68 {
69         struct inode *current_lower_inode = sdcardfs_lower_inode(inode);
70         if (current_lower_inode == (struct inode *)candidate_lower_inode)
71                 return 1; /* found a match */
72         else
73                 return 0; /* no match */
74 }
75
76 static int sdcardfs_inode_set(struct inode *inode, void *lower_inode)
77 {
78         /* we do actual inode initialization in sdcardfs_iget */
79         return 0;
80 }
81
82 struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode)
83 {
84         struct sdcardfs_inode_info *info;
85         struct inode *inode; /* the new inode to return */
86         int err;
87
88         inode = iget5_locked(sb, /* our superblock */
89                              /*
90                               * hashval: we use inode number, but we can
91                               * also use "(unsigned long)lower_inode"
92                               * instead.
93                               */
94                              lower_inode->i_ino, /* hashval */
95                              sdcardfs_inode_test,       /* inode comparison function */
96                              sdcardfs_inode_set, /* inode init function */
97                              lower_inode); /* data passed to test+set fxns */
98         if (!inode) {
99                 err = -EACCES;
100                 iput(lower_inode);
101                 return ERR_PTR(err);
102         }
103         /* if found a cached inode, then just return it */
104         if (!(inode->i_state & I_NEW))
105                 return inode;
106
107         /* initialize new inode */
108         info = SDCARDFS_I(inode);
109
110         inode->i_ino = lower_inode->i_ino;
111         if (!igrab(lower_inode)) {
112                 err = -ESTALE;
113                 return ERR_PTR(err);
114         }
115         sdcardfs_set_lower_inode(inode, lower_inode);
116
117         inode->i_version++;
118
119         /* use different set of inode ops for symlinks & directories */
120         if (S_ISDIR(lower_inode->i_mode))
121                 inode->i_op = &sdcardfs_dir_iops;
122         else if (S_ISLNK(lower_inode->i_mode))
123                 inode->i_op = &sdcardfs_symlink_iops;
124         else
125                 inode->i_op = &sdcardfs_main_iops;
126
127         /* use different set of file ops for directories */
128         if (S_ISDIR(lower_inode->i_mode))
129                 inode->i_fop = &sdcardfs_dir_fops;
130         else
131                 inode->i_fop = &sdcardfs_main_fops;
132
133         inode->i_mapping->a_ops = &sdcardfs_aops;
134
135         inode->i_atime.tv_sec = 0;
136         inode->i_atime.tv_nsec = 0;
137         inode->i_mtime.tv_sec = 0;
138         inode->i_mtime.tv_nsec = 0;
139         inode->i_ctime.tv_sec = 0;
140         inode->i_ctime.tv_nsec = 0;
141
142         /* properly initialize special inodes */
143         if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
144             S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
145                 init_special_inode(inode, lower_inode->i_mode,
146                                    lower_inode->i_rdev);
147
148         /* all well, copy inode attributes */
149         fsstack_copy_attr_all(inode, lower_inode);
150         fsstack_copy_inode_size(inode, lower_inode);
151
152         fix_derived_permission(inode);
153
154         unlock_new_inode(inode);
155         return inode;
156 }
157
158 /*
159  * Connect a sdcardfs inode dentry/inode with several lower ones.  This is
160  * the classic stackable file system "vnode interposition" action.
161  *
162  * @dentry: sdcardfs's dentry which interposes on lower one
163  * @sb: sdcardfs's super_block
164  * @lower_path: the lower path (caller does path_get/put)
165  */
166 int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
167                      struct path *lower_path)
168 {
169         int err = 0;
170         struct inode *inode;
171         struct inode *lower_inode;
172         struct super_block *lower_sb;
173
174         lower_inode = lower_path->dentry->d_inode;
175         lower_sb = sdcardfs_lower_super(sb);
176
177         /* check that the lower file system didn't cross a mount point */
178         if (lower_inode->i_sb != lower_sb) {
179                 err = -EXDEV;
180                 goto out;
181         }
182
183         /*
184          * We allocate our new inode below by calling sdcardfs_iget,
185          * which will initialize some of the new inode's fields
186          */
187
188         /* inherit lower inode number for sdcardfs's inode */
189         inode = sdcardfs_iget(sb, lower_inode);
190         if (IS_ERR(inode)) {
191                 err = PTR_ERR(inode);
192                 goto out;
193         }
194
195         d_add(dentry, inode);
196         update_derived_permission(dentry);
197 out:
198         return err;
199 }
200
201 /*
202  * Main driver function for sdcardfs's lookup.
203  *
204  * Returns: NULL (ok), ERR_PTR if an error occurred.
205  * Fills in lower_parent_path with <dentry,mnt> on success.
206  */
207 static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
208                 unsigned int flags, struct path *lower_parent_path)
209 {
210         int err = 0;
211         struct vfsmount *lower_dir_mnt;
212         struct dentry *lower_dir_dentry = NULL;
213         struct dentry *lower_dentry;
214         const char *name;
215         struct path lower_path;
216         struct qstr this;
217         struct sdcardfs_sb_info *sbi;
218
219         sbi = SDCARDFS_SB(dentry->d_sb);
220         /* must initialize dentry operations */
221         d_set_d_op(dentry, &sdcardfs_ci_dops);
222
223         if (IS_ROOT(dentry))
224                 goto out;
225
226         name = dentry->d_name.name;
227
228         /* now start the actual lookup procedure */
229         lower_dir_dentry = lower_parent_path->dentry;
230         lower_dir_mnt = lower_parent_path->mnt;
231
232         /* Use vfs_path_lookup to check if the dentry exists or not */
233         if (sbi->options.lower_fs == LOWER_FS_EXT4) {
234                 err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name,
235                                 LOOKUP_CASE_INSENSITIVE, &lower_path);
236         } else if (sbi->options.lower_fs == LOWER_FS_FAT) {
237                 err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name, 0,
238                                 &lower_path);
239         }
240
241         /* no error: handle positive dentries */
242         if (!err) {
243                 /* check if the dentry is an obb dentry
244                  * if true, the lower_inode must be replaced with
245                  * the inode of the graft path */
246
247                 if(need_graft_path(dentry)) {
248
249                         /* setup_obb_dentry()
250                          * The lower_path will be stored to the dentry's orig_path
251                          * and the base obbpath will be copyed to the lower_path variable.
252                          * if an error returned, there's no change in the lower_path
253                          *              returns: -ERRNO if error (0: no error) */
254                         err = setup_obb_dentry(dentry, &lower_path);
255
256                         if(err) {
257                                 /* if the sbi->obbpath is not available, we can optionally
258                                  * setup the lower_path with its orig_path.
259                                  * but, the current implementation just returns an error
260                                  * because the sdcard daemon also regards this case as
261                                  * a lookup fail. */
262                                 printk(KERN_INFO "sdcardfs: base obbpath is not available\n");
263                                 sdcardfs_put_reset_orig_path(dentry);
264                                 goto out;
265                         }
266                 }
267
268                 sdcardfs_set_lower_path(dentry, &lower_path);
269                 err = sdcardfs_interpose(dentry, dentry->d_sb, &lower_path);
270                 if (err) /* path_put underlying path on error */
271                         sdcardfs_put_reset_lower_path(dentry);
272                 goto out;
273         }
274
275         /*
276          * We don't consider ENOENT an error, and we want to return a
277          * negative dentry.
278          */
279         if (err && err != -ENOENT)
280                 goto out;
281
282         /* instatiate a new negative dentry */
283         this.name = name;
284         this.len = strlen(name);
285         this.hash = full_name_hash(this.name, this.len);
286         lower_dentry = d_lookup(lower_dir_dentry, &this);
287         if (lower_dentry)
288                 goto setup_lower;
289
290         lower_dentry = d_alloc(lower_dir_dentry, &this);
291         if (!lower_dentry) {
292                 err = -ENOMEM;
293                 goto out;
294         }
295         d_add(lower_dentry, NULL); /* instantiate and hash */
296
297 setup_lower:
298         lower_path.dentry = lower_dentry;
299         lower_path.mnt = mntget(lower_dir_mnt);
300         sdcardfs_set_lower_path(dentry, &lower_path);
301
302         /*
303          * If the intent is to create a file, then don't return an error, so
304          * the VFS will continue the process of making this negative dentry
305          * into a positive one.
306          */
307         if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET))
308                 err = 0;
309
310 out:
311         return ERR_PTR(err);
312 }
313
314 /*
315  * On success:
316  *      fills dentry object appropriate values and returns NULL.
317  * On fail (== error)
318  *      returns error ptr
319  *
320  * @dir : Parent inode. It is locked (dir->i_mutex)
321  * @dentry : Target dentry to lookup. we should set each of fields.
322  *           (dentry->d_name is initialized already)
323  * @nd : nameidata of parent inode
324  */
325 struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
326                              unsigned int flags)
327 {
328         struct dentry *ret = NULL, *parent;
329         struct path lower_parent_path;
330         int err = 0;
331         struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
332         const struct cred *saved_cred = NULL;
333
334         parent = dget_parent(dentry);
335
336         if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name,
337                                                 sbi->options.derive, 0, 0)) {
338                 ret = ERR_PTR(-EACCES);
339                 printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
340                          "      dentry: %s, task:%s\n",
341                                                  __func__, dentry->d_name.name, current->comm);
342                 goto out_err;
343         }
344
345         /* save current_cred and override it */
346         OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb), saved_cred);
347
348         sdcardfs_get_lower_path(parent, &lower_parent_path);
349
350         /* allocate dentry private data.  We free it in ->d_release */
351         err = new_dentry_private_data(dentry);
352         if (err) {
353                 ret = ERR_PTR(err);
354                 goto out;
355         }
356
357         ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path);
358         if (IS_ERR(ret))
359         {
360                 goto out;
361         }
362         if (ret)
363                 dentry = ret;
364         if (dentry->d_inode) {
365                 fsstack_copy_attr_times(dentry->d_inode,
366                                         sdcardfs_lower_inode(dentry->d_inode));
367                 /* get drived permission */
368                 get_derived_permission(parent, dentry);
369                 fix_derived_permission(dentry->d_inode);
370         }
371         /* update parent directory's atime */
372         fsstack_copy_attr_atime(parent->d_inode,
373                                 sdcardfs_lower_inode(parent->d_inode));
374
375 out:
376         sdcardfs_put_lower_path(parent, &lower_parent_path);
377         REVERT_CRED(saved_cred);
378 out_err:
379         dput(parent);
380         return ret;
381 }