#include "wrapfs.h"
-static int wrapfs_create(struct inode *dir, struct dentry *dentry,
+static int wrapfs_create(struct user_namespace *mnt_userns,
+ struct inode *dir, struct dentry *dentry,
umode_t mode, bool want_excl)
{
int err;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = vfs_create(d_inode(lower_parent_dentry), lower_dentry, mode,
+ err = vfs_create(&init_user_ns, d_inode(lower_parent_dentry),
+ lower_dentry, mode,
want_excl);
if (err)
goto out;
lower_new_dentry = lower_new_path.dentry;
lower_dir_dentry = lock_parent(lower_new_dentry);
- err = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
- lower_new_dentry, NULL);
+ err = vfs_link(lower_old_dentry, &init_user_ns,
+ d_inode(lower_dir_dentry), lower_new_dentry, NULL);
if (err || d_really_is_negative(lower_new_dentry))
goto out;
goto out;
}
- err = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
+ err = vfs_unlink(&init_user_ns, lower_dir_inode, lower_dentry,
+ NULL);
/*
* Note: unlinking on top of NFS can cause silly-renamed files.
return err;
}
-static int wrapfs_symlink(struct inode *dir, struct dentry *dentry,
+static int wrapfs_symlink(struct user_namespace *mnt_userns,
+ struct inode *dir, struct dentry *dentry,
const char *symname)
{
int err;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = vfs_symlink(d_inode(lower_parent_dentry), lower_dentry, symname);
+ err = vfs_symlink(&init_user_ns, d_inode(lower_parent_dentry),
+ lower_dentry, symname);
if (err)
goto out;
err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
return err;
}
-static int wrapfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+static int wrapfs_mkdir(struct user_namespace *mnt_userns,
+ struct inode *dir, struct dentry *dentry, umode_t mode)
{
int err;
struct dentry *lower_dentry;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = vfs_mkdir(d_inode(lower_parent_dentry), lower_dentry, mode);
+ err = vfs_mkdir(&init_user_ns, d_inode(lower_parent_dentry),
+ lower_dentry, mode);
if (err)
goto out;
goto out;
}
- err = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry);
+ err = vfs_rmdir(&init_user_ns, d_inode(lower_dir_dentry),
+ lower_dentry);
if (err)
goto out;
return err;
}
-static int wrapfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
- dev_t dev)
+static int wrapfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+ struct dentry *dentry, umode_t mode, dev_t dev)
{
int err;
struct dentry *lower_dentry;
lower_dentry = lower_path.dentry;
lower_parent_dentry = lock_parent(lower_dentry);
- err = vfs_mknod(d_inode(lower_parent_dentry), lower_dentry, mode, dev);
+ err = vfs_mknod(&init_user_ns, d_inode(lower_parent_dentry),
+ lower_dentry, mode, dev);
if (err)
goto out;
* The locking rules in wrapfs_rename are complex. We could use a simpler
* superblock-level name-space lock for renames and copy-ups.
*/
-static int wrapfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+static int wrapfs_rename(struct user_namespace *mnt_userns,
+ struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
{
struct dentry *lower_new_dir_dentry = NULL;
struct dentry *trap = NULL;
struct path lower_old_path, lower_new_path;
+ struct renamedata rd = {};
if (flags)
return -EINVAL;
goto out;
}
- err = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
- d_inode(lower_new_dir_dentry), lower_new_dentry,
- NULL, 0);
+ rd.old_mnt_userns = &init_user_ns;
+ rd.old_dir = d_inode(lower_old_dir_dentry);
+ rd.old_dentry = lower_old_dentry;
+ rd.new_mnt_userns = &init_user_ns;
+ rd.new_dir = d_inode(lower_new_dir_dentry);
+ rd.new_dentry = lower_new_dentry;
+ err = vfs_rename(&rd);
if (err)
goto out;
return buf;
}
-static int wrapfs_permission(struct inode *inode, int mask)
+static int wrapfs_permission(struct user_namespace *mnt_userns,
+ struct inode *inode, int mask)
{
struct inode *lower_inode;
int err;
lower_inode = wrapfs_lower_inode(inode);
- err = inode_permission(lower_inode, mask);
+ err = inode_permission(&init_user_ns, lower_inode, mask);
return err;
}
-static int wrapfs_setattr(struct dentry *dentry, struct iattr *ia)
+static int wrapfs_setattr(struct user_namespace *mnt_userns,
+ struct dentry *dentry, struct iattr *ia)
{
int err;
struct dentry *lower_dentry;
* this user can change the lower inode: that should happen when
* calling notify_change on the lower inode.
*/
- err = setattr_prepare(dentry, ia);
+ err = setattr_prepare(&init_user_ns, dentry, ia);
if (err)
goto out_err;
* tries to open(), unlink(), then ftruncate() a file.
*/
inode_lock(d_inode(lower_dentry));
- err = notify_change(lower_dentry, &lower_ia, /* note: lower_ia */
- NULL);
+ err = notify_change(&init_user_ns, lower_dentry, &lower_ia, NULL);
inode_unlock(d_inode(lower_dentry));
if (err)
goto out;
return err;
}
-static int wrapfs_getattr(const struct path *path, struct kstat *stat,
+static int wrapfs_getattr(struct user_namespace *mnt_userns,
+ const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
int err;
goto out;
fsstack_copy_attr_all(d_inode(dentry),
d_inode(lower_path.dentry));
- generic_fillattr(d_inode(dentry), stat);
+ generic_fillattr(&init_user_ns, d_inode(dentry), stat);
stat->blocks = lower_stat.blocks;
out:
wrapfs_put_lower_path(dentry, &lower_path);
err = -EOPNOTSUPP;
goto out;
}
- err = vfs_setxattr(lower_dentry, name, value, size, flags);
+ err = vfs_setxattr(&init_user_ns, lower_dentry, name, value, size, flags);
if (err)
goto out;
fsstack_copy_attr_all(d_inode(dentry),
err = -EOPNOTSUPP;
goto out;
}
- err = vfs_getxattr(lower_dentry, name, buffer, size);
+ err = vfs_getxattr(&init_user_ns, lower_dentry, name, buffer, size);
if (err)
goto out;
fsstack_copy_attr_atime(d_inode(dentry),
err = -EOPNOTSUPP;
goto out;
}
- err = vfs_removexattr(lower_dentry, name);
+ err = vfs_removexattr(&init_user_ns, lower_dentry, name);
if (err)
goto out;
fsstack_copy_attr_all(d_inode(dentry), lower_inode);
}
static int wrapfs_xattr_set(const struct xattr_handler *handler,
+ struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value, size_t size,
int flags)