Commit a015dafc authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

ovl: use ovl_inode mutex to synchronize concurrent copy up

Use the new ovl_inode mutex to synchonize concurrent copy up
instead of the super block copy up workqueue.

Moving the synchronization object from the overlay dentry to
the overlay inode is needed for synchonizing concurrent copy up
of lower hardlinks to the same upper inode.
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 13c72075
...@@ -29,7 +29,6 @@ struct ovl_fs { ...@@ -29,7 +29,6 @@ struct ovl_fs {
const struct cred *creator_cred; const struct cred *creator_cred;
bool tmpfile; bool tmpfile;
bool noxattr; bool noxattr;
wait_queue_head_t copyup_wq;
/* sb common to all layers */ /* sb common to all layers */
struct super_block *same_sb; struct super_block *same_sb;
}; };
...@@ -41,7 +40,6 @@ struct ovl_entry { ...@@ -41,7 +40,6 @@ struct ovl_entry {
struct { struct {
u64 version; u64 version;
bool opaque; bool opaque;
bool copying;
}; };
struct rcu_head rcu; struct rcu_head rcu;
}; };
...@@ -57,6 +55,9 @@ struct ovl_inode { ...@@ -57,6 +55,9 @@ struct ovl_inode {
struct inode vfs_inode; struct inode vfs_inode;
struct dentry *__upperdentry; struct dentry *__upperdentry;
struct inode *lower; struct inode *lower;
/* synchronize copy up and more */
struct mutex lock;
}; };
static inline struct ovl_inode *OVL_I(struct inode *inode) static inline struct ovl_inode *OVL_I(struct inode *inode)
......
...@@ -173,6 +173,7 @@ static struct inode *ovl_alloc_inode(struct super_block *sb) ...@@ -173,6 +173,7 @@ static struct inode *ovl_alloc_inode(struct super_block *sb)
oi->flags = 0; oi->flags = 0;
oi->__upperdentry = NULL; oi->__upperdentry = NULL;
oi->lower = NULL; oi->lower = NULL;
mutex_init(&oi->lock);
return &oi->vfs_inode; return &oi->vfs_inode;
} }
...@@ -190,6 +191,7 @@ static void ovl_destroy_inode(struct inode *inode) ...@@ -190,6 +191,7 @@ static void ovl_destroy_inode(struct inode *inode)
dput(oi->__upperdentry); dput(oi->__upperdentry);
kfree(oi->redirect); kfree(oi->redirect);
mutex_destroy(&oi->lock);
call_rcu(&inode->i_rcu, ovl_i_callback); call_rcu(&inode->i_rcu, ovl_i_callback);
} }
...@@ -782,7 +784,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) ...@@ -782,7 +784,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
if (!ufs) if (!ufs)
goto out; goto out;
init_waitqueue_head(&ufs->copyup_wq);
ufs->config.redirect_dir = ovl_redirect_dir_def; ufs->config.redirect_dir = ovl_redirect_dir_def;
err = ovl_parse_opt((char *) data, &ufs->config); err = ovl_parse_opt((char *) data, &ufs->config);
if (err) if (err)
......
...@@ -270,32 +270,21 @@ struct file *ovl_path_open(struct path *path, int flags) ...@@ -270,32 +270,21 @@ struct file *ovl_path_open(struct path *path, int flags)
int ovl_copy_up_start(struct dentry *dentry) int ovl_copy_up_start(struct dentry *dentry)
{ {
struct ovl_fs *ofs = dentry->d_sb->s_fs_info; struct ovl_inode *oi = OVL_I(d_inode(dentry));
struct ovl_entry *oe = dentry->d_fsdata;
int err; int err;
spin_lock(&ofs->copyup_wq.lock); err = mutex_lock_interruptible(&oi->lock);
err = wait_event_interruptible_locked(ofs->copyup_wq, !oe->copying); if (!err && ovl_dentry_upper(dentry)) {
if (!err) { err = 1; /* Already copied up */
if (ovl_dentry_upper(dentry)) mutex_unlock(&oi->lock);
err = 1; /* Already copied up */
else
oe->copying = true;
} }
spin_unlock(&ofs->copyup_wq.lock);
return err; return err;
} }
void ovl_copy_up_end(struct dentry *dentry) void ovl_copy_up_end(struct dentry *dentry)
{ {
struct ovl_fs *ofs = dentry->d_sb->s_fs_info; mutex_unlock(&OVL_I(d_inode(dentry))->lock);
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);
} }
bool ovl_check_dir_xattr(struct dentry *dentry, const char *name) bool ovl_check_dir_xattr(struct dentry *dentry, const char *name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment