diff options
author | Jan Kara <jack@suse.cz> | 2009-06-02 08:24:03 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2009-06-03 22:14:30 -0400 |
commit | edd45c08499a3e9d4c25431cd2b6a9ce5f692c92 (patch) | |
tree | 13016ad69aa059604c1d71809d66a92f60124fd4 /fs/ocfs2/dir.c | |
parent | 80d73f15d12f087f3fe074f8a4d6e5c5624f2b47 (diff) |
ocfs2: Correct ordering of ip_alloc_sem and localloc locks for directories
We use ordering ip_alloc_sem -> local alloc locks in ocfs2_write_begin().
So change lock ordering in ocfs2_extend_dir() and ocfs2_expand_inline_dir()
to also use this lock ordering.
Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r-- | fs/ocfs2/dir.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index c5752305627c..b358f3bf896d 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -2900,6 +2900,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
2900 | alloc = ocfs2_clusters_for_bytes(sb, bytes); | 2900 | alloc = ocfs2_clusters_for_bytes(sb, bytes); |
2901 | dx_alloc = 0; | 2901 | dx_alloc = 0; |
2902 | 2902 | ||
2903 | down_write(&oi->ip_alloc_sem); | ||
2904 | |||
2903 | if (ocfs2_supports_indexed_dirs(osb)) { | 2905 | if (ocfs2_supports_indexed_dirs(osb)) { |
2904 | credits += ocfs2_add_dir_index_credits(sb); | 2906 | credits += ocfs2_add_dir_index_credits(sb); |
2905 | 2907 | ||
@@ -2940,8 +2942,6 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
2940 | goto out; | 2942 | goto out; |
2941 | } | 2943 | } |
2942 | 2944 | ||
2943 | down_write(&oi->ip_alloc_sem); | ||
2944 | |||
2945 | /* | 2945 | /* |
2946 | * Prepare for worst case allocation scenario of two separate | 2946 | * Prepare for worst case allocation scenario of two separate |
2947 | * extents in the unindexed tree. | 2947 | * extents in the unindexed tree. |
@@ -2953,7 +2953,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
2953 | if (IS_ERR(handle)) { | 2953 | if (IS_ERR(handle)) { |
2954 | ret = PTR_ERR(handle); | 2954 | ret = PTR_ERR(handle); |
2955 | mlog_errno(ret); | 2955 | mlog_errno(ret); |
2956 | goto out_sem; | 2956 | goto out; |
2957 | } | 2957 | } |
2958 | 2958 | ||
2959 | if (vfs_dq_alloc_space_nodirty(dir, | 2959 | if (vfs_dq_alloc_space_nodirty(dir, |
@@ -3172,10 +3172,8 @@ out_commit: | |||
3172 | 3172 | ||
3173 | ocfs2_commit_trans(osb, handle); | 3173 | ocfs2_commit_trans(osb, handle); |
3174 | 3174 | ||
3175 | out_sem: | ||
3176 | up_write(&oi->ip_alloc_sem); | ||
3177 | |||
3178 | out: | 3175 | out: |
3176 | up_write(&oi->ip_alloc_sem); | ||
3179 | if (data_ac) | 3177 | if (data_ac) |
3180 | ocfs2_free_alloc_context(data_ac); | 3178 | ocfs2_free_alloc_context(data_ac); |
3181 | if (meta_ac) | 3179 | if (meta_ac) |
@@ -3322,11 +3320,15 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
3322 | brelse(new_bh); | 3320 | brelse(new_bh); |
3323 | new_bh = NULL; | 3321 | new_bh = NULL; |
3324 | 3322 | ||
3323 | down_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
3324 | drop_alloc_sem = 1; | ||
3325 | dir_i_size = i_size_read(dir); | 3325 | dir_i_size = i_size_read(dir); |
3326 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; | 3326 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; |
3327 | goto do_extend; | 3327 | goto do_extend; |
3328 | } | 3328 | } |
3329 | 3329 | ||
3330 | down_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
3331 | drop_alloc_sem = 1; | ||
3330 | dir_i_size = i_size_read(dir); | 3332 | dir_i_size = i_size_read(dir); |
3331 | mlog(0, "extending dir %llu (i_size = %lld)\n", | 3333 | mlog(0, "extending dir %llu (i_size = %lld)\n", |
3332 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); | 3334 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); |
@@ -3370,9 +3372,6 @@ do_extend: | |||
3370 | credits++; /* For attaching the new dirent block to the | 3372 | credits++; /* For attaching the new dirent block to the |
3371 | * dx_root */ | 3373 | * dx_root */ |
3372 | 3374 | ||
3373 | down_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
3374 | drop_alloc_sem = 1; | ||
3375 | |||
3376 | handle = ocfs2_start_trans(osb, credits); | 3375 | handle = ocfs2_start_trans(osb, credits); |
3377 | if (IS_ERR(handle)) { | 3376 | if (IS_ERR(handle)) { |
3378 | status = PTR_ERR(handle); | 3377 | status = PTR_ERR(handle); |
@@ -3435,10 +3434,10 @@ bail_bh: | |||
3435 | *new_de_bh = new_bh; | 3434 | *new_de_bh = new_bh; |
3436 | get_bh(*new_de_bh); | 3435 | get_bh(*new_de_bh); |
3437 | bail: | 3436 | bail: |
3438 | if (drop_alloc_sem) | ||
3439 | up_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
3440 | if (handle) | 3437 | if (handle) |
3441 | ocfs2_commit_trans(osb, handle); | 3438 | ocfs2_commit_trans(osb, handle); |
3439 | if (drop_alloc_sem) | ||
3440 | up_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
3442 | 3441 | ||
3443 | if (data_ac) | 3442 | if (data_ac) |
3444 | ocfs2_free_alloc_context(data_ac); | 3443 | ocfs2_free_alloc_context(data_ac); |