diff options
-rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
-rw-r--r-- | fs/gfs2/log.c | 4 | ||||
-rw-r--r-- | fs/gfs2/ops_address.c | 23 | ||||
-rw-r--r-- | fs/gfs2/ops_vm.c | 20 | ||||
-rw-r--r-- | fs/gfs2/recovery.c | 9 |
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 | ||
280 | enum { | 280 | enum { |
281 | GFF_DID_DIRECT_ALLOC = 0, | 281 | GFF_DID_DIRECT_ALLOC = 0, |
282 | GFF_EXLOCK = 1, | ||
282 | }; | 283 | }; |
283 | 284 | ||
284 | struct gfs2_file { | 285 | struct 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 | ||
255 | skip_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; |
263 | out_unlock: | 271 | out_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 | 319 | skip_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) | |||
141 | static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, | 133 | static 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 | 175 | out: | |
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 | ||