aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/gfs2/super.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c143
1 files changed, 108 insertions, 35 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 0ec3ec672de1..50aac606b990 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -21,6 +21,8 @@
21#include <linux/gfs2_ondisk.h> 21#include <linux/gfs2_ondisk.h>
22#include <linux/crc32.h> 22#include <linux/crc32.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/wait.h>
25#include <linux/writeback.h>
24 26
25#include "gfs2.h" 27#include "gfs2.h"
26#include "incore.h" 28#include "incore.h"
@@ -70,6 +72,11 @@ enum {
70 Opt_commit, 72 Opt_commit,
71 Opt_err_withdraw, 73 Opt_err_withdraw,
72 Opt_err_panic, 74 Opt_err_panic,
75 Opt_statfs_quantum,
76 Opt_statfs_percent,
77 Opt_quota_quantum,
78 Opt_barrier,
79 Opt_nobarrier,
73 Opt_error, 80 Opt_error,
74}; 81};
75 82
@@ -101,18 +108,23 @@ static const match_table_t tokens = {
101 {Opt_commit, "commit=%d"}, 108 {Opt_commit, "commit=%d"},
102 {Opt_err_withdraw, "errors=withdraw"}, 109 {Opt_err_withdraw, "errors=withdraw"},
103 {Opt_err_panic, "errors=panic"}, 110 {Opt_err_panic, "errors=panic"},
111 {Opt_statfs_quantum, "statfs_quantum=%d"},
112 {Opt_statfs_percent, "statfs_percent=%d"},
113 {Opt_quota_quantum, "quota_quantum=%d"},
114 {Opt_barrier, "barrier"},
115 {Opt_nobarrier, "nobarrier"},
104 {Opt_error, NULL} 116 {Opt_error, NULL}
105}; 117};
106 118
107/** 119/**
108 * gfs2_mount_args - Parse mount options 120 * gfs2_mount_args - Parse mount options
109 * @sdp: 121 * @args: The structure into which the parsed options will be written
110 * @data: 122 * @options: The options to parse
111 * 123 *
112 * Return: errno 124 * Return: errno
113 */ 125 */
114 126
115int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) 127int gfs2_mount_args(struct gfs2_args *args, char *options)
116{ 128{
117 char *o; 129 char *o;
118 int token; 130 int token;
@@ -157,7 +169,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
157 break; 169 break;
158 case Opt_debug: 170 case Opt_debug:
159 if (args->ar_errors == GFS2_ERRORS_PANIC) { 171 if (args->ar_errors == GFS2_ERRORS_PANIC) {
160 fs_info(sdp, "-o debug and -o errors=panic " 172 printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
161 "are mutually exclusive.\n"); 173 "are mutually exclusive.\n");
162 return -EINVAL; 174 return -EINVAL;
163 } 175 }
@@ -210,7 +222,29 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
210 case Opt_commit: 222 case Opt_commit:
211 rv = match_int(&tmp[0], &args->ar_commit); 223 rv = match_int(&tmp[0], &args->ar_commit);
212 if (rv || args->ar_commit <= 0) { 224 if (rv || args->ar_commit <= 0) {
213 fs_info(sdp, "commit mount option requires a positive numeric argument\n"); 225 printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n");
226 return rv ? rv : -EINVAL;
227 }
228 break;
229 case Opt_statfs_quantum:
230 rv = match_int(&tmp[0], &args->ar_statfs_quantum);
231 if (rv || args->ar_statfs_quantum < 0) {
232 printk(KERN_WARNING "GFS2: statfs_quantum mount option requires a non-negative numeric argument\n");
233 return rv ? rv : -EINVAL;
234 }
235 break;
236 case Opt_quota_quantum:
237 rv = match_int(&tmp[0], &args->ar_quota_quantum);
238 if (rv || args->ar_quota_quantum <= 0) {
239 printk(KERN_WARNING "GFS2: quota_quantum mount option requires a positive numeric argument\n");
240 return rv ? rv : -EINVAL;
241 }
242 break;
243 case Opt_statfs_percent:
244 rv = match_int(&tmp[0], &args->ar_statfs_percent);
245 if (rv || args->ar_statfs_percent < 0 ||
246 args->ar_statfs_percent > 100) {
247 printk(KERN_WARNING "statfs_percent mount option requires a numeric argument between 0 and 100\n");
214 return rv ? rv : -EINVAL; 248 return rv ? rv : -EINVAL;
215 } 249 }
216 break; 250 break;
@@ -219,15 +253,21 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
219 break; 253 break;
220 case Opt_err_panic: 254 case Opt_err_panic:
221 if (args->ar_debug) { 255 if (args->ar_debug) {
222 fs_info(sdp, "-o debug and -o errors=panic " 256 printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
223 "are mutually exclusive.\n"); 257 "are mutually exclusive.\n");
224 return -EINVAL; 258 return -EINVAL;
225 } 259 }
226 args->ar_errors = GFS2_ERRORS_PANIC; 260 args->ar_errors = GFS2_ERRORS_PANIC;
227 break; 261 break;
262 case Opt_barrier:
263 args->ar_nobarrier = 0;
264 break;
265 case Opt_nobarrier:
266 args->ar_nobarrier = 1;
267 break;
228 case Opt_error: 268 case Opt_error:
229 default: 269 default:
230 fs_info(sdp, "invalid mount option: %s\n", o); 270 printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o);
231 return -EINVAL; 271 return -EINVAL;
232 } 272 }
233 } 273 }
@@ -442,7 +482,10 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
442{ 482{
443 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); 483 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
444 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; 484 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
485 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
445 struct buffer_head *l_bh; 486 struct buffer_head *l_bh;
487 s64 x, y;
488 int need_sync = 0;
446 int error; 489 int error;
447 490
448 error = gfs2_meta_inode_buffer(l_ip, &l_bh); 491 error = gfs2_meta_inode_buffer(l_ip, &l_bh);
@@ -456,9 +499,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
456 l_sc->sc_free += free; 499 l_sc->sc_free += free;
457 l_sc->sc_dinodes += dinodes; 500 l_sc->sc_dinodes += dinodes;
458 gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); 501 gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode));
502 if (sdp->sd_args.ar_statfs_percent) {
503 x = 100 * l_sc->sc_free;
504 y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent;
505 if (x >= y || x <= -y)
506 need_sync = 1;
507 }
459 spin_unlock(&sdp->sd_statfs_spin); 508 spin_unlock(&sdp->sd_statfs_spin);
460 509
461 brelse(l_bh); 510 brelse(l_bh);
511 if (need_sync)
512 gfs2_wake_up_statfs(sdp);
462} 513}
463 514
464void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, 515void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
@@ -484,8 +535,9 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
484 gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); 535 gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
485} 536}
486 537
487int gfs2_statfs_sync(struct gfs2_sbd *sdp) 538int gfs2_statfs_sync(struct super_block *sb, int type)
488{ 539{
540 struct gfs2_sbd *sdp = sb->s_fs_info;
489 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 541 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
490 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); 542 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
491 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; 543 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
@@ -521,6 +573,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp)
521 goto out_bh2; 573 goto out_bh2;
522 574
523 update_statfs(sdp, m_bh, l_bh); 575 update_statfs(sdp, m_bh, l_bh);
576 sdp->sd_statfs_force_sync = 0;
524 577
525 gfs2_trans_end(sdp); 578 gfs2_trans_end(sdp);
526 579
@@ -659,7 +712,7 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp)
659 * Returns: errno 712 * Returns: errno
660 */ 713 */
661 714
662static int gfs2_write_inode(struct inode *inode, int sync) 715static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
663{ 716{
664 struct gfs2_inode *ip = GFS2_I(inode); 717 struct gfs2_inode *ip = GFS2_I(inode);
665 struct gfs2_sbd *sdp = GFS2_SB(inode); 718 struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -670,8 +723,7 @@ static int gfs2_write_inode(struct inode *inode, int sync)
670 int ret = 0; 723 int ret = 0;
671 724
672 /* Check this is a "normal" inode, etc */ 725 /* Check this is a "normal" inode, etc */
673 if (!test_bit(GIF_USER, &ip->i_flags) || 726 if (current->flags & PF_MEMALLOC)
674 (current->flags & PF_MEMALLOC))
675 return 0; 727 return 0;
676 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 728 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
677 if (ret) 729 if (ret)
@@ -694,7 +746,7 @@ static int gfs2_write_inode(struct inode *inode, int sync)
694do_unlock: 746do_unlock:
695 gfs2_glock_dq_uninit(&gh); 747 gfs2_glock_dq_uninit(&gh);
696do_flush: 748do_flush:
697 if (sync != 0) 749 if (wbc->sync_mode == WB_SYNC_ALL)
698 gfs2_log_flush(GFS2_SB(inode), ip->i_gl); 750 gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
699 return ret; 751 return ret;
700} 752}
@@ -712,8 +764,8 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
712 int error; 764 int error;
713 765
714 flush_workqueue(gfs2_delete_workqueue); 766 flush_workqueue(gfs2_delete_workqueue);
715 gfs2_quota_sync(sdp); 767 gfs2_quota_sync(sdp->sd_vfs, 0, 1);
716 gfs2_statfs_sync(sdp); 768 gfs2_statfs_sync(sdp->sd_vfs, 0);
717 769
718 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, 770 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
719 &t_gh); 771 &t_gh);
@@ -808,6 +860,7 @@ restart:
808 gfs2_clear_rgrpd(sdp); 860 gfs2_clear_rgrpd(sdp);
809 gfs2_jindex_free(sdp); 861 gfs2_jindex_free(sdp);
810 /* Take apart glock structures and buffer lists */ 862 /* Take apart glock structures and buffer lists */
863 invalidate_inodes(sdp->sd_vfs);
811 gfs2_gl_hash_clear(sdp); 864 gfs2_gl_hash_clear(sdp);
812 /* Unmount the locking protocol */ 865 /* Unmount the locking protocol */
813 gfs2_lm_unmount(sdp); 866 gfs2_lm_unmount(sdp);
@@ -1061,8 +1114,13 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
1061 1114
1062 spin_lock(&gt->gt_spin); 1115 spin_lock(&gt->gt_spin);
1063 args.ar_commit = gt->gt_log_flush_secs; 1116 args.ar_commit = gt->gt_log_flush_secs;
1117 args.ar_quota_quantum = gt->gt_quota_quantum;
1118 if (gt->gt_statfs_slow)
1119 args.ar_statfs_quantum = 0;
1120 else
1121 args.ar_statfs_quantum = gt->gt_statfs_quantum;
1064 spin_unlock(&gt->gt_spin); 1122 spin_unlock(&gt->gt_spin);
1065 error = gfs2_mount_args(sdp, &args, data); 1123 error = gfs2_mount_args(&args, data);
1066 if (error) 1124 if (error)
1067 return error; 1125 return error;
1068 1126
@@ -1097,8 +1155,21 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
1097 sb->s_flags |= MS_POSIXACL; 1155 sb->s_flags |= MS_POSIXACL;
1098 else 1156 else
1099 sb->s_flags &= ~MS_POSIXACL; 1157 sb->s_flags &= ~MS_POSIXACL;
1158 if (sdp->sd_args.ar_nobarrier)
1159 set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
1160 else
1161 clear_bit(SDF_NOBARRIERS, &sdp->sd_flags);
1100 spin_lock(&gt->gt_spin); 1162 spin_lock(&gt->gt_spin);
1101 gt->gt_log_flush_secs = args.ar_commit; 1163 gt->gt_log_flush_secs = args.ar_commit;
1164 gt->gt_quota_quantum = args.ar_quota_quantum;
1165 if (args.ar_statfs_quantum) {
1166 gt->gt_statfs_slow = 0;
1167 gt->gt_statfs_quantum = args.ar_statfs_quantum;
1168 }
1169 else {
1170 gt->gt_statfs_slow = 1;
1171 gt->gt_statfs_quantum = 30;
1172 }
1102 spin_unlock(&gt->gt_spin); 1173 spin_unlock(&gt->gt_spin);
1103 1174
1104 gfs2_online_uevent(sdp); 1175 gfs2_online_uevent(sdp);
@@ -1124,7 +1195,7 @@ static void gfs2_drop_inode(struct inode *inode)
1124{ 1195{
1125 struct gfs2_inode *ip = GFS2_I(inode); 1196 struct gfs2_inode *ip = GFS2_I(inode);
1126 1197
1127 if (test_bit(GIF_USER, &ip->i_flags) && inode->i_nlink) { 1198 if (inode->i_nlink) {
1128 struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; 1199 struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
1129 if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) 1200 if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
1130 clear_nlink(inode); 1201 clear_nlink(inode);
@@ -1142,18 +1213,12 @@ static void gfs2_clear_inode(struct inode *inode)
1142{ 1213{
1143 struct gfs2_inode *ip = GFS2_I(inode); 1214 struct gfs2_inode *ip = GFS2_I(inode);
1144 1215
1145 /* This tells us its a "real" inode and not one which only 1216 ip->i_gl->gl_object = NULL;
1146 * serves to contain an address space (see rgrp.c, meta_io.c) 1217 gfs2_glock_put(ip->i_gl);
1147 * which therefore doesn't have its own glocks. 1218 ip->i_gl = NULL;
1148 */ 1219 if (ip->i_iopen_gh.gh_gl) {
1149 if (test_bit(GIF_USER, &ip->i_flags)) { 1220 ip->i_iopen_gh.gh_gl->gl_object = NULL;
1150 ip->i_gl->gl_object = NULL; 1221 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
1151 gfs2_glock_put(ip->i_gl);
1152 ip->i_gl = NULL;
1153 if (ip->i_iopen_gh.gh_gl) {
1154 ip->i_iopen_gh.gh_gl->gl_object = NULL;
1155 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
1156 }
1157 } 1222 }
1158} 1223}
1159 1224
@@ -1179,7 +1244,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1179{ 1244{
1180 struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; 1245 struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info;
1181 struct gfs2_args *args = &sdp->sd_args; 1246 struct gfs2_args *args = &sdp->sd_args;
1182 int lfsecs; 1247 int val;
1183 1248
1184 if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) 1249 if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir))
1185 seq_printf(s, ",meta"); 1250 seq_printf(s, ",meta");
@@ -1240,9 +1305,17 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1240 } 1305 }
1241 if (args->ar_discard) 1306 if (args->ar_discard)
1242 seq_printf(s, ",discard"); 1307 seq_printf(s, ",discard");
1243 lfsecs = sdp->sd_tune.gt_log_flush_secs; 1308 val = sdp->sd_tune.gt_log_flush_secs;
1244 if (lfsecs != 60) 1309 if (val != 60)
1245 seq_printf(s, ",commit=%d", lfsecs); 1310 seq_printf(s, ",commit=%d", val);
1311 val = sdp->sd_tune.gt_statfs_quantum;
1312 if (val != 30)
1313 seq_printf(s, ",statfs_quantum=%d", val);
1314 val = sdp->sd_tune.gt_quota_quantum;
1315 if (val != 60)
1316 seq_printf(s, ",quota_quantum=%d", val);
1317 if (args->ar_statfs_percent)
1318 seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
1246 if (args->ar_errors != GFS2_ERRORS_DEFAULT) { 1319 if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
1247 const char *state; 1320 const char *state;
1248 1321
@@ -1259,6 +1332,9 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1259 } 1332 }
1260 seq_printf(s, ",errors=%s", state); 1333 seq_printf(s, ",errors=%s", state);
1261 } 1334 }
1335 if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
1336 seq_printf(s, ",nobarrier");
1337
1262 return 0; 1338 return 0;
1263} 1339}
1264 1340
@@ -1277,9 +1353,6 @@ static void gfs2_delete_inode(struct inode *inode)
1277 struct gfs2_holder gh; 1353 struct gfs2_holder gh;
1278 int error; 1354 int error;
1279 1355
1280 if (!test_bit(GIF_USER, &ip->i_flags))
1281 goto out;
1282
1283 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 1356 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
1284 if (unlikely(error)) { 1357 if (unlikely(error)) {
1285 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 1358 gfs2_glock_dq_uninit(&ip->i_iopen_gh);