summaryrefslogtreecommitdiff
path: root/fs/overlayfs/util.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-01-17 06:34:56 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2017-02-07 15:47:14 +0100
commit39d3d60a54df05a1a32fa71159d7a26a530dee6c (patch)
tree176b1873dbc9d1a96abccf597ca91c82d27de87d /fs/overlayfs/util.c
parentd8514d8edb5b045cf7f708e14f888ce760d60f0b (diff)
ovl: introduce copy up waitqueue
The overlay sb 'copyup_wq' and overlay inode 'copying' condition variable are about to replace the upper sb rename_lock, as finer grained synchronization objects for concurrent copy up. Suggested-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/util.c')
-rw-r--r--fs/overlayfs/util.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 952286f4826c..01157d6e8cfe 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -263,3 +263,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);
+}