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.
22 #include "linux/delay.h"
24 /* The dentry cache is just so we have properly sized dentries */
25 static struct kmem_cache *sdcardfs_dentry_cachep;
27 int sdcardfs_init_dentry_cache(void)
29 sdcardfs_dentry_cachep =
30 kmem_cache_create("sdcardfs_dentry",
31 sizeof(struct sdcardfs_dentry_info),
32 0, SLAB_RECLAIM_ACCOUNT, NULL);
34 return sdcardfs_dentry_cachep ? 0 : -ENOMEM;
37 void sdcardfs_destroy_dentry_cache(void)
39 if (sdcardfs_dentry_cachep)
40 kmem_cache_destroy(sdcardfs_dentry_cachep);
43 void free_dentry_private_data(struct dentry *dentry)
45 if (!dentry || !dentry->d_fsdata)
47 kmem_cache_free(sdcardfs_dentry_cachep, dentry->d_fsdata);
48 dentry->d_fsdata = NULL;
51 /* allocate new dentry private data */
52 int new_dentry_private_data(struct dentry *dentry)
54 struct sdcardfs_dentry_info *info = SDCARDFS_D(dentry);
56 /* use zalloc to init dentry_info.lower_path */
57 info = kmem_cache_zalloc(sdcardfs_dentry_cachep, GFP_ATOMIC);
61 spin_lock_init(&info->lock);
62 dentry->d_fsdata = info;
67 static int sdcardfs_inode_test(struct inode *inode, void *candidate_lower_inode)
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 */
73 return 0; /* no match */
76 static int sdcardfs_inode_set(struct inode *inode, void *lower_inode)
78 /* we do actual inode initialization in sdcardfs_iget */
82 struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode)
84 struct sdcardfs_inode_info *info;
85 struct inode *inode; /* the new inode to return */
88 inode = iget5_locked(sb, /* our superblock */
90 * hashval: we use inode number, but we can
91 * also use "(unsigned long)lower_inode"
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 */
103 /* if found a cached inode, then just return it */
104 if (!(inode->i_state & I_NEW))
107 /* initialize new inode */
108 info = SDCARDFS_I(inode);
110 inode->i_ino = lower_inode->i_ino;
111 if (!igrab(lower_inode)) {
115 sdcardfs_set_lower_inode(inode, lower_inode);
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;
125 inode->i_op = &sdcardfs_main_iops;
127 /* use different set of file ops for directories */
128 if (S_ISDIR(lower_inode->i_mode))
129 inode->i_fop = &sdcardfs_dir_fops;
131 inode->i_fop = &sdcardfs_main_fops;
133 inode->i_mapping->a_ops = &sdcardfs_aops;
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;
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);
148 /* all well, copy inode attributes */
149 fsstack_copy_attr_all(inode, lower_inode);
150 fsstack_copy_inode_size(inode, lower_inode);
152 fix_derived_permission(inode);
154 unlock_new_inode(inode);
159 * Connect a sdcardfs inode dentry/inode with several lower ones. This is
160 * the classic stackable file system "vnode interposition" action.
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)
166 int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
167 struct path *lower_path)
171 struct inode *lower_inode;
172 struct super_block *lower_sb;
174 lower_inode = lower_path->dentry->d_inode;
175 lower_sb = sdcardfs_lower_super(sb);
177 /* check that the lower file system didn't cross a mount point */
178 if (lower_inode->i_sb != lower_sb) {
184 * We allocate our new inode below by calling sdcardfs_iget,
185 * which will initialize some of the new inode's fields
188 /* inherit lower inode number for sdcardfs's inode */
189 inode = sdcardfs_iget(sb, lower_inode);
191 err = PTR_ERR(inode);
195 d_add(dentry, inode);
196 update_derived_permission(dentry);
202 * Main driver function for sdcardfs's lookup.
204 * Returns: NULL (ok), ERR_PTR if an error occurred.
205 * Fills in lower_parent_path with <dentry,mnt> on success.
207 static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
208 unsigned int flags, struct path *lower_parent_path)
211 struct vfsmount *lower_dir_mnt;
212 struct dentry *lower_dir_dentry = NULL;
213 struct dentry *lower_dentry;
215 struct path lower_path;
217 struct sdcardfs_sb_info *sbi;
219 sbi = SDCARDFS_SB(dentry->d_sb);
220 /* must initialize dentry operations */
221 d_set_d_op(dentry, &sdcardfs_ci_dops);
226 name = dentry->d_name.name;
228 /* now start the actual lookup procedure */
229 lower_dir_dentry = lower_parent_path->dentry;
230 lower_dir_mnt = lower_parent_path->mnt;
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,
241 /* no error: handle positive dentries */
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 */
247 if(need_graft_path(dentry)) {
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);
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
262 printk(KERN_INFO "sdcardfs: base obbpath is not available\n");
263 sdcardfs_put_reset_orig_path(dentry);
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);
276 * We don't consider ENOENT an error, and we want to return a
279 if (err && err != -ENOENT)
282 /* instatiate a new negative dentry */
284 this.len = strlen(name);
285 this.hash = full_name_hash(this.name, this.len);
286 lower_dentry = d_lookup(lower_dir_dentry, &this);
290 lower_dentry = d_alloc(lower_dir_dentry, &this);
295 d_add(lower_dentry, NULL); /* instantiate and hash */
298 lower_path.dentry = lower_dentry;
299 lower_path.mnt = mntget(lower_dir_mnt);
300 sdcardfs_set_lower_path(dentry, &lower_path);
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.
307 if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET))
316 * fills dentry object appropriate values and returns NULL.
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
325 struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
328 struct dentry *ret = NULL, *parent;
329 struct path lower_parent_path;
331 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
332 const struct cred *saved_cred = NULL;
334 parent = dget_parent(dentry);
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);
345 /* save current_cred and override it */
346 OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb), saved_cred);
348 sdcardfs_get_lower_path(parent, &lower_parent_path);
350 /* allocate dentry private data. We free it in ->d_release */
351 err = new_dentry_private_data(dentry);
357 ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path);
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);
371 /* update parent directory's atime */
372 fsstack_copy_attr_atime(parent->d_inode,
373 sdcardfs_lower_inode(parent->d_inode));
376 sdcardfs_put_lower_path(parent, &lower_parent_path);
377 REVERT_CRED(saved_cred);