aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/log.c4
-rw-r--r--fs/gfs2/ops_address.c23
-rw-r--r--fs/gfs2/ops_vm.c20
-rw-r--r--fs/gfs2/recovery.c9
5 files changed, 32 insertions, 25 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 90e0624d8065..e98c14f30daa 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -279,6 +279,7 @@ static inline struct gfs2_sbd *GFS2_SB(struct inode *inode)
279 279
280enum { 280enum {
281 GFF_DID_DIRECT_ALLOC = 0, 281 GFF_DID_DIRECT_ALLOC = 0,
282 GFF_EXLOCK = 1,
282}; 283};
283 284
284struct gfs2_file { 285struct gfs2_file {
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 60fdc94ccc8a..a591fb8fae20 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -256,8 +256,8 @@ static unsigned int current_tail(struct gfs2_sbd *sdp)
256 if (list_empty(&sdp->sd_ail1_list)) 256 if (list_empty(&sdp->sd_ail1_list))
257 tail = sdp->sd_log_head; 257 tail = sdp->sd_log_head;
258 else { 258 else {
259 ai = list_entry(sdp->sd_ail1_list.prev, 259 ai = list_entry(sdp->sd_ail1_list.prev, struct gfs2_ail,
260 struct gfs2_ail, ai_list); 260 ai_list);
261 tail = ai->ai_first; 261 tail = ai->ai_first;
262 } 262 }
263 263
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index fca69f12e4de..bdd4d6b48721 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -237,14 +237,22 @@ static int gfs2_readpage(struct file *file, struct page *page)
237 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); 237 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
238 struct gfs2_holder gh; 238 struct gfs2_holder gh;
239 int error; 239 int error;
240 int do_unlock = 0;
240 241
241 if (likely(file != &gfs2_internal_file_sentinal)) { 242 if (likely(file != &gfs2_internal_file_sentinal)) {
243 if (file) {
244 struct gfs2_file *gf = file->private_data;
245 if (test_bit(GFF_EXLOCK, &gf->f_flags))
246 goto skip_lock;
247 }
242 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); 248 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh);
249 do_unlock = 1;
243 error = gfs2_glock_nq_m_atime(1, &gh); 250 error = gfs2_glock_nq_m_atime(1, &gh);
244 if (unlikely(error)) 251 if (unlikely(error))
245 goto out_unlock; 252 goto out_unlock;
246 } 253 }
247 254
255skip_lock:
248 if (gfs2_is_stuffed(ip)) { 256 if (gfs2_is_stuffed(ip)) {
249 error = stuffed_readpage(ip, page); 257 error = stuffed_readpage(ip, page);
250 unlock_page(page); 258 unlock_page(page);
@@ -262,7 +270,7 @@ out:
262 return error; 270 return error;
263out_unlock: 271out_unlock:
264 unlock_page(page); 272 unlock_page(page);
265 if (file != &gfs2_internal_file_sentinal) 273 if (do_unlock)
266 gfs2_holder_uninit(&gh); 274 gfs2_holder_uninit(&gh);
267 goto out; 275 goto out;
268} 276}
@@ -291,17 +299,24 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
291 struct gfs2_holder gh; 299 struct gfs2_holder gh;
292 unsigned page_idx; 300 unsigned page_idx;
293 int ret; 301 int ret;
302 int do_unlock = 0;
294 303
295 if (likely(file != &gfs2_internal_file_sentinal)) { 304 if (likely(file != &gfs2_internal_file_sentinal)) {
305 if (file) {
306 struct gfs2_file *gf = file->private_data;
307 if (test_bit(GFF_EXLOCK, &gf->f_flags))
308 goto skip_lock;
309 }
296 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 310 gfs2_holder_init(ip->i_gl, LM_ST_SHARED,
297 LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh); 311 LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh);
312 do_unlock = 1;
298 ret = gfs2_glock_nq_m_atime(1, &gh); 313 ret = gfs2_glock_nq_m_atime(1, &gh);
299 if (ret == GLR_TRYFAILED) 314 if (ret == GLR_TRYFAILED)
300 goto out_noerror; 315 goto out_noerror;
301 if (unlikely(ret)) 316 if (unlikely(ret))
302 goto out_unlock; 317 goto out_unlock;
303 } 318 }
304 319skip_lock:
305 if (gfs2_is_stuffed(ip)) { 320 if (gfs2_is_stuffed(ip)) {
306 struct pagevec lru_pvec; 321 struct pagevec lru_pvec;
307 pagevec_init(&lru_pvec, 0); 322 pagevec_init(&lru_pvec, 0);
@@ -326,7 +341,7 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
326 ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block); 341 ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block);
327 } 342 }
328 343
329 if (likely(file != &gfs2_internal_file_sentinal)) { 344 if (do_unlock) {
330 gfs2_glock_dq_m(1, &gh); 345 gfs2_glock_dq_m(1, &gh);
331 gfs2_holder_uninit(&gh); 346 gfs2_holder_uninit(&gh);
332 } 347 }
@@ -344,7 +359,7 @@ out_unlock:
344 unlock_page(page); 359 unlock_page(page);
345 page_cache_release(page); 360 page_cache_release(page);
346 } 361 }
347 if (likely(file != &gfs2_internal_file_sentinal)) 362 if (do_unlock)
348 gfs2_holder_uninit(&gh); 363 gfs2_holder_uninit(&gh);
349 goto out; 364 goto out;
350} 365}
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index aff66373b7e1..875a769444a1 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -46,13 +46,7 @@ static struct page *gfs2_private_nopage(struct vm_area_struct *area,
46 unsigned long address, int *type) 46 unsigned long address, int *type)
47{ 47{
48 struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host); 48 struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
49 struct gfs2_holder i_gh;
50 struct page *result; 49 struct page *result;
51 int error;
52
53 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
54 if (error)
55 return NULL;
56 50
57 set_bit(GIF_PAGED, &ip->i_flags); 51 set_bit(GIF_PAGED, &ip->i_flags);
58 52
@@ -61,8 +55,6 @@ static struct page *gfs2_private_nopage(struct vm_area_struct *area,
61 if (result && result != NOPAGE_OOM) 55 if (result && result != NOPAGE_OOM)
62 pfault_be_greedy(ip); 56 pfault_be_greedy(ip);
63 57
64 gfs2_glock_dq_uninit(&i_gh);
65
66 return result; 58 return result;
67} 59}
68 60
@@ -141,7 +133,9 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
141static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, 133static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
142 unsigned long address, int *type) 134 unsigned long address, int *type)
143{ 135{
144 struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host); 136 struct file *file = area->vm_file;
137 struct gfs2_file *gf = file->private_data;
138 struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
145 struct gfs2_holder i_gh; 139 struct gfs2_holder i_gh;
146 struct page *result = NULL; 140 struct page *result = NULL;
147 unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + 141 unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
@@ -156,13 +150,14 @@ static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
156 set_bit(GIF_PAGED, &ip->i_flags); 150 set_bit(GIF_PAGED, &ip->i_flags);
157 set_bit(GIF_SW_PAGED, &ip->i_flags); 151 set_bit(GIF_SW_PAGED, &ip->i_flags);
158 152
159 error = gfs2_write_alloc_required(ip, 153 error = gfs2_write_alloc_required(ip, (u64)index << PAGE_CACHE_SHIFT,
160 (uint64_t)index << PAGE_CACHE_SHIFT,
161 PAGE_CACHE_SIZE, &alloc_required); 154 PAGE_CACHE_SIZE, &alloc_required);
162 if (error) 155 if (error)
163 goto out; 156 goto out;
164 157
158 set_bit(GFF_EXLOCK, &gf->f_flags);
165 result = filemap_nopage(area, address, type); 159 result = filemap_nopage(area, address, type);
160 clear_bit(GFF_EXLOCK, &gf->f_flags);
166 if (!result || result == NOPAGE_OOM) 161 if (!result || result == NOPAGE_OOM)
167 goto out; 162 goto out;
168 163
@@ -177,8 +172,7 @@ static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
177 } 172 }
178 173
179 pfault_be_greedy(ip); 174 pfault_be_greedy(ip);
180 175out:
181 out:
182 gfs2_glock_dq_uninit(&i_gh); 176 gfs2_glock_dq_uninit(&i_gh);
183 177
184 return result; 178 return result;
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 7aabc03e4abd..bbd44a4b1a1f 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -153,8 +153,7 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk,
153 153
154 if (lh.lh_header.mh_magic != GFS2_MAGIC || 154 if (lh.lh_header.mh_magic != GFS2_MAGIC ||
155 lh.lh_header.mh_type != GFS2_METATYPE_LH || 155 lh.lh_header.mh_type != GFS2_METATYPE_LH ||
156 lh.lh_blkno != blk || 156 lh.lh_blkno != blk || lh.lh_hash != hash)
157 lh.lh_hash != hash)
158 return 1; 157 return 1;
159 158
160 *head = lh; 159 *head = lh;
@@ -482,11 +481,9 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd)
482 481
483 /* Acquire a shared hold on the transaction lock */ 482 /* Acquire a shared hold on the transaction lock */
484 483
485 error = gfs2_glock_nq_init(sdp->sd_trans_gl, 484 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED,
486 LM_ST_SHARED,
487 LM_FLAG_NOEXP | LM_FLAG_PRIORITY | 485 LM_FLAG_NOEXP | LM_FLAG_PRIORITY |
488 GL_NOCANCEL | GL_NOCACHE, 486 GL_NOCANCEL | GL_NOCACHE, &t_gh);
489 &t_gh);
490 if (error) 487 if (error)
491 goto fail_gunlock_ji; 488 goto fail_gunlock_ji;
492 489