diff options
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r-- | fs/ocfs2/dir.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 5efea44d780d..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, 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); |