aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2015-11-05 21:44:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 22:34:48 -0500
commit93d911fcce259a3f950ee20592beee31b855cd96 (patch)
treedb5a232a287f08ae5eb1d750562b60986c81f1ab /fs/ocfs2
parent30edc43c7ff0760f6896c37c06a84533546588fa (diff)
ocfs2: only take lock if dio entry when recover orphans
We have no need to take inode mutex, rw and inode lock if it is not dio entry when recover orphans. Optimize it by adding a flag OCFS2_INODE_DIO_ORPHAN_ENTRY to ocfs2_inode_info to reduce contention. Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Cc: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/inode.h2
-rw-r--r--fs/ocfs2/journal.c86
2 files changed, 49 insertions, 39 deletions
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index ca3431ee7f24..aac8b86f312e 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -112,6 +112,8 @@ struct ocfs2_inode_info
112#define OCFS2_INODE_OPEN_DIRECT 0x00000020 112#define OCFS2_INODE_OPEN_DIRECT 0x00000020
113/* Tell the inode wipe code it's not in orphan dir */ 113/* Tell the inode wipe code it's not in orphan dir */
114#define OCFS2_INODE_SKIP_ORPHAN_DIR 0x00000040 114#define OCFS2_INODE_SKIP_ORPHAN_DIR 0x00000040
115/* Entry in orphan dir with 'dio-' prefix */
116#define OCFS2_INODE_DIO_ORPHAN_ENTRY 0x00000080
115 117
116static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) 118static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
117{ 119{
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 4bac6007837d..04d6303f39a7 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -2049,6 +2049,10 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
2049 if (IS_ERR(iter)) 2049 if (IS_ERR(iter))
2050 return 0; 2050 return 0;
2051 2051
2052 if (!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
2053 OCFS2_DIO_ORPHAN_PREFIX_LEN))
2054 OCFS2_I(iter)->ip_flags |= OCFS2_INODE_DIO_ORPHAN_ENTRY;
2055
2052 /* Skip inodes which are already added to recover list, since dio may 2056 /* Skip inodes which are already added to recover list, since dio may
2053 * happen concurrently with unlink/rename */ 2057 * happen concurrently with unlink/rename */
2054 if (OCFS2_I(iter)->ip_next_orphan) { 2058 if (OCFS2_I(iter)->ip_next_orphan) {
@@ -2195,25 +2199,51 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
2195 iter = oi->ip_next_orphan; 2199 iter = oi->ip_next_orphan;
2196 oi->ip_next_orphan = NULL; 2200 oi->ip_next_orphan = NULL;
2197 2201
2198 mutex_lock(&inode->i_mutex); 2202 if (oi->ip_flags & OCFS2_INODE_DIO_ORPHAN_ENTRY) {
2199 ret = ocfs2_rw_lock(inode, 1); 2203 mutex_lock(&inode->i_mutex);
2200 if (ret < 0) { 2204 ret = ocfs2_rw_lock(inode, 1);
2201 mlog_errno(ret); 2205 if (ret < 0) {
2202 goto next; 2206 mlog_errno(ret);
2203 } 2207 goto unlock_mutex;
2204 /* 2208 }
2205 * We need to take and drop the inode lock to 2209 /*
2206 * force read inode from disk. 2210 * We need to take and drop the inode lock to
2207 */ 2211 * force read inode from disk.
2208 ret = ocfs2_inode_lock(inode, &di_bh, 1); 2212 */
2209 if (ret) { 2213 ret = ocfs2_inode_lock(inode, &di_bh, 1);
2210 mlog_errno(ret); 2214 if (ret) {
2211 goto unlock_rw; 2215 mlog_errno(ret);
2212 } 2216 goto unlock_rw;
2217 }
2213 2218
2214 di = (struct ocfs2_dinode *)di_bh->b_data; 2219 di = (struct ocfs2_dinode *)di_bh->b_data;
2215 2220
2216 if (inode->i_nlink == 0) { 2221 if (di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL)) {
2222 ret = ocfs2_truncate_file(inode, di_bh,
2223 i_size_read(inode));
2224 if (ret < 0) {
2225 if (ret != -ENOSPC)
2226 mlog_errno(ret);
2227 goto unlock_inode;
2228 }
2229
2230 ret = ocfs2_del_inode_from_orphan(osb, inode,
2231 di_bh, 0, 0);
2232 if (ret)
2233 mlog_errno(ret);
2234 }
2235unlock_inode:
2236 ocfs2_inode_unlock(inode, 1);
2237 brelse(di_bh);
2238 di_bh = NULL;
2239unlock_rw:
2240 ocfs2_rw_unlock(inode, 1);
2241unlock_mutex:
2242 mutex_unlock(&inode->i_mutex);
2243
2244 /* clear dio flag in ocfs2_inode_info */
2245 oi->ip_flags &= ~OCFS2_INODE_DIO_ORPHAN_ENTRY;
2246 } else {
2217 spin_lock(&oi->ip_lock); 2247 spin_lock(&oi->ip_lock);
2218 /* Set the proper information to get us going into 2248 /* Set the proper information to get us going into
2219 * ocfs2_delete_inode. */ 2249 * ocfs2_delete_inode. */
@@ -2221,28 +2251,6 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
2221 spin_unlock(&oi->ip_lock); 2251 spin_unlock(&oi->ip_lock);
2222 } 2252 }
2223 2253
2224 if ((orphan_reco_type == ORPHAN_NEED_TRUNCATE) &&
2225 (di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL))) {
2226 ret = ocfs2_truncate_file(inode, di_bh,
2227 i_size_read(inode));
2228 if (ret < 0) {
2229 if (ret != -ENOSPC)
2230 mlog_errno(ret);
2231 goto unlock_inode;
2232 }
2233
2234 ret = ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0);
2235 if (ret)
2236 mlog_errno(ret);
2237 } /* else if ORPHAN_NO_NEED_TRUNCATE, do nothing */
2238unlock_inode:
2239 ocfs2_inode_unlock(inode, 1);
2240 brelse(di_bh);
2241 di_bh = NULL;
2242unlock_rw:
2243 ocfs2_rw_unlock(inode, 1);
2244next:
2245 mutex_unlock(&inode->i_mutex);
2246 iput(inode); 2254 iput(inode);
2247 inode = iter; 2255 inode = iter;
2248 } 2256 }