if (!cred)
return NULL;
- cred->fsuid = sbi->options.fs_low_uid;
- cred->fsgid = sbi->options.fs_low_gid;
+ cred->fsuid = make_kuid(&init_user_ns, sbi->options.fs_low_uid);
+ cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid);
old_cred = override_creds(cred);
}
static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
- int mode, struct nameidata *nd)
+ umode_t mode, bool want_excl)
{
- int err = 0;
+ int err;
struct dentry *lower_dentry;
struct dentry *lower_parent_dentry = NULL;
- struct path lower_path, saved_path;
+ struct path lower_path;
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
const struct cred *saved_cred = NULL;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
-
- pathcpy(&saved_path, &nd->path);
- pathcpy(&nd->path, &lower_path);
-
/* set last 16bytes of mode field to 0664 */
mode = (mode & S_IFMT) | 00664;
- err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
-
- pathcpy(&nd->path, &saved_path);
+ err = vfs_create(d_inode(lower_parent_dentry), lower_dentry, mode, want_excl);
if (err)
goto out;
if (err)
goto out;
fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
+ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
unlock_dir(lower_parent_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
REVERT_CRED(saved_cred);
OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb));
- file_size_save = i_size_read(old_dentry->d_inode);
+ file_size_save = i_size_read(d_inode(old_dentry));
sdcardfs_get_lower_path(old_dentry, &lower_old_path);
sdcardfs_get_lower_path(new_dentry, &lower_new_path);
lower_old_dentry = lower_old_path.dentry;
lower_new_dentry = lower_new_path.dentry;
lower_dir_dentry = lock_parent(lower_new_dentry);
- err = mnt_want_write(lower_new_path.mnt);
- if (err)
- goto out_unlock;
-
- err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
- lower_new_dentry);
- if (err || !lower_new_dentry->d_inode)
+ err = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
+ lower_new_dentry, NULL);
+ if (err || !d_inode(lower_new_dentry))
goto out;
err = sdcardfs_interpose(new_dentry, dir->i_sb, &lower_new_path);
if (err)
goto out;
- fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
- fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
- old_dentry->d_inode->i_nlink =
- sdcardfs_lower_inode(old_dentry->d_inode)->i_nlink;
- i_size_write(new_dentry->d_inode, file_size_save);
+ fsstack_copy_attr_times(dir, d_inode(lower_new_dentry));
+ fsstack_copy_inode_size(dir, d_inode(lower_new_dentry));
+ set_nlink(d_inode(old_dentry),
+ sdcardfs_lower_inode(d_inode(old_dentry))->i_nlink);
+ i_size_write(d_inode(new_dentry), file_size_save);
out:
- mnt_drop_write(lower_new_path.mnt);
-out_unlock:
unlock_dir(lower_dir_dentry);
sdcardfs_put_lower_path(old_dentry, &lower_old_path);
sdcardfs_put_lower_path(new_dentry, &lower_new_path);
dget(lower_dentry);
lower_dir_dentry = lock_parent(lower_dentry);
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_unlink(lower_dir_inode, lower_dentry);
+ err = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
/*
* Note: unlinking on top of NFS can cause silly-renamed files.
goto out;
fsstack_copy_attr_times(dir, lower_dir_inode);
fsstack_copy_inode_size(dir, lower_dir_inode);
- dentry->d_inode->i_nlink =
- sdcardfs_lower_inode(dentry->d_inode)->i_nlink;
- dentry->d_inode->i_ctime = dir->i_ctime;
+ set_nlink(d_inode(dentry),
+ sdcardfs_lower_inode(d_inode(dentry))->i_nlink);
+ d_inode(dentry)->i_ctime = dir->i_ctime;
d_drop(dentry); /* this is needed, else LTP fails (VFS won't do it) */
out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
unlock_dir(lower_dir_dentry);
dput(lower_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
static int sdcardfs_symlink(struct inode *dir, struct dentry *dentry,
const char *symname)
{
- int err = 0;
+ int err;
struct dentry *lower_dentry;
struct dentry *lower_parent_dentry = NULL;
struct path lower_path;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_symlink(lower_parent_dentry->d_inode, lower_dentry, symname);
+ err = vfs_symlink(d_inode(lower_parent_dentry), lower_dentry, symname);
if (err)
goto out;
err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path);
if (err)
goto out;
fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
+ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
unlock_dir(lower_parent_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
REVERT_CRED();
return 0;
}
-static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
- int err = 0;
+ int err;
int make_nomedia_in_obb = 0;
struct dentry *lower_dentry;
struct dentry *lower_parent_dentry = NULL;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
-
/* set last 16bytes of mode field to 0775 */
mode = (mode & S_IFMT) | 00775;
- err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, mode);
+ err = vfs_mkdir(d_inode(lower_parent_dentry), lower_dentry, mode);
if (err)
goto out;
goto out;
fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
+ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
/* update number of links on parent directory */
- dir->i_nlink = sdcardfs_lower_inode(dir)->i_nlink;
+ set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink);
if ((sbi->options.derive == DERIVE_UNIFIED) && (!strcasecmp(dentry->d_name.name, "obb"))
&& (pi->perm == PERM_ANDROID) && (pi->userid == 0))
kfree(nomedia_fullpath);
}
out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
unlock_dir(lower_parent_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
out_revert:
lower_dentry = lower_path.dentry;
lower_dir_dentry = lock_parent(lower_dentry);
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
+ err = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry);
if (err)
goto out;
d_drop(dentry); /* drop our dentry on success (why not VFS's job?) */
- if (dentry->d_inode)
- clear_nlink(dentry->d_inode);
- fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
- fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
- dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
+ if (d_inode(dentry))
+ clear_nlink(d_inode(dentry));
+ fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
+ fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
+ set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink);
out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
unlock_dir(lower_dir_dentry);
sdcardfs_put_real_lower(dentry, &lower_path);
REVERT_CRED(saved_cred);
}
#if 0
-static int sdcardfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+static int sdcardfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
dev_t dev)
{
- int err = 0;
+ int err;
struct dentry *lower_dentry;
struct dentry *lower_parent_dentry = NULL;
struct path lower_path;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev);
+ err = vfs_mknod(d_inode(lower_parent_dentry), lower_dentry, mode, dev);
if (err)
goto out;
if (err)
goto out;
fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
+ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
unlock_dir(lower_parent_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
REVERT_CRED();
goto out;
}
- err = mnt_want_write(lower_old_path.mnt);
+ err = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
+ d_inode(lower_new_dir_dentry), lower_new_dentry,
+ NULL, 0);
if (err)
goto out;
- err = mnt_want_write(lower_new_path.mnt);
- if (err)
- goto out_drop_old_write;
-
- err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
- lower_new_dir_dentry->d_inode, lower_new_dentry);
- if (err)
- goto out_err;
/* Copy attrs from lower dir, but i_uid/i_gid */
- fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
- fsstack_copy_inode_size(new_dir, lower_new_dir_dentry->d_inode);
+ fsstack_copy_attr_all(new_dir, d_inode(lower_new_dir_dentry));
+ fsstack_copy_inode_size(new_dir, d_inode(lower_new_dir_dentry));
fix_derived_permission(new_dir);
if (new_dir != old_dir) {
- fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
- fsstack_copy_inode_size(old_dir, lower_old_dir_dentry->d_inode);
+ fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry));
+ fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry));
fix_derived_permission(old_dir);
/* update the derived permission of the old_dentry
* with its new parent
*/
new_parent = dget_parent(new_dentry);
if(new_parent) {
- if(old_dentry->d_inode) {
+ if(d_inode(old_dentry)) {
get_derived_permission(new_parent, old_dentry);
- fix_derived_permission(old_dentry->d_inode);
+ fix_derived_permission(d_inode(old_dentry));
}
dput(new_parent);
}
}
-out_err:
- mnt_drop_write(lower_new_path.mnt);
-out_drop_old_write:
- mnt_drop_write(lower_old_path.mnt);
out:
unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
dput(lower_old_dir_dentry);
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
- if (!lower_dentry->d_inode->i_op ||
- !lower_dentry->d_inode->i_op->readlink) {
+ if (!d_inode(lower_dentry)->i_op ||
+ !d_inode(lower_dentry)->i_op->readlink) {
err = -EINVAL;
goto out;
}
- err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
+ err = d_inode(lower_dentry)->i_op->readlink(lower_dentry,
buf, bufsiz);
if (err < 0)
goto out;
- fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
+ fsstack_copy_attr_atime(d_inode(dentry), d_inode(lower_dentry));
out:
sdcardfs_put_lower_path(dentry, &lower_path);
#endif
#if 0
-static void *sdcardfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *sdcardfs_follow_link(struct dentry *dentry, void **cookie)
{
char *buf;
int len = PAGE_SIZE, err;
buf = kmalloc(len, GFP_KERNEL);
if (!buf) {
buf = ERR_PTR(-ENOMEM);
- goto out;
+ return buf;
}
/* read the symlink, and then we will follow it */
} else {
buf[err] = '\0';
}
-out:
- nd_set_link(nd, buf);
- return NULL;
-}
-#endif
-
-#if 0
-/* this @nd *IS* still used */
-static void sdcardfs_put_link(struct dentry *dentry, struct nameidata *nd,
- void *cookie)
-{
- char *buf = nd_get_link(nd);
- if (!IS_ERR(buf)) /* free the char* */
- kfree(buf);
+ return *cookie = buf;
}
#endif
-static int sdcardfs_permission(struct inode *inode, int mask, unsigned int flags)
+static int sdcardfs_permission(struct inode *inode, int mask)
{
int err;
- if (flags & IPERM_FLAG_RCU)
- return -ECHILD;
-
/*
* Permission check on sdcardfs inode.
* Calling process should have AID_SDCARD_RW permission
*/
- err = generic_permission(inode, mask, 0, inode->i_op->check_acl);
+ err = generic_permission(inode, mask);
/* XXX
* Original sdcardfs code calls inode_permission(lower_inode,.. )
}
-static int sdcardfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
- struct kstat *stat)
-{
- struct dentry *lower_dentry;
- struct inode *inode;
- struct inode *lower_inode;
- struct path lower_path;
- struct dentry *parent;
- struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
-
- parent = dget_parent(dentry);
- if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name,
- sbi->options.derive, 0, 0)) {
- printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
- " dentry: %s, task:%s\n",
- __func__, dentry->d_name.name, current->comm);
- dput(parent);
- return -EACCES;
- }
- dput(parent);
-
- inode = dentry->d_inode;
-
- sdcardfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- lower_inode = sdcardfs_lower_inode(inode);
-
- fsstack_copy_attr_all(inode, lower_inode);
- fsstack_copy_inode_size(inode, lower_inode);
- /* if the dentry has been moved from other location
- * so, on this stage, its derived permission must be
- * rechecked from its private field.
- */
- fix_derived_permission(inode);
-
- generic_fillattr(inode, stat);
- sdcardfs_put_lower_path(dentry, &lower_path);
- return 0;
-}
-
static int sdcardfs_setattr(struct dentry *dentry, struct iattr *ia)
{
- int err = 0;
+ int err;
struct dentry *lower_dentry;
struct inode *inode;
struct inode *lower_inode;
struct dentry *parent;
int has_rw;
- inode = dentry->d_inode;
+ inode = d_inode(dentry);
/*
* Check if user has permission to change inode. We don't check if
/* check the Android group ID */
has_rw = get_caller_has_rw_locked(sbi->pkgl_id, sbi->options.derive);
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name,
+ if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name,
sbi->options.derive, 1, has_rw)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
/* notify the (possibly copied-up) lower inode */
/*
- * Note: we use lower_dentry->d_inode, because lower_inode may be
+ * Note: we use d_inode(lower_dentry), because lower_inode may be
* unlinked (no inode->i_sb and i_ino==0. This happens if someone
* tries to open(), unlink(), then ftruncate() a file.
*/
- mutex_lock(&lower_dentry->d_inode->i_mutex);
- err = notify_change(lower_dentry, &lower_ia); /* note: lower_ia */
- mutex_unlock(&lower_dentry->d_inode->i_mutex);
+ mutex_lock(&d_inode(lower_dentry)->i_mutex);
+ err = notify_change(lower_dentry, &lower_ia, /* note: lower_ia */
+ NULL);
+ mutex_unlock(&d_inode(lower_dentry)->i_mutex);
if (current->mm)
up_write(¤t->mm->mmap_sem);
if (err)
return err;
}
+static int sdcardfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct dentry *lower_dentry;
+ struct inode *inode;
+ struct inode *lower_inode;
+ struct path lower_path;
+ struct dentry *parent;
+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
+
+ parent = dget_parent(dentry);
+ if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name,
+ sbi->options.derive, 0, 0)) {
+ printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
+ " dentry: %s, task:%s\n",
+ __func__, dentry->d_name.name, current->comm);
+ dput(parent);
+ return -EACCES;
+ }
+ dput(parent);
+
+ inode = d_inode(dentry);
+
+ sdcardfs_get_lower_path(dentry, &lower_path);
+ lower_dentry = lower_path.dentry;
+ lower_inode = sdcardfs_lower_inode(inode);
+
+ fsstack_copy_attr_all(inode, lower_inode);
+ fsstack_copy_inode_size(inode, lower_inode);
+ /* if the dentry has been moved from other location
+ * so, on this stage, its derived permission must be
+ * rechecked from its private field.
+ */
+ fix_derived_permission(inode);
+
+ generic_fillattr(inode, stat);
+ sdcardfs_put_lower_path(dentry, &lower_path);
+ return 0;
+}
+
const struct inode_operations sdcardfs_symlink_iops = {
.permission = sdcardfs_permission,
.setattr = sdcardfs_setattr,
* These methods are *NOT* perfectly tested.
.readlink = sdcardfs_readlink,
.follow_link = sdcardfs_follow_link,
- .put_link = sdcardfs_put_link,
+ .put_link = kfree_put_link,
*/
};
const struct inode_operations sdcardfs_dir_iops = {
.create = sdcardfs_create,
.lookup = sdcardfs_lookup,
+#if 0
.permission = sdcardfs_permission,
+#endif
.unlink = sdcardfs_unlink,
.mkdir = sdcardfs_mkdir,
.rmdir = sdcardfs_rmdir,