Commit 8d5596c6 authored by Mark Fasheh's avatar Mark Fasheh

ocfs2: don't pass handle to ocfs2_meta_lock in ocfs2_rename()

Take and drop the locks directly.
Signed-off-by: default avatarMark Fasheh <mark.fasheh@oracle.com>
parent 6d8fc40e
...@@ -104,13 +104,6 @@ static int ocfs2_fill_new_dir(struct ocfs2_super *osb, ...@@ -104,13 +104,6 @@ static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
struct buffer_head *fe_bh, struct buffer_head *fe_bh,
struct ocfs2_alloc_context *data_ac); struct ocfs2_alloc_context *data_ac);
static int ocfs2_double_lock(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct buffer_head **bh1,
struct inode *inode1,
struct buffer_head **bh2,
struct inode *inode2);
static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
struct inode **ret_orphan_dir, struct inode **ret_orphan_dir,
struct inode *inode, struct inode *inode,
...@@ -992,7 +985,6 @@ static int ocfs2_unlink(struct inode *dir, ...@@ -992,7 +985,6 @@ static int ocfs2_unlink(struct inode *dir,
* if they have the same id, then the 1st one is the only one locked. * if they have the same id, then the 1st one is the only one locked.
*/ */
static int ocfs2_double_lock(struct ocfs2_super *osb, static int ocfs2_double_lock(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct buffer_head **bh1, struct buffer_head **bh1,
struct inode *inode1, struct inode *inode1,
struct buffer_head **bh2, struct buffer_head **bh2,
...@@ -1008,8 +1000,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, ...@@ -1008,8 +1000,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
(unsigned long long)oi1->ip_blkno, (unsigned long long)oi1->ip_blkno,
(unsigned long long)oi2->ip_blkno); (unsigned long long)oi2->ip_blkno);
BUG_ON(!handle);
if (*bh1) if (*bh1)
*bh1 = NULL; *bh1 = NULL;
if (*bh2) if (*bh2)
...@@ -1029,25 +1019,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, ...@@ -1029,25 +1019,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
inode1 = tmpinode; inode1 = tmpinode;
} }
/* lock id2 */ /* lock id2 */
status = ocfs2_meta_lock(inode2, handle, bh2, 1); status = ocfs2_meta_lock(inode2, NULL, bh2, 1);
if (status < 0) { if (status < 0) {
if (status != -ENOENT) if (status != -ENOENT)
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
} }
/* lock id1 */ /* lock id1 */
status = ocfs2_meta_lock(inode1, handle, bh1, 1); status = ocfs2_meta_lock(inode1, NULL, bh1, 1);
if (status < 0) { if (status < 0) {
/*
* An error return must mean that no cluster locks
* were held on function exit.
*/
if (oi1->ip_blkno != oi2->ip_blkno)
ocfs2_meta_unlock(inode2, 1);
if (status != -ENOENT) if (status != -ENOENT)
mlog_errno(status); mlog_errno(status);
goto bail;
} }
bail: bail:
mlog_exit(status); mlog_exit(status);
return status; return status;
} }
static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2)
{
ocfs2_meta_unlock(inode1, 1);
if (inode1 != inode2)
ocfs2_meta_unlock(inode2, 1);
}
#define PARENT_INO(buffer) \ #define PARENT_INO(buffer) \
((struct ocfs2_dir_entry *) \ ((struct ocfs2_dir_entry *) \
((char *)buffer + \ ((char *)buffer + \
...@@ -1058,7 +1064,8 @@ static int ocfs2_rename(struct inode *old_dir, ...@@ -1058,7 +1064,8 @@ static int ocfs2_rename(struct inode *old_dir,
struct inode *new_dir, struct inode *new_dir,
struct dentry *new_dentry) struct dentry *new_dentry)
{ {
int status = 0, rename_lock = 0; int status = 0, rename_lock = 0, parents_locked = 0;
int old_child_locked = 0, new_child_locked = 0;
struct inode *old_inode = old_dentry->d_inode; struct inode *old_inode = old_dentry->d_inode;
struct inode *new_inode = new_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode;
struct inode *orphan_dir = NULL; struct inode *orphan_dir = NULL;
...@@ -1122,13 +1129,13 @@ static int ocfs2_rename(struct inode *old_dir, ...@@ -1122,13 +1129,13 @@ static int ocfs2_rename(struct inode *old_dir,
} }
/* if old and new are the same, this'll just do one lock. */ /* if old and new are the same, this'll just do one lock. */
status = ocfs2_double_lock(osb, handle, status = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
&old_dir_bh, old_dir,
&new_dir_bh, new_dir); &new_dir_bh, new_dir);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
parents_locked = 1;
/* make sure both dirs have bhs /* make sure both dirs have bhs
* get an extra ref on old_dir_bh if old==new */ * get an extra ref on old_dir_bh if old==new */
...@@ -1149,12 +1156,13 @@ static int ocfs2_rename(struct inode *old_dir, ...@@ -1149,12 +1156,13 @@ static int ocfs2_rename(struct inode *old_dir,
* the vote thread on other nodes won't have to concurrently * the vote thread on other nodes won't have to concurrently
* downconvert the inode and the dentry locks. * downconvert the inode and the dentry locks.
*/ */
status = ocfs2_meta_lock(old_inode, handle, NULL, 1); status = ocfs2_meta_lock(old_inode, NULL, NULL, 1);
if (status < 0) { if (status < 0) {
if (status != -ENOENT) if (status != -ENOENT)
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
old_child_locked = 1;
status = ocfs2_remote_dentry_delete(old_dentry); status = ocfs2_remote_dentry_delete(old_dentry);
if (status < 0) { if (status < 0) {
...@@ -1240,12 +1248,13 @@ static int ocfs2_rename(struct inode *old_dir, ...@@ -1240,12 +1248,13 @@ static int ocfs2_rename(struct inode *old_dir,
goto bail; goto bail;
} }
status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1); status = ocfs2_meta_lock(new_inode, NULL, &newfe_bh, 1);
if (status < 0) { if (status < 0) {
if (status != -ENOENT) if (status != -ENOENT)
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
new_child_locked = 1;
status = ocfs2_remote_dentry_delete(new_dentry); status = ocfs2_remote_dentry_delete(new_dentry);
if (status < 0) { if (status < 0) {
...@@ -1435,6 +1444,15 @@ static int ocfs2_rename(struct inode *old_dir, ...@@ -1435,6 +1444,15 @@ static int ocfs2_rename(struct inode *old_dir,
if (handle) if (handle)
ocfs2_commit_trans(handle); ocfs2_commit_trans(handle);
if (parents_locked)
ocfs2_double_unlock(old_dir, new_dir);
if (old_child_locked)
ocfs2_meta_unlock(old_inode, 1);
if (new_child_locked)
ocfs2_meta_unlock(new_inode, 1);
if (orphan_dir) { if (orphan_dir) {
/* This was locked for us in ocfs2_prepare_orphan_dir() */ /* This was locked for us in ocfs2_prepare_orphan_dir() */
ocfs2_meta_unlock(orphan_dir, 1); ocfs2_meta_unlock(orphan_dir, 1);
......
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