aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2017-07-04 22:03:18 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2017-07-04 22:03:18 +0200
commit7d90b853f932874f0b348858fddbd41f022179ee (patch)
treee28f87cbf2f0ed094ca899667dfe07ee79ee77fd /fs/overlayfs
parentovl: defer upper dir lock to tempfile link (diff)
downloadlinux-dev-7d90b853f932874f0b348858fddbd41f022179ee.tar.xz
linux-dev-7d90b853f932874f0b348858fddbd41f022179ee.zip
ovl: extract helper to get temp file in copy up
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/copy_up.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 28711af7f9db..a7941ab80c9b 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -345,16 +345,13 @@ static int ovl_install_temp(struct dentry *workdir, struct dentry *upperdir,
return err;
}
-static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
- struct dentry *dentry, struct path *lowerpath,
- struct kstat *stat, const char *link,
- struct kstat *pstat, bool tmpfile)
+static int ovl_get_tmpfile(struct dentry *workdir, struct dentry *upperdir,
+ struct dentry *dentry,
+ struct kstat *stat, const char *link, bool tmpfile,
+ struct dentry **tempp)
{
- struct inode *wdir = workdir->d_inode;
- struct inode *udir = upperdir->d_inode;
- struct dentry *newdentry = NULL;
- struct dentry *temp = NULL;
int err;
+ struct dentry *temp;
const struct cred *old_creds = NULL;
struct cred *new_creds = NULL;
struct cattr cattr = {
@@ -371,24 +368,50 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
if (new_creds)
old_creds = override_creds(new_creds);
- if (tmpfile)
+ if (tmpfile) {
temp = ovl_do_tmpfile(upperdir, stat->mode);
- else
+ if (IS_ERR(temp))
+ goto temp_err;
+ } else {
temp = ovl_lookup_temp(workdir);
- err = 0;
- if (IS_ERR(temp)) {
- err = PTR_ERR(temp);
- temp = NULL;
+ if (IS_ERR(temp))
+ goto temp_err;
+
+ err = ovl_create_real(d_inode(workdir), temp, &cattr,
+ NULL, true);
+ if (err) {
+ dput(temp);
+ goto out;
+ }
}
-
- if (!err && !tmpfile)
- err = ovl_create_real(wdir, temp, &cattr, NULL, true);
-
+ err = 0;
+ *tempp = temp;
+out:
if (new_creds) {
revert_creds(old_creds);
put_cred(new_creds);
}
+ return err;
+
+temp_err:
+ err = PTR_ERR(temp);
+ goto out;
+}
+
+static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
+ struct dentry *dentry, struct path *lowerpath,
+ struct kstat *stat, const char *link,
+ struct kstat *pstat, bool tmpfile)
+{
+ struct inode *wdir = workdir->d_inode;
+ struct inode *udir = upperdir->d_inode;
+ struct dentry *newdentry = NULL;
+ struct dentry *temp = NULL;
+ int err;
+
+ err = ovl_get_tmpfile(workdir, upperdir, dentry, stat, link, tmpfile,
+ &temp);
if (err)
goto out;