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 kmem_cache_destroy(sdcardfs_dentry_cachep);
42 void free_dentry_private_data(struct dentry *dentry)
44 if (!dentry || !dentry->d_fsdata)
46 kmem_cache_free(sdcardfs_dentry_cachep, dentry->d_fsdata);
47 dentry->d_fsdata = NULL;
50 /* allocate new dentry private data */
51 int new_dentry_private_data(struct dentry *dentry)
53 struct sdcardfs_dentry_info *info = SDCARDFS_D(dentry);
55 /* use zalloc to init dentry_info.lower_path */
56 info = kmem_cache_zalloc(sdcardfs_dentry_cachep, GFP_ATOMIC);
60 spin_lock_init(&info->lock);
61 dentry->d_fsdata = info;
67 struct inode *lower_inode;
71 static int sdcardfs_inode_test(struct inode *inode, void *candidate_data/*void *candidate_lower_inode*/)
73 struct inode *current_lower_inode = sdcardfs_lower_inode(inode);
74 userid_t current_userid = SDCARDFS_I(inode)->data->userid;
76 if (current_lower_inode == ((struct inode_data *)candidate_data)->lower_inode &&
77 current_userid == ((struct inode_data *)candidate_data)->id)
78 return 1; /* found a match */
80 return 0; /* no match */
83 static int sdcardfs_inode_set(struct inode *inode, void *lower_inode)
85 /* we do actual inode initialization in sdcardfs_iget */
89 struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, userid_t id)
91 struct sdcardfs_inode_info *info;
92 struct inode_data data;
93 struct inode *inode; /* the new inode to return */
95 if (!igrab(lower_inode))
96 return ERR_PTR(-ESTALE);
99 data.lower_inode = lower_inode;
100 inode = iget5_locked(sb, /* our superblock */
102 * hashval: we use inode number, but we can
103 * also use "(unsigned long)lower_inode"
106 lower_inode->i_ino, /* hashval */
107 sdcardfs_inode_test, /* inode comparison function */
108 sdcardfs_inode_set, /* inode init function */
109 &data); /* data passed to test+set fxns */
112 return ERR_PTR(-ENOMEM);
114 /* if found a cached inode, then just return it (after iput) */
115 if (!(inode->i_state & I_NEW)) {
120 /* initialize new inode */
121 info = SDCARDFS_I(inode);
123 inode->i_ino = lower_inode->i_ino;
124 sdcardfs_set_lower_inode(inode, lower_inode);
128 /* use different set of inode ops for symlinks & directories */
129 if (S_ISDIR(lower_inode->i_mode))
130 inode->i_op = &sdcardfs_dir_iops;
131 else if (S_ISLNK(lower_inode->i_mode))
132 inode->i_op = &sdcardfs_symlink_iops;
134 inode->i_op = &sdcardfs_main_iops;
136 /* use different set of file ops for directories */
137 if (S_ISDIR(lower_inode->i_mode))
138 inode->i_fop = &sdcardfs_dir_fops;
140 inode->i_fop = &sdcardfs_main_fops;
142 inode->i_mapping->a_ops = &sdcardfs_aops;
144 inode->i_atime.tv_sec = 0;
145 inode->i_atime.tv_nsec = 0;
146 inode->i_mtime.tv_sec = 0;
147 inode->i_mtime.tv_nsec = 0;
148 inode->i_ctime.tv_sec = 0;
149 inode->i_ctime.tv_nsec = 0;
151 /* properly initialize special inodes */
152 if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
153 S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
154 init_special_inode(inode, lower_inode->i_mode,
155 lower_inode->i_rdev);
157 /* all well, copy inode attributes */
158 sdcardfs_copy_and_fix_attrs(inode, lower_inode);
159 fsstack_copy_inode_size(inode, lower_inode);
161 unlock_new_inode(inode);
166 * Helper interpose routine, called directly by ->lookup to handle
169 static struct dentry *__sdcardfs_interpose(struct dentry *dentry,
170 struct super_block *sb,
171 struct path *lower_path,
175 struct inode *lower_inode;
176 struct super_block *lower_sb;
177 struct dentry *ret_dentry;
179 lower_inode = d_inode(lower_path->dentry);
180 lower_sb = sdcardfs_lower_super(sb);
182 /* check that the lower file system didn't cross a mount point */
183 if (lower_inode->i_sb != lower_sb) {
184 ret_dentry = ERR_PTR(-EXDEV);
189 * We allocate our new inode below by calling sdcardfs_iget,
190 * which will initialize some of the new inode's fields
193 /* inherit lower inode number for sdcardfs's inode */
194 inode = sdcardfs_iget(sb, lower_inode, id);
196 ret_dentry = ERR_CAST(inode);
200 ret_dentry = d_splice_alias(inode, dentry);
201 dentry = ret_dentry ?: dentry;
202 update_derived_permission_lock(dentry);
208 * Connect an sdcardfs inode dentry/inode with several lower ones. This is
209 * the classic stackable file system "vnode interposition" action.
211 * @dentry: sdcardfs's dentry which interposes on lower one
212 * @sb: sdcardfs's super_block
213 * @lower_path: the lower path (caller does path_get/put)
215 int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
216 struct path *lower_path, userid_t id)
218 struct dentry *ret_dentry;
220 ret_dentry = __sdcardfs_interpose(dentry, sb, lower_path, id);
221 return PTR_ERR(ret_dentry);
224 struct sdcardfs_name_data {
225 struct dir_context ctx;
226 const struct qstr *to_find;
231 static int sdcardfs_name_match(struct dir_context *ctx, const char *name,
232 int namelen, loff_t offset, u64 ino, unsigned int d_type)
234 struct sdcardfs_name_data *buf = container_of(ctx, struct sdcardfs_name_data, ctx);
235 struct qstr candidate = QSTR_INIT(name, namelen);
237 if (qstr_case_eq(buf->to_find, &candidate)) {
238 memcpy(buf->name, name, namelen);
239 buf->name[namelen] = 0;
247 * Main driver function for sdcardfs's lookup.
249 * Returns: NULL (ok), ERR_PTR if an error occurred.
250 * Fills in lower_parent_path with <dentry,mnt> on success.
252 static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
253 unsigned int flags, struct path *lower_parent_path, userid_t id)
256 struct vfsmount *lower_dir_mnt;
257 struct dentry *lower_dir_dentry = NULL;
258 struct dentry *lower_dentry;
259 const struct qstr *name;
260 struct path lower_path;
262 struct dentry *ret_dentry = NULL;
263 struct sdcardfs_sb_info *sbi;
265 sbi = SDCARDFS_SB(dentry->d_sb);
266 /* must initialize dentry operations */
267 d_set_d_op(dentry, &sdcardfs_ci_dops);
272 name = &dentry->d_name;
274 /* now start the actual lookup procedure */
275 lower_dir_dentry = lower_parent_path->dentry;
276 lower_dir_mnt = lower_parent_path->mnt;
278 /* Use vfs_path_lookup to check if the dentry exists or not */
279 err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name->name, 0,
281 /* check for other cases */
282 if (err == -ENOENT) {
284 const struct cred *cred = current_cred();
286 struct sdcardfs_name_data buffer = {
287 .ctx.actor = sdcardfs_name_match,
297 file = dentry_open(lower_parent_path, O_RDONLY, cred);
302 err = iterate_dir(file, &buffer.ctx);
308 err = vfs_path_lookup(lower_dir_dentry,
315 __putname(buffer.name);
318 /* no error: handle positive dentries */
320 /* check if the dentry is an obb dentry
321 * if true, the lower_inode must be replaced with
322 * the inode of the graft path
325 if (need_graft_path(dentry)) {
327 /* setup_obb_dentry()
328 * The lower_path will be stored to the dentry's orig_path
329 * and the base obbpath will be copyed to the lower_path variable.
330 * if an error returned, there's no change in the lower_path
331 * returns: -ERRNO if error (0: no error)
333 err = setup_obb_dentry(dentry, &lower_path);
336 /* if the sbi->obbpath is not available, we can optionally
337 * setup the lower_path with its orig_path.
338 * but, the current implementation just returns an error
339 * because the sdcard daemon also regards this case as
342 pr_info("sdcardfs: base obbpath is not available\n");
343 sdcardfs_put_reset_orig_path(dentry);
348 sdcardfs_set_lower_path(dentry, &lower_path);
350 __sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id);
351 if (IS_ERR(ret_dentry)) {
352 err = PTR_ERR(ret_dentry);
353 /* path_put underlying path on error */
354 sdcardfs_put_reset_lower_path(dentry);
360 * We don't consider ENOENT an error, and we want to return a
363 if (err && err != -ENOENT)
366 /* instatiate a new negative dentry */
367 dname.name = name->name;
368 dname.len = name->len;
370 /* See if the low-level filesystem might want
371 * to use its own hash
373 lower_dentry = d_hash_and_lookup(lower_dir_dentry, &dname);
374 if (IS_ERR(lower_dentry))
377 /* We called vfs_path_lookup earlier, and did not get a negative
378 * dentry then. Don't confuse the lower filesystem by forcing
385 lower_path.dentry = lower_dentry;
386 lower_path.mnt = mntget(lower_dir_mnt);
387 sdcardfs_set_lower_path(dentry, &lower_path);
390 * If the intent is to create a file, then don't return an error, so
391 * the VFS will continue the process of making this negative dentry
392 * into a positive one.
394 if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET))
405 * fills dentry object appropriate values and returns NULL.
409 * @dir : Parent inode. It is locked (dir->i_mutex)
410 * @dentry : Target dentry to lookup. we should set each of fields.
411 * (dentry->d_name is initialized already)
412 * @nd : nameidata of parent inode
414 struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
417 struct dentry *ret = NULL, *parent;
418 struct path lower_parent_path;
420 const struct cred *saved_cred = NULL;
422 parent = dget_parent(dentry);
424 if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
425 ret = ERR_PTR(-EACCES);
429 /* save current_cred and override it */
430 OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
432 sdcardfs_get_lower_path(parent, &lower_parent_path);
434 /* allocate dentry private data. We free it in ->d_release */
435 err = new_dentry_private_data(dentry);
441 ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path,
442 SDCARDFS_I(dir)->data->userid);
447 if (d_inode(dentry)) {
448 fsstack_copy_attr_times(d_inode(dentry),
449 sdcardfs_lower_inode(d_inode(dentry)));
450 /* get derived permission */
451 get_derived_permission(parent, dentry);
452 fixup_tmp_permissions(d_inode(dentry));
453 fixup_lower_ownership(dentry, dentry->d_name.name);
455 /* update parent directory's atime */
456 fsstack_copy_attr_atime(d_inode(parent),
457 sdcardfs_lower_inode(d_inode(parent)));
460 sdcardfs_put_lower_path(parent, &lower_parent_path);
461 REVERT_CRED(saved_cred);