diff options
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r-- | fs/ocfs2/dir.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 04e01915b86e..baad2aa27c14 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -82,6 +82,7 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
82 | struct inode *inode = filp->f_dentry->d_inode; | 82 | struct inode *inode = filp->f_dentry->d_inode; |
83 | struct super_block * sb = inode->i_sb; | 83 | struct super_block * sb = inode->i_sb; |
84 | unsigned int ra_sectors = 16; | 84 | unsigned int ra_sectors = 16; |
85 | int lock_level = 0; | ||
85 | 86 | ||
86 | mlog_entry("dirino=%llu\n", | 87 | mlog_entry("dirino=%llu\n", |
87 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 88 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
@@ -89,7 +90,15 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
89 | stored = 0; | 90 | stored = 0; |
90 | bh = NULL; | 91 | bh = NULL; |
91 | 92 | ||
92 | error = ocfs2_meta_lock(inode, NULL, NULL, 0); | 93 | error = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level); |
94 | if (lock_level && error >= 0) { | ||
95 | /* We release EX lock which used to update atime | ||
96 | * and get PR lock again to reduce contention | ||
97 | * on commonly accessed directories. */ | ||
98 | ocfs2_meta_unlock(inode, 1); | ||
99 | lock_level = 0; | ||
100 | error = ocfs2_meta_lock(inode, NULL, 0); | ||
101 | } | ||
93 | if (error < 0) { | 102 | if (error < 0) { |
94 | if (error != -ENOENT) | 103 | if (error != -ENOENT) |
95 | mlog_errno(error); | 104 | mlog_errno(error); |
@@ -198,7 +207,7 @@ revalidate: | |||
198 | 207 | ||
199 | stored = 0; | 208 | stored = 0; |
200 | bail: | 209 | bail: |
201 | ocfs2_meta_unlock(inode, 0); | 210 | ocfs2_meta_unlock(inode, lock_level); |
202 | 211 | ||
203 | bail_nolock: | 212 | bail_nolock: |
204 | mlog_exit(stored); | 213 | mlog_exit(stored); |
@@ -340,7 +349,7 @@ int ocfs2_empty_dir(struct inode *inode) | |||
340 | 349 | ||
341 | /* returns a bh of the 1st new block in the allocation. */ | 350 | /* returns a bh of the 1st new block in the allocation. */ |
342 | int ocfs2_do_extend_dir(struct super_block *sb, | 351 | int ocfs2_do_extend_dir(struct super_block *sb, |
343 | struct ocfs2_journal_handle *handle, | 352 | handle_t *handle, |
344 | struct inode *dir, | 353 | struct inode *dir, |
345 | struct buffer_head *parent_fe_bh, | 354 | struct buffer_head *parent_fe_bh, |
346 | struct ocfs2_alloc_context *data_ac, | 355 | struct ocfs2_alloc_context *data_ac, |
@@ -398,7 +407,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
398 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 407 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
399 | struct ocfs2_alloc_context *data_ac = NULL; | 408 | struct ocfs2_alloc_context *data_ac = NULL; |
400 | struct ocfs2_alloc_context *meta_ac = NULL; | 409 | struct ocfs2_alloc_context *meta_ac = NULL; |
401 | struct ocfs2_journal_handle *handle = NULL; | 410 | handle_t *handle = NULL; |
402 | struct buffer_head *new_bh = NULL; | 411 | struct buffer_head *new_bh = NULL; |
403 | struct ocfs2_dir_entry * de; | 412 | struct ocfs2_dir_entry * de; |
404 | struct super_block *sb = osb->sb; | 413 | struct super_block *sb = osb->sb; |
@@ -409,13 +418,6 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
409 | mlog(0, "extending dir %llu (i_size = %lld)\n", | 418 | mlog(0, "extending dir %llu (i_size = %lld)\n", |
410 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); | 419 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); |
411 | 420 | ||
412 | handle = ocfs2_alloc_handle(osb); | ||
413 | if (handle == NULL) { | ||
414 | status = -ENOMEM; | ||
415 | mlog_errno(status); | ||
416 | goto bail; | ||
417 | } | ||
418 | |||
419 | /* dir->i_size is always block aligned. */ | 421 | /* dir->i_size is always block aligned. */ |
420 | spin_lock(&OCFS2_I(dir)->ip_lock); | 422 | spin_lock(&OCFS2_I(dir)->ip_lock); |
421 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { | 423 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { |
@@ -428,8 +430,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
428 | } | 430 | } |
429 | 431 | ||
430 | if (!num_free_extents) { | 432 | if (!num_free_extents) { |
431 | status = ocfs2_reserve_new_metadata(osb, handle, | 433 | status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); |
432 | fe, &meta_ac); | ||
433 | if (status < 0) { | 434 | if (status < 0) { |
434 | if (status != -ENOSPC) | 435 | if (status != -ENOSPC) |
435 | mlog_errno(status); | 436 | mlog_errno(status); |
@@ -437,7 +438,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
437 | } | 438 | } |
438 | } | 439 | } |
439 | 440 | ||
440 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 441 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
441 | if (status < 0) { | 442 | if (status < 0) { |
442 | if (status != -ENOSPC) | 443 | if (status != -ENOSPC) |
443 | mlog_errno(status); | 444 | mlog_errno(status); |
@@ -450,7 +451,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
450 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; | 451 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; |
451 | } | 452 | } |
452 | 453 | ||
453 | handle = ocfs2_start_trans(osb, handle, credits); | 454 | handle = ocfs2_start_trans(osb, credits); |
454 | if (IS_ERR(handle)) { | 455 | if (IS_ERR(handle)) { |
455 | status = PTR_ERR(handle); | 456 | status = PTR_ERR(handle); |
456 | handle = NULL; | 457 | handle = NULL; |
@@ -496,7 +497,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
496 | get_bh(*new_de_bh); | 497 | get_bh(*new_de_bh); |
497 | bail: | 498 | bail: |
498 | if (handle) | 499 | if (handle) |
499 | ocfs2_commit_trans(handle); | 500 | ocfs2_commit_trans(osb, handle); |
500 | 501 | ||
501 | if (data_ac) | 502 | if (data_ac) |
502 | ocfs2_free_alloc_context(data_ac); | 503 | ocfs2_free_alloc_context(data_ac); |