aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-12-12 06:34:09 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-01-14 14:28:25 -0500
commit8ad151c2ac9aa106cb903cfd838b31561dbd7bcc (patch)
tree8c488968b7e9dd8ccfd254608665454b46adf46f /fs
parentc754fbbb1b6bf462c6ddba48b19f20adf2335cac (diff)
GFS2: Only run logd and quota when mounted read/write
While investigating a rather strange bit of code in the quota clean up function, I spotted that the reason for its existence was that when remounting read only, we were not stopping the quotad thread, and thus it was possible for it to still have a reference to some of the quotas in that case. This patch moves the logd and quota thread start and stop into the make_fs_rw/ro functions, so that we now stop those threads when mounted read only. This means that quotad will always be stopped before we call the quota clean up function, and we can thus dispose of the (rather hackish) code that waits for it to give up its reference on the quotas. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Abhijith Das <adas@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/ops_fstype.c42
-rw-r--r--fs/gfs2/quota.c24
-rw-r--r--fs/gfs2/super.c43
3 files changed, 41 insertions, 68 deletions
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 3b820b672d17..27648e803d1e 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -969,40 +969,6 @@ fail:
969 return error; 969 return error;
970} 970}
971 971
972static int init_threads(struct gfs2_sbd *sdp, int undo)
973{
974 struct task_struct *p;
975 int error = 0;
976
977 if (undo)
978 goto fail_quotad;
979
980 p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
981 if (IS_ERR(p)) {
982 error = PTR_ERR(p);
983 fs_err(sdp, "can't start logd thread: %d\n", error);
984 return error;
985 }
986 sdp->sd_logd_process = p;
987
988 p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
989 if (IS_ERR(p)) {
990 error = PTR_ERR(p);
991 fs_err(sdp, "can't start quotad thread: %d\n", error);
992 goto fail;
993 }
994 sdp->sd_quotad_process = p;
995
996 return 0;
997
998
999fail_quotad:
1000 kthread_stop(sdp->sd_quotad_process);
1001fail:
1002 kthread_stop(sdp->sd_logd_process);
1003 return error;
1004}
1005
1006static const match_table_t nolock_tokens = { 972static const match_table_t nolock_tokens = {
1007 { Opt_jid, "jid=%d\n", }, 973 { Opt_jid, "jid=%d\n", },
1008 { Opt_err, NULL }, 974 { Opt_err, NULL },
@@ -1267,15 +1233,11 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
1267 goto fail_per_node; 1233 goto fail_per_node;
1268 } 1234 }
1269 1235
1270 error = init_threads(sdp, DO);
1271 if (error)
1272 goto fail_per_node;
1273
1274 if (!(sb->s_flags & MS_RDONLY)) { 1236 if (!(sb->s_flags & MS_RDONLY)) {
1275 error = gfs2_make_fs_rw(sdp); 1237 error = gfs2_make_fs_rw(sdp);
1276 if (error) { 1238 if (error) {
1277 fs_err(sdp, "can't make FS RW: %d\n", error); 1239 fs_err(sdp, "can't make FS RW: %d\n", error);
1278 goto fail_threads; 1240 goto fail_per_node;
1279 } 1241 }
1280 } 1242 }
1281 1243
@@ -1283,8 +1245,6 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
1283 gfs2_online_uevent(sdp); 1245 gfs2_online_uevent(sdp);
1284 return 0; 1246 return 0;
1285 1247
1286fail_threads:
1287 init_threads(sdp, UNDO);
1288fail_per_node: 1248fail_per_node:
1289 init_per_node(sdp, UNDO); 1249 init_per_node(sdp, UNDO);
1290fail_inodes: 1250fail_inodes:
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index a1df01d381a8..3287d9871508 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1376,23 +1376,6 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
1376 while (!list_empty(head)) { 1376 while (!list_empty(head)) {
1377 qd = list_entry(head->prev, struct gfs2_quota_data, qd_list); 1377 qd = list_entry(head->prev, struct gfs2_quota_data, qd_list);
1378 1378
1379 /*
1380 * To be removed in due course... we should be able to
1381 * ensure that all refs to the qd have done by this point
1382 * so that this rather odd test is not required
1383 */
1384 spin_lock(&qd->qd_lockref.lock);
1385 if (qd->qd_lockref.count > 1 ||
1386 (qd->qd_lockref.count && !test_bit(QDF_CHANGE, &qd->qd_flags))) {
1387 spin_unlock(&qd->qd_lockref.lock);
1388 list_move(&qd->qd_list, head);
1389 spin_unlock(&qd_lock);
1390 schedule();
1391 spin_lock(&qd_lock);
1392 continue;
1393 }
1394 spin_unlock(&qd->qd_lockref.lock);
1395
1396 list_del(&qd->qd_list); 1379 list_del(&qd->qd_list);
1397 1380
1398 /* Also remove if this qd exists in the reclaim list */ 1381 /* Also remove if this qd exists in the reclaim list */
@@ -1404,11 +1387,8 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
1404 hlist_bl_del_rcu(&qd->qd_hlist); 1387 hlist_bl_del_rcu(&qd->qd_hlist);
1405 spin_unlock_bucket(qd->qd_hash); 1388 spin_unlock_bucket(qd->qd_hash);
1406 1389
1407 if (!qd->qd_lockref.count) { 1390 gfs2_assert_warn(sdp, !qd->qd_change);
1408 gfs2_assert_warn(sdp, !qd->qd_change); 1391 gfs2_assert_warn(sdp, !qd->qd_slot_count);
1409 gfs2_assert_warn(sdp, !qd->qd_slot_count);
1410 } else
1411 gfs2_assert_warn(sdp, qd->qd_slot_count == 1);
1412 gfs2_assert_warn(sdp, !qd->qd_bh_count); 1392 gfs2_assert_warn(sdp, !qd->qd_bh_count);
1413 1393
1414 gfs2_glock_put(qd->qd_gl); 1394 gfs2_glock_put(qd->qd_gl);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 35da5b19c0de..60f60f6181f3 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -369,6 +369,33 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
369 return 0; 369 return 0;
370} 370}
371 371
372static int init_threads(struct gfs2_sbd *sdp)
373{
374 struct task_struct *p;
375 int error = 0;
376
377 p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
378 if (IS_ERR(p)) {
379 error = PTR_ERR(p);
380 fs_err(sdp, "can't start logd thread: %d\n", error);
381 return error;
382 }
383 sdp->sd_logd_process = p;
384
385 p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
386 if (IS_ERR(p)) {
387 error = PTR_ERR(p);
388 fs_err(sdp, "can't start quotad thread: %d\n", error);
389 goto fail;
390 }
391 sdp->sd_quotad_process = p;
392 return 0;
393
394fail:
395 kthread_stop(sdp->sd_logd_process);
396 return error;
397}
398
372/** 399/**
373 * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one 400 * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one
374 * @sdp: the filesystem 401 * @sdp: the filesystem
@@ -384,10 +411,14 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
384 struct gfs2_log_header_host head; 411 struct gfs2_log_header_host head;
385 int error; 412 int error;
386 413
387 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); 414 error = init_threads(sdp);
388 if (error) 415 if (error)
389 return error; 416 return error;
390 417
418 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh);
419 if (error)
420 goto fail_threads;
421
391 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); 422 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
392 423
393 error = gfs2_find_jhead(sdp->sd_jdesc, &head); 424 error = gfs2_find_jhead(sdp->sd_jdesc, &head);
@@ -417,7 +448,9 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
417fail: 448fail:
418 t_gh.gh_flags |= GL_NOCACHE; 449 t_gh.gh_flags |= GL_NOCACHE;
419 gfs2_glock_dq_uninit(&t_gh); 450 gfs2_glock_dq_uninit(&t_gh);
420 451fail_threads:
452 kthread_stop(sdp->sd_quotad_process);
453 kthread_stop(sdp->sd_logd_process);
421 return error; 454 return error;
422} 455}
423 456
@@ -800,6 +833,9 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
800 struct gfs2_holder t_gh; 833 struct gfs2_holder t_gh;
801 int error; 834 int error;
802 835
836 kthread_stop(sdp->sd_quotad_process);
837 kthread_stop(sdp->sd_logd_process);
838
803 flush_workqueue(gfs2_delete_workqueue); 839 flush_workqueue(gfs2_delete_workqueue);
804 gfs2_quota_sync(sdp->sd_vfs, 0); 840 gfs2_quota_sync(sdp->sd_vfs, 0);
805 gfs2_statfs_sync(sdp->sd_vfs, 0); 841 gfs2_statfs_sync(sdp->sd_vfs, 0);
@@ -857,9 +893,6 @@ restart:
857 } 893 }
858 spin_unlock(&sdp->sd_jindex_spin); 894 spin_unlock(&sdp->sd_jindex_spin);
859 895
860 kthread_stop(sdp->sd_quotad_process);
861 kthread_stop(sdp->sd_logd_process);
862
863 if (!(sb->s_flags & MS_RDONLY)) { 896 if (!(sb->s_flags & MS_RDONLY)) {
864 error = gfs2_make_fs_ro(sdp); 897 error = gfs2_make_fs_ro(sdp);
865 if (error) 898 if (error)