aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-06-14 15:32:57 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-06-14 15:32:57 -0400
commitfeaa7bba026c181ce071d5a4884f7f9dd26207a1 (patch)
treec858deb225917265cb07820730e9764674d133e8 /fs/gfs2/super.c
parent22da645fd6675b7abc55cf937ddf6132f343e5b9 (diff)
[GFS2] Fix unlinked file handling
This patch fixes the way we have been dealing with unlinked, but still open files. It removes all limits (other than memory for inodes, as per every other filesystem) on numbers of these which we can support on GFS2. It also means that (like other fs) its the responsibility of the last process to close the file to deallocate the storage, rather than the person who did the unlinking. Note that with GFS2, those two events might take place on different nodes. Also there are a number of other changes: o We use the Linux inode subsystem as it was intended to be used, wrt allocating GFS2 inodes o The Linux inode cache is now the point which we use for local enforcement of only holding one copy of the inode in core at once (previous to this we used the glock layer). o We no longer use the unlinked "special" file. We just ignore it completely. This makes unlinking more efficient. o We now use the 4th block allocation state. The previously unused state is used to track unlinked but still open inodes. o gfs2_inoded is no longer needed o Several fields are now no longer needed (and removed) from the in core struct gfs2_inode o Several fields are no longer needed (and removed) from the in core superblock There are a number of future possible optimisations and clean ups which have been made possible by this patch. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c45
1 files changed, 14 insertions, 31 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index a943a505bc5a..f2d287660cc9 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -31,7 +31,6 @@
31#include "rgrp.h" 31#include "rgrp.h"
32#include "super.h" 32#include "super.h"
33#include "trans.h" 33#include "trans.h"
34#include "unlinked.h"
35#include "util.h" 34#include "util.h"
36 35
37/** 36/**
@@ -55,7 +54,6 @@ void gfs2_tune_init(struct gfs2_tune *gt)
55 gt->gt_recoverd_secs = 60; 54 gt->gt_recoverd_secs = 60;
56 gt->gt_logd_secs = 1; 55 gt->gt_logd_secs = 1;
57 gt->gt_quotad_secs = 5; 56 gt->gt_quotad_secs = 5;
58 gt->gt_inoded_secs = 15;
59 gt->gt_quota_simul_sync = 64; 57 gt->gt_quota_simul_sync = 64;
60 gt->gt_quota_warn_period = 10; 58 gt->gt_quota_warn_period = 10;
61 gt->gt_quota_scale_num = 1; 59 gt->gt_quota_scale_num = 1;
@@ -202,9 +200,6 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
202 sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; 200 sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
203 sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; 201 sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
204 sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); 202 sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
205 sdp->sd_ut_per_block = (sdp->sd_sb.sb_bsize -
206 sizeof(struct gfs2_meta_header)) /
207 sizeof(struct gfs2_unlinked_tag);
208 sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize - 203 sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
209 sizeof(struct gfs2_meta_header)) / 204 sizeof(struct gfs2_meta_header)) /
210 sizeof(struct gfs2_quota_change); 205 sizeof(struct gfs2_quota_change);
@@ -277,7 +272,7 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
277 272
278int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) 273int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
279{ 274{
280 struct gfs2_inode *dip = sdp->sd_jindex->u.generic_ip; 275 struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex);
281 struct qstr name; 276 struct qstr name;
282 char buf[20]; 277 char buf[20];
283 struct gfs2_jdesc *jd; 278 struct gfs2_jdesc *jd;
@@ -296,8 +291,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
296 name.len = sprintf(buf, "journal%u", sdp->sd_journals); 291 name.len = sprintf(buf, "journal%u", sdp->sd_journals);
297 name.hash = gfs2_disk_hash(name.name, name.len); 292 name.hash = gfs2_disk_hash(name.name, name.len);
298 293
299 error = gfs2_dir_search(sdp->sd_jindex, 294 error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL);
300 &name, NULL, NULL);
301 if (error == -ENOENT) { 295 if (error == -ENOENT) {
302 error = 0; 296 error = 0;
303 break; 297 break;
@@ -423,22 +417,19 @@ struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp)
423 417
424int gfs2_jdesc_check(struct gfs2_jdesc *jd) 418int gfs2_jdesc_check(struct gfs2_jdesc *jd)
425{ 419{
426 struct gfs2_inode *ip = jd->jd_inode->u.generic_ip; 420 struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
427 struct gfs2_sbd *sdp = ip->i_sbd; 421 struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
428 int ar; 422 int ar;
429 int error; 423 int error;
430 424
431 if (ip->i_di.di_size < (8 << 20) || 425 if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) ||
432 ip->i_di.di_size > (1 << 30) ||
433 (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) { 426 (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) {
434 gfs2_consist_inode(ip); 427 gfs2_consist_inode(ip);
435 return -EIO; 428 return -EIO;
436 } 429 }
437 jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; 430 jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
438 431
439 error = gfs2_write_alloc_required(ip, 432 error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar);
440 0, ip->i_di.di_size,
441 &ar);
442 if (!error && ar) { 433 if (!error && ar) {
443 gfs2_consist_inode(ip); 434 gfs2_consist_inode(ip);
444 error = -EIO; 435 error = -EIO;
@@ -456,7 +447,7 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
456 447
457int gfs2_make_fs_rw(struct gfs2_sbd *sdp) 448int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
458{ 449{
459 struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip; 450 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
460 struct gfs2_glock *j_gl = ip->i_gl; 451 struct gfs2_glock *j_gl = ip->i_gl;
461 struct gfs2_holder t_gh; 452 struct gfs2_holder t_gh;
462 struct gfs2_log_header head; 453 struct gfs2_log_header head;
@@ -484,9 +475,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
484 sdp->sd_log_sequence = head.lh_sequence + 1; 475 sdp->sd_log_sequence = head.lh_sequence + 1;
485 gfs2_log_pointers_init(sdp, head.lh_blkno); 476 gfs2_log_pointers_init(sdp, head.lh_blkno);
486 477
487 error = gfs2_unlinked_init(sdp);
488 if (error)
489 goto fail;
490 error = gfs2_quota_init(sdp); 478 error = gfs2_quota_init(sdp);
491 if (error) 479 if (error)
492 goto fail_unlinked; 480 goto fail_unlinked;
@@ -498,7 +486,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
498 return 0; 486 return 0;
499 487
500 fail_unlinked: 488 fail_unlinked:
501 gfs2_unlinked_cleanup(sdp);
502 489
503 fail: 490 fail:
504 t_gh.gh_flags |= GL_NOCACHE; 491 t_gh.gh_flags |= GL_NOCACHE;
@@ -519,7 +506,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
519 struct gfs2_holder t_gh; 506 struct gfs2_holder t_gh;
520 int error; 507 int error;
521 508
522 gfs2_unlinked_dealloc(sdp);
523 gfs2_quota_sync(sdp); 509 gfs2_quota_sync(sdp);
524 gfs2_statfs_sync(sdp); 510 gfs2_statfs_sync(sdp);
525 511
@@ -537,7 +523,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
537 if (t_gh.gh_gl) 523 if (t_gh.gh_gl)
538 gfs2_glock_dq_uninit(&t_gh); 524 gfs2_glock_dq_uninit(&t_gh);
539 525
540 gfs2_unlinked_cleanup(sdp);
541 gfs2_quota_cleanup(sdp); 526 gfs2_quota_cleanup(sdp);
542 527
543 return error; 528 return error;
@@ -545,9 +530,9 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
545 530
546int gfs2_statfs_init(struct gfs2_sbd *sdp) 531int gfs2_statfs_init(struct gfs2_sbd *sdp)
547{ 532{
548 struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip; 533 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
549 struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; 534 struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
550 struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip; 535 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
551 struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; 536 struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
552 struct buffer_head *m_bh, *l_bh; 537 struct buffer_head *m_bh, *l_bh;
553 struct gfs2_holder gh; 538 struct gfs2_holder gh;
@@ -594,7 +579,7 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
594void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free, 579void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
595 int64_t dinodes) 580 int64_t dinodes)
596{ 581{
597 struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip; 582 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
598 struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; 583 struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
599 struct buffer_head *l_bh; 584 struct buffer_head *l_bh;
600 int error; 585 int error;
@@ -620,8 +605,8 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
620 605
621int gfs2_statfs_sync(struct gfs2_sbd *sdp) 606int gfs2_statfs_sync(struct gfs2_sbd *sdp)
622{ 607{
623 struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip; 608 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
624 struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip; 609 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
625 struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; 610 struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
626 struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; 611 struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
627 struct gfs2_holder gh; 612 struct gfs2_holder gh;
@@ -852,10 +837,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
852 error = -ENOMEM; 837 error = -ENOMEM;
853 goto out; 838 goto out;
854 } 839 }
855 ip = jd->jd_inode->u.generic_ip; 840 ip = GFS2_I(jd->jd_inode);
856 error = gfs2_glock_nq_init(ip->i_gl, 841 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh);
857 LM_ST_SHARED, 0,
858 &lfcc->gh);
859 if (error) { 842 if (error) {
860 kfree(lfcc); 843 kfree(lfcc);
861 goto out; 844 goto out;