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
)->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 */
97 data
.lower_inode
= lower_inode
;
98 inode
= iget5_locked(sb
, /* our superblock */
100 * hashval: we use inode number, but we can
101 * also use "(unsigned long)lower_inode"
104 lower_inode
->i_ino
, /* hashval */
105 sdcardfs_inode_test
, /* inode comparison function */
106 sdcardfs_inode_set
, /* inode init function */
107 &data
); /* data passed to test+set fxns */
113 /* if found a cached inode, then just return it */
114 if (!(inode
->i_state
& I_NEW
))
117 /* initialize new inode */
118 info
= SDCARDFS_I(inode
);
120 inode
->i_ino
= lower_inode
->i_ino
;
121 if (!igrab(lower_inode
)) {
125 sdcardfs_set_lower_inode(inode
, lower_inode
);
129 /* use different set of inode ops for symlinks & directories */
130 if (S_ISDIR(lower_inode
->i_mode
))
131 inode
->i_op
= &sdcardfs_dir_iops
;
132 else if (S_ISLNK(lower_inode
->i_mode
))
133 inode
->i_op
= &sdcardfs_symlink_iops
;
135 inode
->i_op
= &sdcardfs_main_iops
;
137 /* use different set of file ops for directories */
138 if (S_ISDIR(lower_inode
->i_mode
))
139 inode
->i_fop
= &sdcardfs_dir_fops
;
141 inode
->i_fop
= &sdcardfs_main_fops
;
143 inode
->i_mapping
->a_ops
= &sdcardfs_aops
;
145 inode
->i_atime
.tv_sec
= 0;
146 inode
->i_atime
.tv_nsec
= 0;
147 inode
->i_mtime
.tv_sec
= 0;
148 inode
->i_mtime
.tv_nsec
= 0;
149 inode
->i_ctime
.tv_sec
= 0;
150 inode
->i_ctime
.tv_nsec
= 0;
152 /* properly initialize special inodes */
153 if (S_ISBLK(lower_inode
->i_mode
) || S_ISCHR(lower_inode
->i_mode
) ||
154 S_ISFIFO(lower_inode
->i_mode
) || S_ISSOCK(lower_inode
->i_mode
))
155 init_special_inode(inode
, lower_inode
->i_mode
,
156 lower_inode
->i_rdev
);
158 /* all well, copy inode attributes */
159 sdcardfs_copy_and_fix_attrs(inode
, lower_inode
);
160 fsstack_copy_inode_size(inode
, lower_inode
);
162 unlock_new_inode(inode
);
167 * Helper interpose routine, called directly by ->lookup to handle
170 static struct dentry
*__sdcardfs_interpose(struct dentry
*dentry
,
171 struct super_block
*sb
,
172 struct path
*lower_path
,
176 struct inode
*lower_inode
;
177 struct super_block
*lower_sb
;
178 struct dentry
*ret_dentry
;
180 lower_inode
= lower_path
->dentry
->d_inode
;
181 lower_sb
= sdcardfs_lower_super(sb
);
183 /* check that the lower file system didn't cross a mount point */
184 if (lower_inode
->i_sb
!= lower_sb
) {
185 ret_dentry
= ERR_PTR(-EXDEV
);
190 * We allocate our new inode below by calling sdcardfs_iget,
191 * which will initialize some of the new inode's fields
194 /* inherit lower inode number for sdcardfs's inode */
195 inode
= sdcardfs_iget(sb
, lower_inode
, id
);
197 ret_dentry
= ERR_CAST(inode
);
201 ret_dentry
= d_splice_alias(inode
, dentry
);
202 dentry
= ret_dentry
?: dentry
;
203 update_derived_permission_lock(dentry
);
209 * Connect an sdcardfs inode dentry/inode with several lower ones. This is
210 * the classic stackable file system "vnode interposition" action.
212 * @dentry: sdcardfs's dentry which interposes on lower one
213 * @sb: sdcardfs's super_block
214 * @lower_path: the lower path (caller does path_get/put)
216 int sdcardfs_interpose(struct dentry
*dentry
, struct super_block
*sb
,
217 struct path
*lower_path
, userid_t id
)
219 struct dentry
*ret_dentry
;
221 ret_dentry
= __sdcardfs_interpose(dentry
, sb
, lower_path
, id
);
222 return PTR_ERR(ret_dentry
);
225 struct sdcardfs_name_data
{
226 struct dir_context ctx
;
227 const struct qstr
*to_find
;
232 static int sdcardfs_name_match(void *__buf
, const char *name
, int namelen
,
233 loff_t offset
, u64 ino
, unsigned int d_type
)
235 struct sdcardfs_name_data
*buf
= (struct sdcardfs_name_data
*) __buf
;
236 struct qstr candidate
= QSTR_INIT(name
, namelen
);
238 if (qstr_case_eq(buf
->to_find
, &candidate
)) {
239 memcpy(buf
->name
, name
, namelen
);
240 buf
->name
[namelen
] = 0;
248 * Main driver function for sdcardfs's lookup.
250 * Returns: NULL (ok), ERR_PTR if an error occurred.
251 * Fills in lower_parent_path with <dentry,mnt> on success.
253 static struct dentry
*__sdcardfs_lookup(struct dentry
*dentry
,
254 unsigned int flags
, struct path
*lower_parent_path
, userid_t id
)
257 struct vfsmount
*lower_dir_mnt
;
258 struct dentry
*lower_dir_dentry
= NULL
;
259 struct dentry
*lower_dentry
;
260 const struct qstr
*name
;
261 struct path lower_path
;
263 struct dentry
*ret_dentry
= NULL
;
264 struct sdcardfs_sb_info
*sbi
;
266 sbi
= SDCARDFS_SB(dentry
->d_sb
);
267 /* must initialize dentry operations */
268 d_set_d_op(dentry
, &sdcardfs_ci_dops
);
273 name
= &dentry
->d_name
;
275 /* now start the actual lookup procedure */
276 lower_dir_dentry
= lower_parent_path
->dentry
;
277 lower_dir_mnt
= lower_parent_path
->mnt
;
279 /* Use vfs_path_lookup to check if the dentry exists or not */
280 err
= vfs_path_lookup(lower_dir_dentry
, lower_dir_mnt
, name
->name
, 0,
282 /* check for other cases */
283 if (err
== -ENOENT
) {
285 const struct cred
*cred
= current_cred();
287 struct sdcardfs_name_data buffer
= {
288 .ctx
.actor
= sdcardfs_name_match
,
298 file
= dentry_open(lower_parent_path
, O_RDONLY
, cred
);
303 err
= iterate_dir(file
, &buffer
.ctx
);
309 err
= vfs_path_lookup(lower_dir_dentry
,
316 __putname(buffer
.name
);
319 /* no error: handle positive dentries */
321 /* check if the dentry is an obb dentry
322 * if true, the lower_inode must be replaced with
323 * the inode of the graft path
326 if (need_graft_path(dentry
)) {
328 /* setup_obb_dentry()
329 * The lower_path will be stored to the dentry's orig_path
330 * and the base obbpath will be copyed to the lower_path variable.
331 * if an error returned, there's no change in the lower_path
332 * returns: -ERRNO if error (0: no error)
334 err
= setup_obb_dentry(dentry
, &lower_path
);
337 /* if the sbi->obbpath is not available, we can optionally
338 * setup the lower_path with its orig_path.
339 * but, the current implementation just returns an error
340 * because the sdcard daemon also regards this case as
343 pr_info("sdcardfs: base obbpath is not available\n");
344 sdcardfs_put_reset_orig_path(dentry
);
349 sdcardfs_set_lower_path(dentry
, &lower_path
);
351 __sdcardfs_interpose(dentry
, dentry
->d_sb
, &lower_path
, id
);
352 if (IS_ERR(ret_dentry
)) {
353 err
= PTR_ERR(ret_dentry
);
354 /* path_put underlying path on error */
355 sdcardfs_put_reset_lower_path(dentry
);
361 * We don't consider ENOENT an error, and we want to return a
364 if (err
&& err
!= -ENOENT
)
367 /* instatiate a new negative dentry */
368 dname
.name
= name
->name
;
369 dname
.len
= name
->len
;
370 dname
.hash
= full_name_hash(dname
.name
, dname
.len
);
371 lower_dentry
= d_lookup(lower_dir_dentry
, &dname
);
375 lower_dentry
= d_alloc(lower_dir_dentry
, &dname
);
380 d_add(lower_dentry
, NULL
); /* instantiate and hash */
383 lower_path
.dentry
= lower_dentry
;
384 lower_path
.mnt
= mntget(lower_dir_mnt
);
385 sdcardfs_set_lower_path(dentry
, &lower_path
);
388 * If the intent is to create a file, then don't return an error, so
389 * the VFS will continue the process of making this negative dentry
390 * into a positive one.
392 if (flags
& (LOOKUP_CREATE
|LOOKUP_RENAME_TARGET
))
403 * fills dentry object appropriate values and returns NULL.
407 * @dir : Parent inode. It is locked (dir->i_mutex)
408 * @dentry : Target dentry to lookup. we should set each of fields.
409 * (dentry->d_name is initialized already)
410 * @nd : nameidata of parent inode
412 struct dentry
*sdcardfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
415 struct dentry
*ret
= NULL
, *parent
;
416 struct path lower_parent_path
;
418 const struct cred
*saved_cred
= NULL
;
420 parent
= dget_parent(dentry
);
422 if (!check_caller_access_to_name(parent
->d_inode
, &dentry
->d_name
)) {
423 ret
= ERR_PTR(-EACCES
);
427 /* save current_cred and override it */
428 OVERRIDE_CRED_PTR(SDCARDFS_SB(dir
->i_sb
), saved_cred
, SDCARDFS_I(dir
));
430 sdcardfs_get_lower_path(parent
, &lower_parent_path
);
432 /* allocate dentry private data. We free it in ->d_release */
433 err
= new_dentry_private_data(dentry
);
439 ret
= __sdcardfs_lookup(dentry
, flags
, &lower_parent_path
, SDCARDFS_I(dir
)->userid
);
444 if (dentry
->d_inode
) {
445 fsstack_copy_attr_times(dentry
->d_inode
,
446 sdcardfs_lower_inode(dentry
->d_inode
));
447 /* get derived permission */
448 get_derived_permission(parent
, dentry
);
449 fixup_tmp_permissions(dentry
->d_inode
);
450 fixup_lower_ownership(dentry
, dentry
->d_name
.name
);
452 /* update parent directory's atime */
453 fsstack_copy_attr_atime(parent
->d_inode
,
454 sdcardfs_lower_inode(parent
->d_inode
));
457 sdcardfs_put_lower_path(parent
, &lower_parent_path
);
458 REVERT_CRED(saved_cred
);