summaryrefslogtreecommitdiff
path: root/fs/overlayfs/util.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-03 11:55:57 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-03 12:02:42 -0800
commite58bc927835a6f5ddbe4d2e069c9082b706810e7 (patch)
treea7d6a2d637e324c5dad98540d1d293aaf3924d28 /fs/overlayfs/util.c
parent590dce2d4934fb909b112cd80c80486362337744 (diff)
parent51f8f3c4e22535933ef9aecc00e9a6069e051b57 (diff)
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs updates from Miklos Szeredi: "Because copy up can take a long time, serialized copy ups could be a big performance bottleneck. This update allows concurrent copy up of regular files eliminating this potential problem. There are also minor fixes" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: drop CAP_SYS_RESOURCE from saved mounter's credentials ovl: properly implement sync_filesystem() ovl: concurrent copy up of regular files ovl: introduce copy up waitqueue ovl: copy up regular file using O_TMPFILE ovl: rearrange code in ovl_copy_up_locked() ovl: check if upperdir fs supports O_TMPFILE
Diffstat (limited to 'fs/overlayfs/util.c')
-rw-r--r--fs/overlayfs/util.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 9dc1c0af586b..1953986ee6bc 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/cred.h>
#include <linux/xattr.h>
+#include <linux/sched/signal.h>
#include "overlayfs.h"
#include "ovl_entry.h"
@@ -264,3 +265,33 @@ struct file *ovl_path_open(struct path *path, int flags)
{
return dentry_open(path, flags | O_NOATIME, current_cred());
}
+
+int ovl_copy_up_start(struct dentry *dentry)
+{
+ struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
+ struct ovl_entry *oe = dentry->d_fsdata;
+ int err;
+
+ spin_lock(&ofs->copyup_wq.lock);
+ err = wait_event_interruptible_locked(ofs->copyup_wq, !oe->copying);
+ if (!err) {
+ if (oe->__upperdentry)
+ err = 1; /* Already copied up */
+ else
+ oe->copying = true;
+ }
+ spin_unlock(&ofs->copyup_wq.lock);
+
+ return err;
+}
+
+void ovl_copy_up_end(struct dentry *dentry)
+{
+ struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
+ struct ovl_entry *oe = dentry->d_fsdata;
+
+ spin_lock(&ofs->copyup_wq.lock);
+ oe->copying = false;
+ wake_up_locked(&ofs->copyup_wq);
+ spin_unlock(&ofs->copyup_wq.lock);
+}