aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-12-06 11:19:54 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-01-03 05:01:50 -0500
commit70d4ee94b370c5ef54d0870600f16bd92d18013c (patch)
treeae741f94eba92bdb6e2882145de03be662557f66
parent7005c3e4ae42858dbb695b2d03d340af799b1f1b (diff)
GFS2: Use only a single address space for rgrps
Prior to this patch, GFS2 had one address space for each rgrp, stored in the glock. This patch changes them to use a single address space in the super block. This therefore saves (sizeof(struct address_space) * nr_of_rgrps) bytes of memory and for large filesystems, that can be significant. It would be nice to be able to do something similar and merge the inode metadata address space into the same global address space. However, that is rather more complicated as the on-disk location doesn't have a 1:1 mapping with the inodes in general. So while it could be done, it will be a more complicated operation as it requires changing a lot more code paths. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/glops.c18
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/lops.c4
-rw-r--r--fs/gfs2/meta_io.c3
-rw-r--r--fs/gfs2/ops_fstype.c12
5 files changed, 31 insertions, 8 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 1b192c8d404d..b792dbcc83f6 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -133,7 +133,8 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
133 133
134static void rgrp_go_sync(struct gfs2_glock *gl) 134static void rgrp_go_sync(struct gfs2_glock *gl)
135{ 135{
136 struct address_space *metamapping = gfs2_glock2aspace(gl); 136 struct gfs2_sbd *sdp = gl->gl_sbd;
137 struct address_space *mapping = &sdp->sd_aspace;
137 struct gfs2_rgrpd *rgd; 138 struct gfs2_rgrpd *rgd;
138 int error; 139 int error;
139 140
@@ -141,10 +142,10 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
141 return; 142 return;
142 GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); 143 GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
143 144
144 gfs2_log_flush(gl->gl_sbd, gl); 145 gfs2_log_flush(sdp, gl);
145 filemap_fdatawrite_range(metamapping, gl->gl_vm.start, gl->gl_vm.end); 146 filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
146 error = filemap_fdatawait_range(metamapping, gl->gl_vm.start, gl->gl_vm.end); 147 error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
147 mapping_set_error(metamapping, error); 148 mapping_set_error(mapping, error);
148 gfs2_ail_empty_gl(gl); 149 gfs2_ail_empty_gl(gl);
149 150
150 spin_lock(&gl->gl_spin); 151 spin_lock(&gl->gl_spin);
@@ -166,10 +167,11 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
166 167
167static void rgrp_go_inval(struct gfs2_glock *gl, int flags) 168static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
168{ 169{
169 struct address_space *mapping = gfs2_glock2aspace(gl); 170 struct gfs2_sbd *sdp = gl->gl_sbd;
171 struct address_space *mapping = &sdp->sd_aspace;
170 172
171 WARN_ON_ONCE(!(flags & DIO_METADATA)); 173 WARN_ON_ONCE(!(flags & DIO_METADATA));
172 gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count)); 174 gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
173 truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end); 175 truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
174 176
175 if (gl->gl_object) { 177 if (gl->gl_object) {
@@ -558,7 +560,7 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = {
558 .go_unlock = gfs2_rgrp_go_unlock, 560 .go_unlock = gfs2_rgrp_go_unlock,
559 .go_dump = gfs2_rgrp_dump, 561 .go_dump = gfs2_rgrp_dump,
560 .go_type = LM_TYPE_RGRP, 562 .go_type = LM_TYPE_RGRP,
561 .go_flags = GLOF_ASPACE | GLOF_LVB, 563 .go_flags = GLOF_LVB,
562}; 564};
563 565
564const struct gfs2_glock_operations gfs2_trans_glops = { 566const struct gfs2_glock_operations gfs2_trans_glops = {
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index e6544ee0c137..a99f60c98845 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -736,6 +736,8 @@ struct gfs2_sbd {
736 736
737 /* Log stuff */ 737 /* Log stuff */
738 738
739 struct address_space sd_aspace;
740
739 spinlock_t sd_log_lock; 741 spinlock_t sd_log_lock;
740 742
741 struct gfs2_trans *sd_log_tr; 743 struct gfs2_trans *sd_log_tr;
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index cdadb92372f2..58f06400b7b8 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -589,8 +589,12 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
589static void gfs2_meta_sync(struct gfs2_glock *gl) 589static void gfs2_meta_sync(struct gfs2_glock *gl)
590{ 590{
591 struct address_space *mapping = gfs2_glock2aspace(gl); 591 struct address_space *mapping = gfs2_glock2aspace(gl);
592 struct gfs2_sbd *sdp = gl->gl_sbd;
592 int error; 593 int error;
593 594
595 if (mapping == NULL)
596 mapping = &sdp->sd_aspace;
597
594 filemap_fdatawrite(mapping); 598 filemap_fdatawrite(mapping);
595 error = filemap_fdatawait(mapping); 599 error = filemap_fdatawait(mapping);
596 600
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 52f177be3bf8..c7f24690ed05 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -116,6 +116,9 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
116 unsigned long index; 116 unsigned long index;
117 unsigned int bufnum; 117 unsigned int bufnum;
118 118
119 if (mapping == NULL)
120 mapping = &sdp->sd_aspace;
121
119 shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift; 122 shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift;
120 index = blkno >> shift; /* convert block to page */ 123 index = blkno >> shift; /* convert block to page */
121 bufnum = blkno - (index << shift); /* block buf index within page */ 124 bufnum = blkno - (index << shift); /* block buf index within page */
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 52fa88314f5c..94aab31477b6 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -36,6 +36,7 @@
36#include "log.h" 36#include "log.h"
37#include "quota.h" 37#include "quota.h"
38#include "dir.h" 38#include "dir.h"
39#include "meta_io.h"
39#include "trace_gfs2.h" 40#include "trace_gfs2.h"
40 41
41#define DO 0 42#define DO 0
@@ -62,6 +63,7 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
62static struct gfs2_sbd *init_sbd(struct super_block *sb) 63static struct gfs2_sbd *init_sbd(struct super_block *sb)
63{ 64{
64 struct gfs2_sbd *sdp; 65 struct gfs2_sbd *sdp;
66 struct address_space *mapping;
65 67
66 sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL); 68 sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL);
67 if (!sdp) 69 if (!sdp)
@@ -98,6 +100,16 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
98 INIT_LIST_HEAD(&sdp->sd_trunc_list); 100 INIT_LIST_HEAD(&sdp->sd_trunc_list);
99 spin_lock_init(&sdp->sd_trunc_lock); 101 spin_lock_init(&sdp->sd_trunc_lock);
100 102
103 mapping = &sdp->sd_aspace;
104
105 mapping->a_ops = &gfs2_meta_aops;
106 mapping->host = sb->s_bdev->bd_inode;
107 mapping->flags = 0;
108 mapping_set_gfp_mask(mapping, GFP_NOFS);
109 mapping->private_data = NULL;
110 mapping->backing_dev_info = sb->s_bdi;
111 mapping->writeback_index = 0;
112
101 spin_lock_init(&sdp->sd_log_lock); 113 spin_lock_init(&sdp->sd_log_lock);
102 atomic_set(&sdp->sd_log_pinned, 0); 114 atomic_set(&sdp->sd_log_pinned, 0);
103 INIT_LIST_HEAD(&sdp->sd_log_le_buf); 115 INIT_LIST_HEAD(&sdp->sd_log_le_buf);