aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r--fs/ocfs2/dir.c33
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;
200bail: 209bail:
201 ocfs2_meta_unlock(inode, 0); 210 ocfs2_meta_unlock(inode, lock_level);
202 211
203bail_nolock: 212bail_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. */
342int ocfs2_do_extend_dir(struct super_block *sb, 351int 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);
497bail: 498bail:
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);