aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/bmap.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/bmap.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/bmap.c')
-rw-r--r--fs/gfs2/bmap.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 41abd3f4fc73..98fa07c2b710 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -136,7 +136,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
136 136
137static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size) 137static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
138{ 138{
139 struct gfs2_sbd *sdp = ip->i_sbd; 139 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
140 uint64_t *arr; 140 uint64_t *arr;
141 unsigned int max, height; 141 unsigned int max, height;
142 142
@@ -169,7 +169,7 @@ static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
169 169
170static int build_height(struct inode *inode, unsigned height) 170static int build_height(struct inode *inode, unsigned height)
171{ 171{
172 struct gfs2_inode *ip = inode->u.generic_ip; 172 struct gfs2_inode *ip = GFS2_I(inode);
173 unsigned new_height = height - ip->i_di.di_height; 173 unsigned new_height = height - ip->i_di.di_height;
174 struct buffer_head *dibh; 174 struct buffer_head *dibh;
175 struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; 175 struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
@@ -283,7 +283,7 @@ static int build_height(struct inode *inode, unsigned height)
283static void find_metapath(struct gfs2_inode *ip, uint64_t block, 283static void find_metapath(struct gfs2_inode *ip, uint64_t block,
284 struct metapath *mp) 284 struct metapath *mp)
285{ 285{
286 struct gfs2_sbd *sdp = ip->i_sbd; 286 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
287 uint64_t b = block; 287 uint64_t b = block;
288 unsigned int i; 288 unsigned int i;
289 289
@@ -382,8 +382,8 @@ static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock,
382 int *boundary, 382 int *boundary,
383 struct metapath *mp) 383 struct metapath *mp)
384{ 384{
385 struct gfs2_inode *ip = inode->u.generic_ip; 385 struct gfs2_inode *ip = GFS2_I(inode);
386 struct gfs2_sbd *sdp = ip->i_sbd; 386 struct gfs2_sbd *sdp = GFS2_SB(inode);
387 struct buffer_head *bh; 387 struct buffer_head *bh;
388 int create = *new; 388 int create = *new;
389 unsigned int bsize; 389 unsigned int bsize;
@@ -446,7 +446,7 @@ out:
446 446
447static inline void bmap_lock(struct inode *inode, int create) 447static inline void bmap_lock(struct inode *inode, int create)
448{ 448{
449 struct gfs2_inode *ip = inode->u.generic_ip; 449 struct gfs2_inode *ip = GFS2_I(inode);
450 if (create) 450 if (create)
451 down_write(&ip->i_rw_mutex); 451 down_write(&ip->i_rw_mutex);
452 else 452 else
@@ -455,7 +455,7 @@ static inline void bmap_lock(struct inode *inode, int create)
455 455
456static inline void bmap_unlock(struct inode *inode, int create) 456static inline void bmap_unlock(struct inode *inode, int create)
457{ 457{
458 struct gfs2_inode *ip = inode->u.generic_ip; 458 struct gfs2_inode *ip = GFS2_I(inode);
459 if (create) 459 if (create)
460 up_write(&ip->i_rw_mutex); 460 up_write(&ip->i_rw_mutex);
461 else 461 else
@@ -481,8 +481,8 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *
481 481
482int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) 482int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
483{ 483{
484 struct gfs2_inode *ip = inode->u.generic_ip; 484 struct gfs2_inode *ip = GFS2_I(inode);
485 struct gfs2_sbd *sdp = ip->i_sbd; 485 struct gfs2_sbd *sdp = GFS2_SB(inode);
486 struct metapath mp; 486 struct metapath mp;
487 struct buffer_head *bh; 487 struct buffer_head *bh;
488 int boundary; 488 int boundary;
@@ -541,7 +541,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
541 uint64_t block, int first, block_call_t bc, 541 uint64_t block, int first, block_call_t bc,
542 void *data) 542 void *data)
543{ 543{
544 struct gfs2_sbd *sdp = ip->i_sbd; 544 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
545 struct buffer_head *bh = NULL; 545 struct buffer_head *bh = NULL;
546 uint64_t *top, *bottom; 546 uint64_t *top, *bottom;
547 uint64_t bn; 547 uint64_t bn;
@@ -609,8 +609,8 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
609 struct buffer_head *bh, uint64_t *top, uint64_t *bottom, 609 struct buffer_head *bh, uint64_t *top, uint64_t *bottom,
610 unsigned int height, void *data) 610 unsigned int height, void *data)
611{ 611{
612 struct strip_mine *sm = (struct strip_mine *)data; 612 struct strip_mine *sm = data;
613 struct gfs2_sbd *sdp = ip->i_sbd; 613 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
614 struct gfs2_rgrp_list rlist; 614 struct gfs2_rgrp_list rlist;
615 uint64_t bn, bstart; 615 uint64_t bn, bstart;
616 uint32_t blen; 616 uint32_t blen;
@@ -756,7 +756,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
756 756
757static int do_grow(struct gfs2_inode *ip, uint64_t size) 757static int do_grow(struct gfs2_inode *ip, uint64_t size)
758{ 758{
759 struct gfs2_sbd *sdp = ip->i_sbd; 759 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
760 struct gfs2_alloc *al; 760 struct gfs2_alloc *al;
761 struct buffer_head *dibh; 761 struct buffer_head *dibh;
762 unsigned int h; 762 unsigned int h;
@@ -795,7 +795,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
795 h = calc_tree_height(ip, size); 795 h = calc_tree_height(ip, size);
796 if (ip->i_di.di_height < h) { 796 if (ip->i_di.di_height < h) {
797 down_write(&ip->i_rw_mutex); 797 down_write(&ip->i_rw_mutex);
798 error = build_height(ip->i_vnode, h); 798 error = build_height(&ip->i_inode, h);
799 up_write(&ip->i_rw_mutex); 799 up_write(&ip->i_rw_mutex);
800 if (error) 800 if (error)
801 goto out_end_trans; 801 goto out_end_trans;
@@ -830,7 +830,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
830 830
831static int trunc_start(struct gfs2_inode *ip, uint64_t size) 831static int trunc_start(struct gfs2_inode *ip, uint64_t size)
832{ 832{
833 struct gfs2_sbd *sdp = ip->i_sbd; 833 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
834 struct buffer_head *dibh; 834 struct buffer_head *dibh;
835 int journaled = gfs2_is_jdata(ip); 835 int journaled = gfs2_is_jdata(ip);
836 int error; 836 int error;
@@ -854,7 +854,7 @@ static int trunc_start(struct gfs2_inode *ip, uint64_t size)
854 854
855 } else { 855 } else {
856 if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1)) 856 if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1))
857 error = gfs2_block_truncate_page(ip->i_vnode->i_mapping); 857 error = gfs2_block_truncate_page(ip->i_inode.i_mapping);
858 858
859 if (!error) { 859 if (!error) {
860 ip->i_di.di_size = size; 860 ip->i_di.di_size = size;
@@ -883,7 +883,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, uint64_t size)
883 if (!size) 883 if (!size)
884 lblock = 0; 884 lblock = 0;
885 else 885 else
886 lblock = (size - 1) >> ip->i_sbd->sd_sb.sb_bsize_shift; 886 lblock = (size - 1) >> GFS2_SB(&ip->i_inode)->sd_sb.sb_bsize_shift;
887 887
888 find_metapath(ip, lblock, &mp); 888 find_metapath(ip, lblock, &mp);
889 gfs2_alloc_get(ip); 889 gfs2_alloc_get(ip);
@@ -911,7 +911,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, uint64_t size)
911 911
912static int trunc_end(struct gfs2_inode *ip) 912static int trunc_end(struct gfs2_inode *ip)
913{ 913{
914 struct gfs2_sbd *sdp = ip->i_sbd; 914 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
915 struct buffer_head *dibh; 915 struct buffer_head *dibh;
916 int error; 916 int error;
917 917
@@ -990,7 +990,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size)
990{ 990{
991 int error; 991 int error;
992 992
993 if (gfs2_assert_warn(ip->i_sbd, S_ISREG(ip->i_di.di_mode))) 993 if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode)))
994 return -EINVAL; 994 return -EINVAL;
995 995
996 if (size > ip->i_di.di_size) 996 if (size > ip->i_di.di_size)
@@ -1027,7 +1027,7 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
1027void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len, 1027void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
1028 unsigned int *data_blocks, unsigned int *ind_blocks) 1028 unsigned int *data_blocks, unsigned int *ind_blocks)
1029{ 1029{
1030 struct gfs2_sbd *sdp = ip->i_sbd; 1030 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1031 unsigned int tmp; 1031 unsigned int tmp;
1032 1032
1033 if (gfs2_is_dir(ip)) { 1033 if (gfs2_is_dir(ip)) {
@@ -1057,7 +1057,7 @@ void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
1057int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset, 1057int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
1058 unsigned int len, int *alloc_required) 1058 unsigned int len, int *alloc_required)
1059{ 1059{
1060 struct gfs2_sbd *sdp = ip->i_sbd; 1060 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1061 uint64_t lblock, lblock_stop, dblock; 1061 uint64_t lblock, lblock_stop, dblock;
1062 uint32_t extlen; 1062 uint32_t extlen;
1063 int new = 0; 1063 int new = 0;
@@ -1088,7 +1088,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
1088 } 1088 }
1089 1089
1090 for (; lblock < lblock_stop; lblock += extlen) { 1090 for (; lblock < lblock_stop; lblock += extlen) {
1091 error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen); 1091 error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
1092 if (error) 1092 if (error)
1093 return error; 1093 return error;
1094 1094