diff options
-rw-r--r-- | fs/gfs2/glops.c | 115 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 21 | ||||
-rw-r--r-- | fs/gfs2/meta_io.h | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_file.c | 3 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 6 |
5 files changed, 57 insertions, 89 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index f34bc7093dd1..bf23a62aa925 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -76,29 +76,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /** | 78 | /** |
79 | * gfs2_pte_inval - Sync and invalidate all PTEs associated with a glock | 79 | * rgrp_go_sync - sync out the metadata for this glock |
80 | * @gl: the glock | ||
81 | * | ||
82 | */ | ||
83 | |||
84 | static void gfs2_pte_inval(struct gfs2_glock *gl) | ||
85 | { | ||
86 | struct gfs2_inode *ip; | ||
87 | struct inode *inode; | ||
88 | |||
89 | ip = gl->gl_object; | ||
90 | inode = &ip->i_inode; | ||
91 | if (!ip || !S_ISREG(inode->i_mode)) | ||
92 | return; | ||
93 | |||
94 | unmap_shared_mapping_range(inode->i_mapping, 0, 0); | ||
95 | if (test_bit(GIF_SW_PAGED, &ip->i_flags)) | ||
96 | set_bit(GLF_DIRTY, &gl->gl_flags); | ||
97 | |||
98 | } | ||
99 | |||
100 | /** | ||
101 | * meta_go_sync - sync out the metadata for this glock | ||
102 | * @gl: the glock | 80 | * @gl: the glock |
103 | * | 81 | * |
104 | * Called when demoting or unlocking an EX glock. We must flush | 82 | * Called when demoting or unlocking an EX glock. We must flush |
@@ -106,36 +84,42 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
106 | * not return to caller to demote/unlock the glock until I/O is complete. | 84 | * not return to caller to demote/unlock the glock until I/O is complete. |
107 | */ | 85 | */ |
108 | 86 | ||
109 | static void meta_go_sync(struct gfs2_glock *gl) | 87 | static void rgrp_go_sync(struct gfs2_glock *gl) |
110 | { | 88 | { |
111 | if (gl->gl_state != LM_ST_EXCLUSIVE) | 89 | struct address_space *metamapping = gl->gl_aspace->i_mapping; |
90 | int error; | ||
91 | |||
92 | if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) | ||
112 | return; | 93 | return; |
94 | BUG_ON(gl->gl_state != LM_ST_EXCLUSIVE); | ||
113 | 95 | ||
114 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { | 96 | gfs2_log_flush(gl->gl_sbd, gl); |
115 | gfs2_log_flush(gl->gl_sbd, gl); | 97 | filemap_fdatawrite(metamapping); |
116 | gfs2_meta_sync(gl); | 98 | error = filemap_fdatawait(metamapping); |
117 | gfs2_ail_empty_gl(gl); | 99 | mapping_set_error(metamapping, error); |
118 | } | 100 | gfs2_ail_empty_gl(gl); |
119 | } | 101 | } |
120 | 102 | ||
121 | /** | 103 | /** |
122 | * meta_go_inval - invalidate the metadata for this glock | 104 | * rgrp_go_inval - invalidate the metadata for this glock |
123 | * @gl: the glock | 105 | * @gl: the glock |
124 | * @flags: | 106 | * @flags: |
125 | * | 107 | * |
108 | * We never used LM_ST_DEFERRED with resource groups, so that we | ||
109 | * should always see the metadata flag set here. | ||
110 | * | ||
126 | */ | 111 | */ |
127 | 112 | ||
128 | static void meta_go_inval(struct gfs2_glock *gl, int flags) | 113 | static void rgrp_go_inval(struct gfs2_glock *gl, int flags) |
129 | { | 114 | { |
130 | if (!(flags & DIO_METADATA)) | 115 | struct address_space *mapping = gl->gl_aspace->i_mapping; |
131 | return; | ||
132 | 116 | ||
133 | gfs2_meta_inval(gl); | 117 | BUG_ON(!(flags & DIO_METADATA)); |
134 | if (gl->gl_object == GFS2_I(gl->gl_sbd->sd_rindex)) | 118 | gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count)); |
135 | gl->gl_sbd->sd_rindex_uptodate = 0; | 119 | truncate_inode_pages(mapping, 0); |
136 | else if (gl->gl_ops == &gfs2_rgrp_glops && gl->gl_object) { | ||
137 | struct gfs2_rgrpd *rgd = (struct gfs2_rgrpd *)gl->gl_object; | ||
138 | 120 | ||
121 | if (gl->gl_object) { | ||
122 | struct gfs2_rgrpd *rgd = (struct gfs2_rgrpd *)gl->gl_object; | ||
139 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; | 123 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
140 | } | 124 | } |
141 | } | 125 | } |
@@ -152,48 +136,54 @@ static void inode_go_sync(struct gfs2_glock *gl) | |||
152 | struct address_space *metamapping = gl->gl_aspace->i_mapping; | 136 | struct address_space *metamapping = gl->gl_aspace->i_mapping; |
153 | int error; | 137 | int error; |
154 | 138 | ||
155 | if (gl->gl_state != LM_ST_UNLOCKED) | ||
156 | gfs2_pte_inval(gl); | ||
157 | if (gl->gl_state != LM_ST_EXCLUSIVE) | ||
158 | return; | ||
159 | |||
160 | if (ip && !S_ISREG(ip->i_inode.i_mode)) | 139 | if (ip && !S_ISREG(ip->i_inode.i_mode)) |
161 | ip = NULL; | 140 | ip = NULL; |
141 | if (ip && test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) | ||
142 | unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0); | ||
143 | if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) | ||
144 | return; | ||
162 | 145 | ||
163 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 146 | BUG_ON(gl->gl_state != LM_ST_EXCLUSIVE); |
164 | gfs2_log_flush(gl->gl_sbd, gl); | 147 | |
165 | filemap_fdatawrite(metamapping); | 148 | gfs2_log_flush(gl->gl_sbd, gl); |
166 | if (ip) { | 149 | filemap_fdatawrite(metamapping); |
167 | struct address_space *mapping = ip->i_inode.i_mapping; | 150 | if (ip) { |
168 | filemap_fdatawrite(mapping); | 151 | struct address_space *mapping = ip->i_inode.i_mapping; |
169 | error = filemap_fdatawait(mapping); | 152 | filemap_fdatawrite(mapping); |
170 | mapping_set_error(mapping, error); | 153 | error = filemap_fdatawait(mapping); |
171 | } | 154 | mapping_set_error(mapping, error); |
172 | error = filemap_fdatawait(metamapping); | ||
173 | mapping_set_error(metamapping, error); | ||
174 | clear_bit(GLF_DIRTY, &gl->gl_flags); | ||
175 | gfs2_ail_empty_gl(gl); | ||
176 | } | 155 | } |
156 | error = filemap_fdatawait(metamapping); | ||
157 | mapping_set_error(metamapping, error); | ||
158 | gfs2_ail_empty_gl(gl); | ||
177 | } | 159 | } |
178 | 160 | ||
179 | /** | 161 | /** |
180 | * inode_go_inval - prepare a inode glock to be released | 162 | * inode_go_inval - prepare a inode glock to be released |
181 | * @gl: the glock | 163 | * @gl: the glock |
182 | * @flags: | 164 | * @flags: |
165 | * | ||
166 | * Normally we invlidate everything, but if we are moving into | ||
167 | * LM_ST_DEFERRED from LM_ST_SHARED or LM_ST_EXCLUSIVE then we | ||
168 | * can keep hold of the metadata, since it won't have changed. | ||
183 | * | 169 | * |
184 | */ | 170 | */ |
185 | 171 | ||
186 | static void inode_go_inval(struct gfs2_glock *gl, int flags) | 172 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
187 | { | 173 | { |
188 | struct gfs2_inode *ip = gl->gl_object; | 174 | struct gfs2_inode *ip = gl->gl_object; |
189 | int meta = (flags & DIO_METADATA); | ||
190 | 175 | ||
191 | if (meta) { | 176 | gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count)); |
192 | gfs2_meta_inval(gl); | 177 | |
178 | if (flags & DIO_METADATA) { | ||
179 | struct address_space *mapping = gl->gl_aspace->i_mapping; | ||
180 | truncate_inode_pages(mapping, 0); | ||
193 | if (ip) | 181 | if (ip) |
194 | set_bit(GIF_INVALID, &ip->i_flags); | 182 | set_bit(GIF_INVALID, &ip->i_flags); |
195 | } | 183 | } |
196 | 184 | ||
185 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) | ||
186 | gl->gl_sbd->sd_rindex_uptodate = 0; | ||
197 | if (ip && S_ISREG(ip->i_inode.i_mode)) | 187 | if (ip && S_ISREG(ip->i_inode.i_mode)) |
198 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | 188 | truncate_inode_pages(ip->i_inode.i_mapping, 0); |
199 | } | 189 | } |
@@ -395,7 +385,6 @@ static int trans_go_demote_ok(const struct gfs2_glock *gl) | |||
395 | } | 385 | } |
396 | 386 | ||
397 | const struct gfs2_glock_operations gfs2_meta_glops = { | 387 | const struct gfs2_glock_operations gfs2_meta_glops = { |
398 | .go_xmote_th = meta_go_sync, | ||
399 | .go_type = LM_TYPE_META, | 388 | .go_type = LM_TYPE_META, |
400 | }; | 389 | }; |
401 | 390 | ||
@@ -410,8 +399,8 @@ const struct gfs2_glock_operations gfs2_inode_glops = { | |||
410 | }; | 399 | }; |
411 | 400 | ||
412 | const struct gfs2_glock_operations gfs2_rgrp_glops = { | 401 | const struct gfs2_glock_operations gfs2_rgrp_glops = { |
413 | .go_xmote_th = meta_go_sync, | 402 | .go_xmote_th = rgrp_go_sync, |
414 | .go_inval = meta_go_inval, | 403 | .go_inval = rgrp_go_inval, |
415 | .go_demote_ok = rgrp_go_demote_ok, | 404 | .go_demote_ok = rgrp_go_demote_ok, |
416 | .go_lock = rgrp_go_lock, | 405 | .go_lock = rgrp_go_lock, |
417 | .go_unlock = rgrp_go_unlock, | 406 | .go_unlock = rgrp_go_unlock, |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 870d65ae7ae2..8d6f13256b26 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -89,27 +89,6 @@ void gfs2_aspace_put(struct inode *aspace) | |||
89 | } | 89 | } |
90 | 90 | ||
91 | /** | 91 | /** |
92 | * gfs2_meta_inval - Invalidate all buffers associated with a glock | ||
93 | * @gl: the glock | ||
94 | * | ||
95 | */ | ||
96 | |||
97 | void gfs2_meta_inval(struct gfs2_glock *gl) | ||
98 | { | ||
99 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
100 | struct inode *aspace = gl->gl_aspace; | ||
101 | struct address_space *mapping = gl->gl_aspace->i_mapping; | ||
102 | |||
103 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); | ||
104 | |||
105 | atomic_inc(&aspace->i_writecount); | ||
106 | truncate_inode_pages(mapping, 0); | ||
107 | atomic_dec(&aspace->i_writecount); | ||
108 | |||
109 | gfs2_assert_withdraw(sdp, !mapping->nrpages); | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * gfs2_meta_sync - Sync all buffers associated with a glock | 92 | * gfs2_meta_sync - Sync all buffers associated with a glock |
114 | * @gl: The glock | 93 | * @gl: The glock |
115 | * | 94 | * |
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index b1a5f3674d43..de270c2f9b63 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -40,7 +40,6 @@ static inline void gfs2_buffer_copy_tail(struct buffer_head *to_bh, | |||
40 | struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp); | 40 | struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp); |
41 | void gfs2_aspace_put(struct inode *aspace); | 41 | void gfs2_aspace_put(struct inode *aspace); |
42 | 42 | ||
43 | void gfs2_meta_inval(struct gfs2_glock *gl); | ||
44 | void gfs2_meta_sync(struct gfs2_glock *gl); | 43 | void gfs2_meta_sync(struct gfs2_glock *gl); |
45 | 44 | ||
46 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); | 45 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 99d726f1c7a6..48ec3d5e29eb 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -355,7 +355,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
355 | if (ret) | 355 | if (ret) |
356 | goto out; | 356 | goto out; |
357 | 357 | ||
358 | set_bit(GIF_SW_PAGED, &ip->i_flags); | ||
359 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); | 358 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); |
360 | if (ret || !alloc_required) | 359 | if (ret || !alloc_required) |
361 | goto out_unlock; | 360 | goto out_unlock; |
@@ -396,6 +395,8 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
396 | goto out_unlock_page; | 395 | goto out_unlock_page; |
397 | } | 396 | } |
398 | ret = gfs2_allocate_page_backing(page); | 397 | ret = gfs2_allocate_page_backing(page); |
398 | if (!ret) | ||
399 | set_bit(GIF_SW_PAGED, &ip->i_flags); | ||
399 | 400 | ||
400 | out_unlock_page: | 401 | out_unlock_page: |
401 | unlock_page(page); | 402 | unlock_page(page); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 804ca7273a49..51883b3ad89c 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -296,15 +296,15 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | |||
296 | __free_page(page); | 296 | __free_page(page); |
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | |||
299 | /** | 300 | /** |
300 | * gfs2_read_sb - Read super block | 301 | * gfs2_read_sb - Read super block |
301 | * @sdp: The GFS2 superblock | 302 | * @sdp: The GFS2 superblock |
302 | * @gl: the glock for the superblock (assumed to be held) | ||
303 | * @silent: Don't print message if mount fails | 303 | * @silent: Don't print message if mount fails |
304 | * | 304 | * |
305 | */ | 305 | */ |
306 | 306 | ||
307 | static int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) | 307 | static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent) |
308 | { | 308 | { |
309 | u32 hash_blocks, ind_blocks, leaf_blocks; | 309 | u32 hash_blocks, ind_blocks, leaf_blocks; |
310 | u32 tmp_blocks; | 310 | u32 tmp_blocks; |
@@ -524,7 +524,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent) | |||
524 | return ret; | 524 | return ret; |
525 | } | 525 | } |
526 | 526 | ||
527 | ret = gfs2_read_sb(sdp, sb_gh.gh_gl, silent); | 527 | ret = gfs2_read_sb(sdp, silent); |
528 | if (ret) { | 528 | if (ret) { |
529 | fs_err(sdp, "can't read superblock: %d\n", ret); | 529 | fs_err(sdp, "can't read superblock: %d\n", ret); |
530 | goto out; | 530 | goto out; |