aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2010-04-14 11:58:16 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2010-04-14 11:48:05 -0400
commit1a0eae8848cde6e0734360f6456496c995ee1e23 (patch)
tree536f944468ef5bc6f47ec09325422adbc5a3907a
parent602c89d2e3e8652f94a697c9a919be739b9bcdd5 (diff)
GFS2: glock livelock
This patch fixes a couple gfs2 problems with the reclaiming of unlinked dinodes. First, there were a couple of livelocks where everything would come to a halt waiting for a glock that was seemingly held by a process that no longer existed. In fact, the process did exist, it just had the wrong pid number in the holder information. Second, there was a lock ordering problem between inode locking and glock locking. Third, glock/inode contention could sometimes cause inodes to be improperly marked invalid by iget_failed. Signed-off-by: Bob Peterson <rpeterso@redhat.com>
-rw-r--r--fs/gfs2/dir.c2
-rw-r--r--fs/gfs2/export.c2
-rw-r--r--fs/gfs2/glock.c3
-rw-r--r--fs/gfs2/inode.c101
-rw-r--r--fs/gfs2/inode.h5
-rw-r--r--fs/gfs2/ops_fstype.c2
-rw-r--r--fs/gfs2/rgrp.c58
7 files changed, 144 insertions, 29 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 25fddc100f18..8295c5b5d4a9 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1475,7 +1475,7 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
1475 inode = gfs2_inode_lookup(dir->i_sb, 1475 inode = gfs2_inode_lookup(dir->i_sb,
1476 be16_to_cpu(dent->de_type), 1476 be16_to_cpu(dent->de_type),
1477 be64_to_cpu(dent->de_inum.no_addr), 1477 be64_to_cpu(dent->de_inum.no_addr),
1478 be64_to_cpu(dent->de_inum.no_formal_ino), 0); 1478 be64_to_cpu(dent->de_inum.no_formal_ino));
1479 brelse(bh); 1479 brelse(bh);
1480 return inode; 1480 return inode;
1481 } 1481 }
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index d15876e9aa26..d81bc7e90e98 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -169,7 +169,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
169 if (error) 169 if (error)
170 goto fail; 170 goto fail;
171 171
172 inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0, 0); 172 inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0);
173 if (IS_ERR(inode)) { 173 if (IS_ERR(inode)) {
174 error = PTR_ERR(inode); 174 error = PTR_ERR(inode);
175 goto fail; 175 goto fail;
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 454d4b4eb36b..ddcdbf493536 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -855,6 +855,9 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder *
855 gh->gh_flags = flags; 855 gh->gh_flags = flags;
856 gh->gh_iflags = 0; 856 gh->gh_iflags = 0;
857 gh->gh_ip = (unsigned long)__builtin_return_address(0); 857 gh->gh_ip = (unsigned long)__builtin_return_address(0);
858 if (gh->gh_owner_pid)
859 put_pid(gh->gh_owner_pid);
860 gh->gh_owner_pid = get_pid(task_pid(current));
858} 861}
859 862
860/** 863/**
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index b1bf2694fb2b..51d8061fa07a 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -158,7 +158,6 @@ void gfs2_set_iop(struct inode *inode)
158 * @sb: The super block 158 * @sb: The super block
159 * @no_addr: The inode number 159 * @no_addr: The inode number
160 * @type: The type of the inode 160 * @type: The type of the inode
161 * @skip_freeing: set this not return an inode if it is currently being freed.
162 * 161 *
163 * Returns: A VFS inode, or an error 162 * Returns: A VFS inode, or an error
164 */ 163 */
@@ -166,17 +165,14 @@ void gfs2_set_iop(struct inode *inode)
166struct inode *gfs2_inode_lookup(struct super_block *sb, 165struct inode *gfs2_inode_lookup(struct super_block *sb,
167 unsigned int type, 166 unsigned int type,
168 u64 no_addr, 167 u64 no_addr,
169 u64 no_formal_ino, int skip_freeing) 168 u64 no_formal_ino)
170{ 169{
171 struct inode *inode; 170 struct inode *inode;
172 struct gfs2_inode *ip; 171 struct gfs2_inode *ip;
173 struct gfs2_glock *io_gl; 172 struct gfs2_glock *io_gl;
174 int error; 173 int error;
175 174
176 if (skip_freeing) 175 inode = gfs2_iget(sb, no_addr);
177 inode = gfs2_iget_skip(sb, no_addr);
178 else
179 inode = gfs2_iget(sb, no_addr);
180 ip = GFS2_I(inode); 176 ip = GFS2_I(inode);
181 177
182 if (!inode) 178 if (!inode)
@@ -234,13 +230,100 @@ fail_glock:
234fail_iopen: 230fail_iopen:
235 gfs2_glock_put(io_gl); 231 gfs2_glock_put(io_gl);
236fail_put: 232fail_put:
237 ip->i_gl->gl_object = NULL; 233 if (inode->i_state & I_NEW)
234 ip->i_gl->gl_object = NULL;
238 gfs2_glock_put(ip->i_gl); 235 gfs2_glock_put(ip->i_gl);
239fail: 236fail:
240 iget_failed(inode); 237 if (inode->i_state & I_NEW)
238 iget_failed(inode);
239 else
240 iput(inode);
241 return ERR_PTR(error); 241 return ERR_PTR(error);
242} 242}
243 243
244/**
245 * gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation
246 * @sb: The super block
247 * no_addr: The inode number
248 * @@inode: A pointer to the inode found, if any
249 *
250 * Returns: 0 and *inode if no errors occurred. If an error occurs,
251 * the resulting *inode may or may not be NULL.
252 */
253
254int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
255 struct inode **inode)
256{
257 struct gfs2_sbd *sdp;
258 struct gfs2_inode *ip;
259 struct gfs2_glock *io_gl;
260 int error;
261 struct gfs2_holder gh;
262
263 *inode = gfs2_iget_skip(sb, no_addr);
264
265 if (!(*inode))
266 return -ENOBUFS;
267
268 if (!((*inode)->i_state & I_NEW))
269 return -ENOBUFS;
270
271 ip = GFS2_I(*inode);
272 sdp = GFS2_SB(*inode);
273 ip->i_no_formal_ino = -1;
274
275 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
276 if (unlikely(error))
277 goto fail;
278 ip->i_gl->gl_object = ip;
279
280 error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
281 if (unlikely(error))
282 goto fail_put;
283
284 set_bit(GIF_INVALID, &ip->i_flags);
285 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT,
286 &ip->i_iopen_gh);
287 if (unlikely(error)) {
288 if (error == GLR_TRYFAILED)
289 error = 0;
290 goto fail_iopen;
291 }
292 ip->i_iopen_gh.gh_gl->gl_object = ip;
293 gfs2_glock_put(io_gl);
294
295 (*inode)->i_mode = DT2IF(DT_UNKNOWN);
296
297 /*
298 * We must read the inode in order to work out its type in
299 * this case. Note that this doesn't happen often as we normally
300 * know the type beforehand. This code path only occurs during
301 * unlinked inode recovery (where it is safe to do this glock,
302 * which is not true in the general case).
303 */
304 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
305 &gh);
306 if (unlikely(error)) {
307 if (error == GLR_TRYFAILED)
308 error = 0;
309 goto fail_glock;
310 }
311 /* Inode is now uptodate */
312 gfs2_glock_dq_uninit(&gh);
313 gfs2_set_iop(*inode);
314
315 return 0;
316fail_glock:
317 gfs2_glock_dq(&ip->i_iopen_gh);
318fail_iopen:
319 gfs2_glock_put(io_gl);
320fail_put:
321 ip->i_gl->gl_object = NULL;
322 gfs2_glock_put(ip->i_gl);
323fail:
324 return error;
325}
326
244static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) 327static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
245{ 328{
246 const struct gfs2_dinode *str = buf; 329 const struct gfs2_dinode *str = buf;
@@ -862,7 +945,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
862 goto fail_gunlock2; 945 goto fail_gunlock2;
863 946
864 inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, 947 inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr,
865 inum.no_formal_ino, 0); 948 inum.no_formal_ino);
866 if (IS_ERR(inode)) 949 if (IS_ERR(inode))
867 goto fail_gunlock2; 950 goto fail_gunlock2;
868 951
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index c341aaf67adb..e161461d4c57 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -83,8 +83,9 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip,
83 83
84extern void gfs2_set_iop(struct inode *inode); 84extern void gfs2_set_iop(struct inode *inode);
85extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, 85extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
86 u64 no_addr, u64 no_formal_ino, 86 u64 no_addr, u64 no_formal_ino);
87 int skip_freeing); 87extern int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
88 struct inode **inode);
88extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); 89extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
89 90
90extern int gfs2_inode_refresh(struct gfs2_inode *ip); 91extern int gfs2_inode_refresh(struct gfs2_inode *ip);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index c1309ed1c496..dc35f3470271 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -487,7 +487,7 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr,
487 struct dentry *dentry; 487 struct dentry *dentry;
488 struct inode *inode; 488 struct inode *inode;
489 489
490 inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0); 490 inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0);
491 if (IS_ERR(inode)) { 491 if (IS_ERR(inode)) {
492 fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode)); 492 fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode));
493 return PTR_ERR(inode); 493 return PTR_ERR(inode);
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 503b842f3ba2..37391550284f 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -948,18 +948,20 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
948 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes 948 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
949 * @rgd: The rgrp 949 * @rgd: The rgrp
950 * 950 *
951 * Returns: The inode, if one has been found 951 * Returns: 0 if no error
952 * The inode, if one has been found, in inode.
952 */ 953 */
953 954
954static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, 955static int try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
955 u64 skip) 956 u64 skip, struct inode **inode)
956{ 957{
957 struct inode *inode;
958 u32 goal = 0, block; 958 u32 goal = 0, block;
959 u64 no_addr; 959 u64 no_addr;
960 struct gfs2_sbd *sdp = rgd->rd_sbd; 960 struct gfs2_sbd *sdp = rgd->rd_sbd;
961 unsigned int n; 961 unsigned int n;
962 int error = 0;
962 963
964 *inode = NULL;
963 for(;;) { 965 for(;;) {
964 if (goal >= rgd->rd_data) 966 if (goal >= rgd->rd_data)
965 break; 967 break;
@@ -979,14 +981,14 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
979 if (no_addr == skip) 981 if (no_addr == skip)
980 continue; 982 continue;
981 *last_unlinked = no_addr; 983 *last_unlinked = no_addr;
982 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, 984 error = gfs2_unlinked_inode_lookup(rgd->rd_sbd->sd_vfs,
983 no_addr, -1, 1); 985 no_addr, inode);
984 if (!IS_ERR(inode)) 986 if (*inode || error)
985 return inode; 987 return error;
986 } 988 }
987 989
988 rgd->rd_flags &= ~GFS2_RDF_CHECK; 990 rgd->rd_flags &= ~GFS2_RDF_CHECK;
989 return NULL; 991 return 0;
990} 992}
991 993
992/** 994/**
@@ -1096,12 +1098,27 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1096 case 0: 1098 case 0:
1097 if (try_rgrp_fit(rgd, al)) 1099 if (try_rgrp_fit(rgd, al))
1098 goto out; 1100 goto out;
1099 if (rgd->rd_flags & GFS2_RDF_CHECK) 1101 /* If the rg came in already locked, there's no
1100 inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); 1102 way we can recover from a failed try_rgrp_unlink
1103 because that would require an iput which can only
1104 happen after the rgrp is unlocked. */
1105 if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
1106 error = try_rgrp_unlink(rgd, last_unlinked,
1107 ip->i_no_addr, &inode);
1101 if (!rg_locked) 1108 if (!rg_locked)
1102 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1109 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1103 if (inode) 1110 if (inode) {
1111 if (error) {
1112 if (inode->i_state & I_NEW)
1113 iget_failed(inode);
1114 else
1115 iput(inode);
1116 return ERR_PTR(error);
1117 }
1104 return inode; 1118 return inode;
1119 }
1120 if (error)
1121 return ERR_PTR(error);
1105 /* fall through */ 1122 /* fall through */
1106 case GLR_TRYFAILED: 1123 case GLR_TRYFAILED:
1107 rgd = recent_rgrp_next(rgd); 1124 rgd = recent_rgrp_next(rgd);
@@ -1130,12 +1147,23 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1130 case 0: 1147 case 0:
1131 if (try_rgrp_fit(rgd, al)) 1148 if (try_rgrp_fit(rgd, al))
1132 goto out; 1149 goto out;
1133 if (rgd->rd_flags & GFS2_RDF_CHECK) 1150 if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
1134 inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); 1151 error = try_rgrp_unlink(rgd, last_unlinked,
1152 ip->i_no_addr, &inode);
1135 if (!rg_locked) 1153 if (!rg_locked)
1136 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1154 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1137 if (inode) 1155 if (inode) {
1156 if (error) {
1157 if (inode->i_state & I_NEW)
1158 iget_failed(inode);
1159 else
1160 iput(inode);
1161 return ERR_PTR(error);
1162 }
1138 return inode; 1163 return inode;
1164 }
1165 if (error)
1166 return ERR_PTR(error);
1139 break; 1167 break;
1140 1168
1141 case GLR_TRYFAILED: 1169 case GLR_TRYFAILED: