aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-05-18 16:25:27 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-05-18 16:25:27 -0400
commit320dd101e2d595a03439adb92b319f3af53dd1d0 (patch)
tree56a88401a218622018030045fec009bafdc4ce76 /fs
parent3a8a9a1034813aa99f5ae3150f652d490c5ff10d (diff)
[GFS2] glock debugging and inode cache changes
This adds some extra debugging to glock.c and changes inode.c's deallocation code to call the debugging code at a suitable moment. I'm chasing down a particular bug to do with deallocation at the moment and the code can go again once the bug is fixed. Also this includes the first part of some changes to unify the Linux struct inode and GFS2's struct gfs2_inode. This transformation will happen in small parts over the next short period. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/glock.c26
-rw-r--r--fs/gfs2/glock.h1
-rw-r--r--fs/gfs2/incore.h8
-rw-r--r--fs/gfs2/inode.c58
-rw-r--r--fs/gfs2/main.c18
-rw-r--r--fs/gfs2/ops_super.c24
6 files changed, 92 insertions, 43 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index c04159031538..2ef8accf1cbc 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -47,6 +47,7 @@ struct greedy {
47typedef void (*glock_examiner) (struct gfs2_glock * gl); 47typedef void (*glock_examiner) (struct gfs2_glock * gl);
48 48
49static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); 49static int gfs2_dump_lockstate(struct gfs2_sbd *sdp);
50static int dump_glock(struct gfs2_glock *gl);
50 51
51/** 52/**
52 * relaxed_state_ok - is a requested lock compatible with the current lock mode? 53 * relaxed_state_ok - is a requested lock compatible with the current lock mode?
@@ -290,6 +291,8 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, uint64_t number,
290 spin_lock_init(&gl->gl_spin); 291 spin_lock_init(&gl->gl_spin);
291 292
292 gl->gl_state = LM_ST_UNLOCKED; 293 gl->gl_state = LM_ST_UNLOCKED;
294 gl->gl_owner = NULL;
295 gl->gl_ip = 0;
293 INIT_LIST_HEAD(&gl->gl_holders); 296 INIT_LIST_HEAD(&gl->gl_holders);
294 INIT_LIST_HEAD(&gl->gl_waiters1); 297 INIT_LIST_HEAD(&gl->gl_waiters1);
295 INIT_LIST_HEAD(&gl->gl_waiters2); 298 INIT_LIST_HEAD(&gl->gl_waiters2);
@@ -661,8 +664,11 @@ void gfs2_glmutex_lock(struct gfs2_glock *gl)
661 spin_lock(&gl->gl_spin); 664 spin_lock(&gl->gl_spin);
662 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) 665 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
663 list_add_tail(&gh.gh_list, &gl->gl_waiters1); 666 list_add_tail(&gh.gh_list, &gl->gl_waiters1);
664 else 667 else {
668 gl->gl_owner = current;
669 gl->gl_ip = (unsigned long)__builtin_return_address(0);
665 complete(&gh.gh_wait); 670 complete(&gh.gh_wait);
671 }
666 spin_unlock(&gl->gl_spin); 672 spin_unlock(&gl->gl_spin);
667 673
668 wait_for_completion(&gh.gh_wait); 674 wait_for_completion(&gh.gh_wait);
@@ -683,6 +689,10 @@ static int gfs2_glmutex_trylock(struct gfs2_glock *gl)
683 spin_lock(&gl->gl_spin); 689 spin_lock(&gl->gl_spin);
684 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) 690 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
685 acquired = 0; 691 acquired = 0;
692 else {
693 gl->gl_owner = current;
694 gl->gl_ip = (unsigned long)__builtin_return_address(0);
695 }
686 spin_unlock(&gl->gl_spin); 696 spin_unlock(&gl->gl_spin);
687 697
688 return acquired; 698 return acquired;
@@ -698,6 +708,8 @@ void gfs2_glmutex_unlock(struct gfs2_glock *gl)
698{ 708{
699 spin_lock(&gl->gl_spin); 709 spin_lock(&gl->gl_spin);
700 clear_bit(GLF_LOCK, &gl->gl_flags); 710 clear_bit(GLF_LOCK, &gl->gl_flags);
711 gl->gl_owner = NULL;
712 gl->gl_ip = 0;
701 run_queue(gl); 713 run_queue(gl);
702 BUG_ON(!spin_is_locked(&gl->gl_spin)); 714 BUG_ON(!spin_is_locked(&gl->gl_spin));
703 spin_unlock(&gl->gl_spin); 715 spin_unlock(&gl->gl_spin);
@@ -1173,7 +1185,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
1173 struct gfs2_sbd *sdp = gl->gl_sbd; 1185 struct gfs2_sbd *sdp = gl->gl_sbd;
1174 int error = 0; 1186 int error = 0;
1175 1187
1176 restart: 1188restart:
1177 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { 1189 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) {
1178 set_bit(HIF_ABORTED, &gh->gh_iflags); 1190 set_bit(HIF_ABORTED, &gh->gh_iflags);
1179 return -EIO; 1191 return -EIO;
@@ -1196,6 +1208,9 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
1196 1208
1197 clear_bit(GLF_PREFETCH, &gl->gl_flags); 1209 clear_bit(GLF_PREFETCH, &gl->gl_flags);
1198 1210
1211 if (error == GLR_TRYFAILED && (gh->gh_flags & GL_DUMP))
1212 dump_glock(gl);
1213
1199 return error; 1214 return error;
1200} 1215}
1201 1216
@@ -2212,9 +2227,8 @@ static int dump_glock(struct gfs2_glock *gl)
2212 2227
2213 spin_lock(&gl->gl_spin); 2228 spin_lock(&gl->gl_spin);
2214 2229
2215 printk(KERN_INFO "Glock (%u, %llu)\n", 2230 printk(KERN_INFO "Glock (%u, %llu)\n", gl->gl_name.ln_type,
2216 gl->gl_name.ln_type, 2231 gl->gl_name.ln_number);
2217 gl->gl_name.ln_number);
2218 printk(KERN_INFO " gl_flags ="); 2232 printk(KERN_INFO " gl_flags =");
2219 for (x = 0; x < 32; x++) 2233 for (x = 0; x < 32; x++)
2220 if (test_bit(x, &gl->gl_flags)) 2234 if (test_bit(x, &gl->gl_flags))
@@ -2222,6 +2236,8 @@ static int dump_glock(struct gfs2_glock *gl)
2222 printk(" \n"); 2236 printk(" \n");
2223 printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref.refcount)); 2237 printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref.refcount));
2224 printk(KERN_INFO " gl_state = %u\n", gl->gl_state); 2238 printk(KERN_INFO " gl_state = %u\n", gl->gl_state);
2239 printk(KERN_INFO " gl_owner = %s\n", gl->gl_owner->comm);
2240 print_symbol(KERN_INFO " gl_ip = %s\n", gl->gl_ip);
2225 printk(KERN_INFO " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); 2241 printk(KERN_INFO " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no");
2226 printk(KERN_INFO " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); 2242 printk(KERN_INFO " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no");
2227 printk(KERN_INFO " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); 2243 printk(KERN_INFO " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count));
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 9df09c7eeb95..2e0a2ba92aa0 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -27,6 +27,7 @@
27#define GL_SYNC 0x00000800 27#define GL_SYNC 0x00000800
28#define GL_NOCANCEL 0x00001000 28#define GL_NOCANCEL 0x00001000
29#define GL_AOP 0x00004000 29#define GL_AOP 0x00004000
30#define GL_DUMP 0x00008000
30 31
31#define GLR_TRYFAILED 13 32#define GLR_TRYFAILED 13
32#define GLR_CANCELED 14 33#define GLR_CANCELED 14
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index fc4a983e3c89..92091d006a02 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -183,6 +183,8 @@ struct gfs2_glock {
183 spinlock_t gl_spin; 183 spinlock_t gl_spin;
184 184
185 unsigned int gl_state; 185 unsigned int gl_state;
186 struct task_struct *gl_owner;
187 unsigned long gl_ip;
186 struct list_head gl_holders; 188 struct list_head gl_holders;
187 struct list_head gl_waiters1; /* HIF_MUTEX */ 189 struct list_head gl_waiters1; /* HIF_MUTEX */
188 struct list_head gl_waiters2; /* HIF_DEMOTE, HIF_GREEDY */ 190 struct list_head gl_waiters2; /* HIF_DEMOTE, HIF_GREEDY */
@@ -244,6 +246,7 @@ enum {
244}; 246};
245 247
246struct gfs2_inode { 248struct gfs2_inode {
249 struct inode i_inode;
247 struct gfs2_inum i_num; 250 struct gfs2_inum i_num;
248 251
249 atomic_t i_count; 252 atomic_t i_count;
@@ -270,6 +273,11 @@ struct gfs2_inode {
270 struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT]; 273 struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
271}; 274};
272 275
276static inline struct gfs2_inode *GFS2_I(struct inode *inode)
277{
278 return container_of(inode, struct gfs2_inode, i_inode);
279}
280
273enum { 281enum {
274 GFF_DID_DIRECT_ALLOC = 0, 282 GFF_DID_DIRECT_ALLOC = 0,
275}; 283};
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 27fbcd9b12f0..c2c7d2b63a57 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -504,7 +504,7 @@ static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
504 504
505 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr, 505 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
506 &gfs2_inode_glops, LM_ST_EXCLUSIVE, 506 &gfs2_inode_glops, LM_ST_EXCLUSIVE,
507 LM_FLAG_TRY_1CB, &i_gh); 507 LM_FLAG_TRY_1CB|GL_DUMP, &i_gh);
508 switch(error) { 508 switch(error) {
509 case 0: 509 case 0:
510 break; 510 break;
@@ -724,9 +724,8 @@ struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
724 if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) || 724 if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) ||
725 (name->len == 2 && memcmp(name->name, "..", 2) == 0 && 725 (name->len == 2 && memcmp(name->name, "..", 2) == 0 &&
726 dir == sb->s_root->d_inode)) { 726 dir == sb->s_root->d_inode)) {
727 gfs2_inode_hold(dip); 727 igrab(dir);
728 ipp = dip; 728 return dir;
729 goto done;
730 } 729 }
731 730
732 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); 731 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
@@ -734,7 +733,7 @@ struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
734 return ERR_PTR(error); 733 return ERR_PTR(error);
735 734
736 if (!is_root) { 735 if (!is_root) {
737 error = gfs2_repermission(dip->i_vnode, MAY_EXEC, NULL); 736 error = gfs2_repermission(dir, MAY_EXEC, NULL);
738 if (error) 737 if (error)
739 goto out; 738 goto out;
740 } 739 }
@@ -756,7 +755,6 @@ struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
756 755
757out: 756out:
758 gfs2_glock_dq_uninit(&d_gh); 757 gfs2_glock_dq_uninit(&d_gh);
759done:
760 if (error == -ENOENT) 758 if (error == -ENOENT)
761 return NULL; 759 return NULL;
762 if (error == 0) { 760 if (error == 0) {
@@ -1058,7 +1056,6 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1058 int error; 1056 int error;
1059 1057
1060 munge_mode_uid_gid(dip, &mode, &uid, &gid); 1058 munge_mode_uid_gid(dip, &mode, &uid, &gid);
1061
1062 gfs2_alloc_get(dip); 1059 gfs2_alloc_get(dip);
1063 1060
1064 error = gfs2_quota_lock(dip, uid, gid); 1061 error = gfs2_quota_lock(dip, uid, gid);
@@ -1069,19 +1066,14 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1069 if (error) 1066 if (error)
1070 goto out_quota; 1067 goto out_quota;
1071 1068
1072 error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED + 1069 error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED + RES_QUOTA, 0);
1073 RES_QUOTA, 0);
1074 if (error) 1070 if (error)
1075 goto out_quota; 1071 goto out_quota;
1076 1072
1077 ul->ul_ut.ut_flags = 0; 1073 ul->ul_ut.ut_flags = 0;
1078 error = gfs2_unlinked_ondisk_munge(sdp, ul); 1074 error = gfs2_unlinked_ondisk_munge(sdp, ul);
1079 1075 init_dinode(dip, gl, &ul->ul_ut.ut_inum, mode, uid, gid);
1080 init_dinode(dip, gl, &ul->ul_ut.ut_inum,
1081 mode, uid, gid);
1082
1083 gfs2_quota_change(dip, +1, uid, gid); 1076 gfs2_quota_change(dip, +1, uid, gid);
1084
1085 gfs2_trans_end(sdp); 1077 gfs2_trans_end(sdp);
1086 1078
1087 out_quota: 1079 out_quota:
@@ -1089,7 +1081,6 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1089 1081
1090 out: 1082 out:
1091 gfs2_alloc_put(dip); 1083 gfs2_alloc_put(dip);
1092
1093 return error; 1084 return error;
1094} 1085}
1095 1086
@@ -1123,8 +1114,7 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
1123 if (error) 1114 if (error)
1124 goto fail_quota_locks; 1115 goto fail_quota_locks;
1125 1116
1126 error = gfs2_trans_begin(sdp, 1117 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
1127 sdp->sd_max_dirres +
1128 al->al_rgd->rd_ri.ri_length + 1118 al->al_rgd->rd_ri.ri_length +
1129 2 * RES_DINODE + RES_UNLINKED + 1119 2 * RES_DINODE + RES_UNLINKED +
1130 RES_STATFS + RES_QUOTA, 0); 1120 RES_STATFS + RES_QUOTA, 0);
@@ -1157,19 +1147,18 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
1157 1147
1158 return 0; 1148 return 0;
1159 1149
1160 fail_end_trans: 1150fail_end_trans:
1161 gfs2_trans_end(sdp); 1151 gfs2_trans_end(sdp);
1162 1152
1163 fail_ipreserv: 1153fail_ipreserv:
1164 if (dip->i_alloc.al_rgd) 1154 if (dip->i_alloc.al_rgd)
1165 gfs2_inplace_release(dip); 1155 gfs2_inplace_release(dip);
1166 1156
1167 fail_quota_locks: 1157fail_quota_locks:
1168 gfs2_quota_unlock(dip); 1158 gfs2_quota_unlock(dip);
1169 1159
1170 fail: 1160fail:
1171 gfs2_alloc_put(dip); 1161 gfs2_alloc_put(dip);
1172
1173 return error; 1162 return error;
1174} 1163}
1175 1164
@@ -1226,11 +1215,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
1226 if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) { 1215 if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) {
1227 gfs2_glock_dq(ghs); 1216 gfs2_glock_dq(ghs);
1228 1217
1229 error = gfs2_glock_nq_num(sdp, 1218 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
1230 ul->ul_ut.ut_inum.no_addr, 1219 &gfs2_inode_glops, LM_ST_EXCLUSIVE,
1231 &gfs2_inode_glops, 1220 GL_SKIP, ghs + 1);
1232 LM_ST_EXCLUSIVE, GL_SKIP,
1233 ghs + 1);
1234 if (error) { 1221 if (error) {
1235 gfs2_unlinked_put(sdp, ul); 1222 gfs2_unlinked_put(sdp, ul);
1236 return ERR_PTR(error); 1223 return ERR_PTR(error);
@@ -1248,11 +1235,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
1248 if (error) 1235 if (error)
1249 goto fail_gunlock2; 1236 goto fail_gunlock2;
1250 } else { 1237 } else {
1251 error = gfs2_glock_nq_num(sdp, 1238 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
1252 ul->ul_ut.ut_inum.no_addr, 1239 &gfs2_inode_glops, LM_ST_EXCLUSIVE,
1253 &gfs2_inode_glops, 1240 GL_SKIP, ghs + 1);
1254 LM_ST_EXCLUSIVE, GL_SKIP,
1255 ghs + 1);
1256 if (error) 1241 if (error)
1257 goto fail_gunlock; 1242 goto fail_gunlock;
1258 } 1243 }
@@ -1285,18 +1270,17 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
1285 return ERR_PTR(-ENOMEM); 1270 return ERR_PTR(-ENOMEM);
1286 return inode; 1271 return inode;
1287 1272
1288 fail_iput: 1273fail_iput:
1289 gfs2_inode_put(ip); 1274 gfs2_inode_put(ip);
1290 1275
1291 fail_gunlock2: 1276fail_gunlock2:
1292 gfs2_glock_dq_uninit(ghs + 1); 1277 gfs2_glock_dq_uninit(ghs + 1);
1293 1278
1294 fail_gunlock: 1279fail_gunlock:
1295 gfs2_glock_dq(ghs); 1280 gfs2_glock_dq(ghs);
1296 1281
1297 fail: 1282fail:
1298 gfs2_unlinked_put(sdp, ul); 1283 gfs2_unlinked_put(sdp, ul);
1299
1300 return ERR_PTR(error); 1284 return ERR_PTR(error);
1301} 1285}
1302 1286
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 9ce56b5c7803..b24d0b40d965 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -23,6 +23,20 @@
23#include "sys.h" 23#include "sys.h"
24#include "util.h" 24#include "util.h"
25 25
26static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
27{
28 struct gfs2_inode *ip = foo;
29 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
30 SLAB_CTOR_CONSTRUCTOR) {
31 inode_init_once(&ip->i_inode);
32 atomic_set(&ip->i_count, 0);
33 ip->i_vnode = &ip->i_inode;
34 spin_lock_init(&ip->i_spin);
35 init_rwsem(&ip->i_rw_mutex);
36 memset(ip->i_cache, 0, sizeof(ip->i_cache));
37 }
38}
39
26/** 40/**
27 * init_gfs2_fs - Register GFS2 as a filesystem 41 * init_gfs2_fs - Register GFS2 as a filesystem
28 * 42 *
@@ -49,7 +63,9 @@ static int __init init_gfs2_fs(void)
49 63
50 gfs2_inode_cachep = kmem_cache_create("gfs2_inode", 64 gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
51 sizeof(struct gfs2_inode), 65 sizeof(struct gfs2_inode),
52 0, 0, NULL, NULL); 66 0, (SLAB_RECLAIM_ACCOUNT|
67 SLAB_PANIC|SLAB_MEM_SPREAD),
68 gfs2_init_inode_once, NULL);
53 if (!gfs2_inode_cachep) 69 if (!gfs2_inode_cachep)
54 goto fail; 70 goto fail;
55 71
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 6fa7b8649f14..1c17acc946f9 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -361,7 +361,31 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
361 return 0; 361 return 0;
362} 362}
363 363
364static struct inode *gfs2_alloc_inode(struct super_block *sb)
365{
366 struct gfs2_sbd *sdp = sb->s_fs_info;
367 struct gfs2_inode *ip;
368
369 ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL);
370 if (ip) {
371 ip->i_flags = 0;
372 ip->i_gl = NULL;
373 ip->i_sbd = sdp;
374 ip->i_vnode = &ip->i_inode;
375 ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
376 ip->i_last_pfault = jiffies;
377 }
378 return &ip->i_inode;
379}
380
381static void gfs2_destroy_inode(struct inode *inode)
382{
383 kmem_cache_free(gfs2_inode_cachep, inode);
384}
385
364struct super_operations gfs2_super_ops = { 386struct super_operations gfs2_super_ops = {
387 .alloc_inode = gfs2_alloc_inode,
388 .destroy_inode = gfs2_destroy_inode,
365 .write_inode = gfs2_write_inode, 389 .write_inode = gfs2_write_inode,
366 .put_super = gfs2_put_super, 390 .put_super = gfs2_put_super,
367 .write_super = gfs2_write_super, 391 .write_super = gfs2_write_super,