summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/dir.c
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2016-07-01 16:34:28 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-07-29 12:05:23 +0200
commit1175b6b8d96331676f1d436b089b965807f23b4a (patch)
treee28f45dd3c2760062fc15f1b34844b345c925d14 /fs/overlayfs/dir.c
parentc0ca3d70e8d3cf81e2255a217f7ca402f5ed0862 (diff)
downloadlinux-0-day-1175b6b8d96331676f1d436b089b965807f23b4a.tar.gz
linux-0-day-1175b6b8d96331676f1d436b089b965807f23b4a.tar.xz
ovl: do operations on underlying file system in mounter's context
Given we are now doing checks both on overlay inode as well underlying inode, we should be able to do checks and operations on underlying file system using mounter's context. So modify all operations to do checks/operations on underlying dentry/inode in the context of mounter. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/dir.c')
-rw-r--r--fs/overlayfs/dir.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index aa63205571967..7195306e9f843 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -138,9 +138,12 @@ static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
int err;
enum ovl_path_type type;
struct path realpath;
+ const struct cred *old_cred;
type = ovl_path_real(dentry, &realpath);
+ old_cred = ovl_override_creds(dentry->d_sb);
err = vfs_getattr(&realpath, stat);
+ revert_creds(old_cred);
if (err)
return err;
@@ -391,6 +394,8 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev,
{
int err;
struct inode *inode;
+ const struct cred *old_cred;
+ struct cred *override_cred;
struct kstat stat = {
.mode = mode,
.rdev = rdev,
@@ -405,28 +410,23 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev,
if (err)
goto out_iput;
- if (!ovl_dentry_is_opaque(dentry)) {
- err = ovl_create_upper(dentry, inode, &stat, link, hardlink);
- } else {
- const struct cred *old_cred;
- struct cred *override_cred;
-
- old_cred = ovl_override_creds(dentry->d_sb);
-
- err = -ENOMEM;
- override_cred = prepare_creds();
- if (override_cred) {
- override_cred->fsuid = old_cred->fsuid;
- override_cred->fsgid = old_cred->fsgid;
- put_cred(override_creds(override_cred));
- put_cred(override_cred);
-
+ old_cred = ovl_override_creds(dentry->d_sb);
+ err = -ENOMEM;
+ override_cred = prepare_creds();
+ if (override_cred) {
+ override_cred->fsuid = old_cred->fsuid;
+ override_cred->fsgid = old_cred->fsgid;
+ put_cred(override_creds(override_cred));
+ put_cred(override_cred);
+
+ if (!ovl_dentry_is_opaque(dentry))
+ err = ovl_create_upper(dentry, inode, &stat, link,
+ hardlink);
+ else
err = ovl_create_over_whiteout(dentry, inode, &stat,
- link, hardlink);
- }
- revert_creds(old_cred);
+ link, hardlink);
}
-
+ revert_creds(old_cred);
if (!err)
inode = NULL;
out_iput:
@@ -637,6 +637,8 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
{
enum ovl_path_type type;
int err;
+ const struct cred *old_cred;
+
err = ovl_check_sticky(dentry);
if (err)
@@ -651,15 +653,13 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
goto out_drop_write;
type = ovl_path_type(dentry);
- if (OVL_TYPE_PURE_UPPER(type)) {
- err = ovl_remove_upper(dentry, is_dir);
- } else {
- const struct cred *old_cred = ovl_override_creds(dentry->d_sb);
+ old_cred = ovl_override_creds(dentry->d_sb);
+ if (OVL_TYPE_PURE_UPPER(type))
+ err = ovl_remove_upper(dentry, is_dir);
+ else
err = ovl_remove_and_whiteout(dentry, is_dir);
-
- revert_creds(old_cred);
- }
+ revert_creds(old_cred);
out_drop_write:
ovl_drop_write(dentry);
out:
@@ -764,8 +764,7 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old,
old_opaque = !OVL_TYPE_PURE_UPPER(old_type);
new_opaque = !OVL_TYPE_PURE_UPPER(new_type);
- if (old_opaque || new_opaque)
- old_cred = ovl_override_creds(old->d_sb);
+ old_cred = ovl_override_creds(old->d_sb);
if (overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) {
opaquedir = ovl_check_empty_and_clear(new);
@@ -895,8 +894,7 @@ out_dput_old:
out_unlock:
unlock_rename(new_upperdir, old_upperdir);
out_revert_creds:
- if (old_opaque || new_opaque)
- revert_creds(old_cred);
+ revert_creds(old_cred);
out_drop_write:
ovl_drop_write(old);
out: