aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-09-21 17:05:23 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-09-21 17:05:23 -0400
commit7276b3b0c77101f8b3f4e45e89a29cf9045e831a (patch)
tree3dd0a981218e490ddf47f925ba20c254e491ce98 /fs/gfs2/glops.c
parent91fa47964165a42401fbc1f41caa63ab78564305 (diff)
[GFS2] Tidy up meta_io code
Fix a bug in the directory reading code, where we might have dereferenced a NULL pointer in case of OOM. Updated the directory code to use the new & improved version of gfs2_meta_ra() which now returns the first block that was being read. Previously it was releasing it requiring following code to grab the block again at each point it was called. Also turned off readahead on directory lookups since we are reading a hash table, and therefore reading the entries in order is very unlikely. Readahead is still used for all other calls to the directory reading function (e.g. when growing the hash table). Removed the DIO_START constant. Everywhere this was used, it was used to unconditionally start i/o aside from a couple of places, so I've removed it and made the couple of exceptions to this rule into separate functions. Also hunted through the other DIO flags and removed them as arguments from functions which were always called with the same combination of arguments. Updated gfs2_meta_indirect_buffer to be a bit more efficient and hopefully also be a bit easier to read. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 9c046dbf472..ef1492e2d44 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -77,32 +77,24 @@ static void gfs2_page_inval(struct gfs2_glock *gl)
77} 77}
78 78
79/** 79/**
80 * gfs2_page_sync - Sync the data pages (not metadata) associated with a glock 80 * gfs2_page_wait - Wait for writeback of data
81 * @gl: the glock 81 * @gl: the glock
82 * @flags: DIO_START | DIO_WAIT
83 * 82 *
84 * Syncs data (not metadata) for a regular file. 83 * Syncs data (not metadata) for a regular file.
85 * No-op for all other types. 84 * No-op for all other types.
86 */ 85 */
87 86
88static void gfs2_page_sync(struct gfs2_glock *gl, int flags) 87static void gfs2_page_wait(struct gfs2_glock *gl)
89{ 88{
90 struct gfs2_inode *ip; 89 struct gfs2_inode *ip = gl->gl_object;
91 struct inode *inode; 90 struct inode *inode = &ip->i_inode;
92 struct address_space *mapping; 91 struct address_space *mapping = inode->i_mapping;
93 int error = 0; 92 int error;
94 93
95 ip = gl->gl_object; 94 if (!S_ISREG(ip->i_di.di_mode))
96 inode = &ip->i_inode;
97 if (!ip || !S_ISREG(ip->i_di.di_mode))
98 return; 95 return;
99 96
100 mapping = inode->i_mapping; 97 error = filemap_fdatawait(mapping);
101
102 if (flags & DIO_START)
103 filemap_fdatawrite(mapping);
104 if (!error && (flags & DIO_WAIT))
105 error = filemap_fdatawait(mapping);
106 98
107 /* Put back any errors cleared by filemap_fdatawait() 99 /* Put back any errors cleared by filemap_fdatawait()
108 so they can be caught by someone who can pass them 100 so they can be caught by someone who can pass them
@@ -115,6 +107,18 @@ static void gfs2_page_sync(struct gfs2_glock *gl, int flags)
115 107
116} 108}
117 109
110static void gfs2_page_writeback(struct gfs2_glock *gl)
111{
112 struct gfs2_inode *ip = gl->gl_object;
113 struct inode *inode = &ip->i_inode;
114 struct address_space *mapping = inode->i_mapping;
115
116 if (!S_ISREG(ip->i_di.di_mode))
117 return;
118
119 filemap_fdatawrite(mapping);
120}
121
118/** 122/**
119 * meta_go_sync - sync out the metadata for this glock 123 * meta_go_sync - sync out the metadata for this glock
120 * @gl: the glock 124 * @gl: the glock
@@ -132,7 +136,7 @@ static void meta_go_sync(struct gfs2_glock *gl, int flags)
132 136
133 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { 137 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) {
134 gfs2_log_flush(gl->gl_sbd, gl); 138 gfs2_log_flush(gl->gl_sbd, gl);
135 gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT); 139 gfs2_meta_sync(gl);
136 if (flags & DIO_RELEASE) 140 if (flags & DIO_RELEASE)
137 gfs2_ail_empty_gl(gl); 141 gfs2_ail_empty_gl(gl);
138 } 142 }
@@ -185,8 +189,7 @@ static void inode_go_xmote_bh(struct gfs2_glock *gl)
185 189
186 if (gl->gl_state != LM_ST_UNLOCKED && 190 if (gl->gl_state != LM_ST_UNLOCKED &&
187 (!gh || !(gh->gh_flags & GL_SKIP))) { 191 (!gh || !(gh->gh_flags & GL_SKIP))) {
188 error = gfs2_meta_read(gl, gl->gl_name.ln_number, DIO_START, 192 error = gfs2_meta_read(gl, gl->gl_name.ln_number, 0, &bh);
189 &bh);
190 if (!error) 193 if (!error)
191 brelse(bh); 194 brelse(bh);
192 } 195 }
@@ -221,16 +224,18 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags)
221 224
222 if (test_bit(GLF_DIRTY, &gl->gl_flags)) { 225 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
223 if (meta && data) { 226 if (meta && data) {
224 gfs2_page_sync(gl, flags | DIO_START); 227 gfs2_page_writeback(gl);
225 gfs2_log_flush(gl->gl_sbd, gl); 228 gfs2_log_flush(gl->gl_sbd, gl);
226 gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT); 229 gfs2_meta_sync(gl);
227 gfs2_page_sync(gl, flags | DIO_WAIT); 230 gfs2_page_wait(gl);
228 clear_bit(GLF_DIRTY, &gl->gl_flags); 231 clear_bit(GLF_DIRTY, &gl->gl_flags);
229 } else if (meta) { 232 } else if (meta) {
230 gfs2_log_flush(gl->gl_sbd, gl); 233 gfs2_log_flush(gl->gl_sbd, gl);
231 gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT); 234 gfs2_meta_sync(gl);
232 } else if (data) 235 } else if (data) {
233 gfs2_page_sync(gl, flags | DIO_START | DIO_WAIT); 236 gfs2_page_writeback(gl);
237 gfs2_page_wait(gl);
238 }
234 if (flags & DIO_RELEASE) 239 if (flags & DIO_RELEASE)
235 gfs2_ail_empty_gl(gl); 240 gfs2_ail_empty_gl(gl);
236 } 241 }