aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/ops_super.c')
-rw-r--r--fs/gfs2/ops_super.c165
1 files changed, 146 insertions, 19 deletions
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index d5355d9b5926..320323d03479 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -28,7 +28,6 @@
28#include "inode.h" 28#include "inode.h"
29#include "log.h" 29#include "log.h"
30#include "mount.h" 30#include "mount.h"
31#include "ops_super.h"
32#include "quota.h" 31#include "quota.h"
33#include "recovery.h" 32#include "recovery.h"
34#include "rgrp.h" 33#include "rgrp.h"
@@ -143,8 +142,6 @@ static void gfs2_put_super(struct super_block *sb)
143 kthread_stop(sdp->sd_quotad_process); 142 kthread_stop(sdp->sd_quotad_process);
144 kthread_stop(sdp->sd_logd_process); 143 kthread_stop(sdp->sd_logd_process);
145 kthread_stop(sdp->sd_recoverd_process); 144 kthread_stop(sdp->sd_recoverd_process);
146 while (sdp->sd_glockd_num--)
147 kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
148 145
149 if (!(sb->s_flags & MS_RDONLY)) { 146 if (!(sb->s_flags & MS_RDONLY)) {
150 error = gfs2_make_fs_ro(sdp); 147 error = gfs2_make_fs_ro(sdp);
@@ -185,7 +182,6 @@ static void gfs2_put_super(struct super_block *sb)
185 182
186 /* At this point, we're through participating in the lockspace */ 183 /* At this point, we're through participating in the lockspace */
187 gfs2_sys_fs_del(sdp); 184 gfs2_sys_fs_del(sdp);
188 kfree(sdp);
189} 185}
190 186
191/** 187/**
@@ -215,18 +211,18 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
215} 211}
216 212
217/** 213/**
218 * gfs2_write_super_lockfs - prevent further writes to the filesystem 214 * gfs2_freeze - prevent further writes to the filesystem
219 * @sb: the VFS structure for the filesystem 215 * @sb: the VFS structure for the filesystem
220 * 216 *
221 */ 217 */
222 218
223static void gfs2_write_super_lockfs(struct super_block *sb) 219static int gfs2_freeze(struct super_block *sb)
224{ 220{
225 struct gfs2_sbd *sdp = sb->s_fs_info; 221 struct gfs2_sbd *sdp = sb->s_fs_info;
226 int error; 222 int error;
227 223
228 if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 224 if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
229 return; 225 return -EINVAL;
230 226
231 for (;;) { 227 for (;;) {
232 error = gfs2_freeze_fs(sdp); 228 error = gfs2_freeze_fs(sdp);
@@ -246,17 +242,150 @@ static void gfs2_write_super_lockfs(struct super_block *sb)
246 fs_err(sdp, "retrying...\n"); 242 fs_err(sdp, "retrying...\n");
247 msleep(1000); 243 msleep(1000);
248 } 244 }
245 return 0;
249} 246}
250 247
251/** 248/**
252 * gfs2_unlockfs - reallow writes to the filesystem 249 * gfs2_unfreeze - reallow writes to the filesystem
253 * @sb: the VFS structure for the filesystem 250 * @sb: the VFS structure for the filesystem
254 * 251 *
255 */ 252 */
256 253
257static void gfs2_unlockfs(struct super_block *sb) 254static int gfs2_unfreeze(struct super_block *sb)
258{ 255{
259 gfs2_unfreeze_fs(sb->s_fs_info); 256 gfs2_unfreeze_fs(sb->s_fs_info);
257 return 0;
258}
259
260/**
261 * statfs_fill - fill in the sg for a given RG
262 * @rgd: the RG
263 * @sc: the sc structure
264 *
265 * Returns: 0 on success, -ESTALE if the LVB is invalid
266 */
267
268static int statfs_slow_fill(struct gfs2_rgrpd *rgd,
269 struct gfs2_statfs_change_host *sc)
270{
271 gfs2_rgrp_verify(rgd);
272 sc->sc_total += rgd->rd_data;
273 sc->sc_free += rgd->rd_free;
274 sc->sc_dinodes += rgd->rd_dinodes;
275 return 0;
276}
277
278/**
279 * gfs2_statfs_slow - Stat a filesystem using asynchronous locking
280 * @sdp: the filesystem
281 * @sc: the sc info that will be returned
282 *
283 * Any error (other than a signal) will cause this routine to fall back
284 * to the synchronous version.
285 *
286 * FIXME: This really shouldn't busy wait like this.
287 *
288 * Returns: errno
289 */
290
291static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
292{
293 struct gfs2_holder ri_gh;
294 struct gfs2_rgrpd *rgd_next;
295 struct gfs2_holder *gha, *gh;
296 unsigned int slots = 64;
297 unsigned int x;
298 int done;
299 int error = 0, err;
300
301 memset(sc, 0, sizeof(struct gfs2_statfs_change_host));
302 gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL);
303 if (!gha)
304 return -ENOMEM;
305
306 error = gfs2_rindex_hold(sdp, &ri_gh);
307 if (error)
308 goto out;
309
310 rgd_next = gfs2_rgrpd_get_first(sdp);
311
312 for (;;) {
313 done = 1;
314
315 for (x = 0; x < slots; x++) {
316 gh = gha + x;
317
318 if (gh->gh_gl && gfs2_glock_poll(gh)) {
319 err = gfs2_glock_wait(gh);
320 if (err) {
321 gfs2_holder_uninit(gh);
322 error = err;
323 } else {
324 if (!error)
325 error = statfs_slow_fill(
326 gh->gh_gl->gl_object, sc);
327 gfs2_glock_dq_uninit(gh);
328 }
329 }
330
331 if (gh->gh_gl)
332 done = 0;
333 else if (rgd_next && !error) {
334 error = gfs2_glock_nq_init(rgd_next->rd_gl,
335 LM_ST_SHARED,
336 GL_ASYNC,
337 gh);
338 rgd_next = gfs2_rgrpd_get_next(rgd_next);
339 done = 0;
340 }
341
342 if (signal_pending(current))
343 error = -ERESTARTSYS;
344 }
345
346 if (done)
347 break;
348
349 yield();
350 }
351
352 gfs2_glock_dq_uninit(&ri_gh);
353
354out:
355 kfree(gha);
356 return error;
357}
358
359/**
360 * gfs2_statfs_i - Do a statfs
361 * @sdp: the filesystem
362 * @sg: the sg structure
363 *
364 * Returns: errno
365 */
366
367static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
368{
369 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
370 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
371
372 spin_lock(&sdp->sd_statfs_spin);
373
374 *sc = *m_sc;
375 sc->sc_total += l_sc->sc_total;
376 sc->sc_free += l_sc->sc_free;
377 sc->sc_dinodes += l_sc->sc_dinodes;
378
379 spin_unlock(&sdp->sd_statfs_spin);
380
381 if (sc->sc_free < 0)
382 sc->sc_free = 0;
383 if (sc->sc_free > sc->sc_total)
384 sc->sc_free = sc->sc_total;
385 if (sc->sc_dinodes < 0)
386 sc->sc_dinodes = 0;
387
388 return 0;
260} 389}
261 390
262/** 391/**
@@ -370,7 +499,6 @@ static void gfs2_clear_inode(struct inode *inode)
370 */ 499 */
371 if (test_bit(GIF_USER, &ip->i_flags)) { 500 if (test_bit(GIF_USER, &ip->i_flags)) {
372 ip->i_gl->gl_object = NULL; 501 ip->i_gl->gl_object = NULL;
373 gfs2_glock_schedule_for_reclaim(ip->i_gl);
374 gfs2_glock_put(ip->i_gl); 502 gfs2_glock_put(ip->i_gl);
375 ip->i_gl = NULL; 503 ip->i_gl = NULL;
376 if (ip->i_iopen_gh.gh_gl) { 504 if (ip->i_iopen_gh.gh_gl) {
@@ -423,8 +551,6 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
423 seq_printf(s, ",debug"); 551 seq_printf(s, ",debug");
424 if (args->ar_upgrade) 552 if (args->ar_upgrade)
425 seq_printf(s, ",upgrade"); 553 seq_printf(s, ",upgrade");
426 if (args->ar_num_glockd != GFS2_GLOCKD_DEFAULT)
427 seq_printf(s, ",num_glockd=%u", args->ar_num_glockd);
428 if (args->ar_posix_acl) 554 if (args->ar_posix_acl)
429 seq_printf(s, ",acl"); 555 seq_printf(s, ",acl");
430 if (args->ar_quota != GFS2_QUOTA_DEFAULT) { 556 if (args->ar_quota != GFS2_QUOTA_DEFAULT) {
@@ -494,16 +620,16 @@ static void gfs2_delete_inode(struct inode *inode)
494 gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); 620 gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
495 error = gfs2_glock_nq(&ip->i_iopen_gh); 621 error = gfs2_glock_nq(&ip->i_iopen_gh);
496 if (error) 622 if (error)
497 goto out_uninit; 623 goto out_truncate;
498 624
499 if (S_ISDIR(inode->i_mode) && 625 if (S_ISDIR(inode->i_mode) &&
500 (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { 626 (ip->i_diskflags & GFS2_DIF_EXHASH)) {
501 error = gfs2_dir_exhash_dealloc(ip); 627 error = gfs2_dir_exhash_dealloc(ip);
502 if (error) 628 if (error)
503 goto out_unlock; 629 goto out_unlock;
504 } 630 }
505 631
506 if (ip->i_di.di_eattr) { 632 if (ip->i_eattr) {
507 error = gfs2_ea_dealloc(ip); 633 error = gfs2_ea_dealloc(ip);
508 if (error) 634 if (error)
509 goto out_unlock; 635 goto out_unlock;
@@ -519,6 +645,7 @@ static void gfs2_delete_inode(struct inode *inode)
519 if (error) 645 if (error)
520 goto out_unlock; 646 goto out_unlock;
521 647
648out_truncate:
522 error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); 649 error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
523 if (error) 650 if (error)
524 goto out_unlock; 651 goto out_unlock;
@@ -527,8 +654,8 @@ static void gfs2_delete_inode(struct inode *inode)
527 gfs2_trans_end(sdp); 654 gfs2_trans_end(sdp);
528 655
529out_unlock: 656out_unlock:
530 gfs2_glock_dq(&ip->i_iopen_gh); 657 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
531out_uninit: 658 gfs2_glock_dq(&ip->i_iopen_gh);
532 gfs2_holder_uninit(&ip->i_iopen_gh); 659 gfs2_holder_uninit(&ip->i_iopen_gh);
533 gfs2_glock_dq_uninit(&gh); 660 gfs2_glock_dq_uninit(&gh);
534 if (error && error != GLR_TRYFAILED) 661 if (error && error != GLR_TRYFAILED)
@@ -563,8 +690,8 @@ const struct super_operations gfs2_super_ops = {
563 .put_super = gfs2_put_super, 690 .put_super = gfs2_put_super,
564 .write_super = gfs2_write_super, 691 .write_super = gfs2_write_super,
565 .sync_fs = gfs2_sync_fs, 692 .sync_fs = gfs2_sync_fs,
566 .write_super_lockfs = gfs2_write_super_lockfs, 693 .freeze_fs = gfs2_freeze,
567 .unlockfs = gfs2_unlockfs, 694 .unfreeze_fs = gfs2_unfreeze,
568 .statfs = gfs2_statfs, 695 .statfs = gfs2_statfs,
569 .remount_fs = gfs2_remount_fs, 696 .remount_fs = gfs2_remount_fs,
570 .clear_inode = gfs2_clear_inode, 697 .clear_inode = gfs2_clear_inode,