aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-06-04 20:06:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-06-04 20:06:28 -0400
commit6f66f9005b66a9a09028f8c85d67600b20a979ec (patch)
tree8d805ed204c8beba4ca01449a651b871234084c2 /fs
parent8764d86100fe58e69877753faa44fc1d9276c624 (diff)
parenta6a4d98b0124b5d3befe8b3a99f51f1b4fcc6dcf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes
Pull gfs2 fixes from Steven Whitehouse: "There are four patches this time. The first fixes a problem where the wrong descriptor type was being written into the log for journaled data blocks. The second fixes a race relating to the deallocation of allocator data. The third provides a fallback if kmalloc is unable to satisfy a request to allocate a directory hash table. The fourth fixes the iopen glock caching so that inodes are deleted in a more timely manner after rmdir/unlink" * git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes: GFS2: Don't cache iopen glocks GFS2: Fall back to vmalloc if kmalloc fails for dir hash tables GFS2: Increase i_writecount during gfs2_setattr_size GFS2: Set log descriptor type for jdata blocks
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/bmap.c17
-rw-r--r--fs/gfs2/dir.c43
-rw-r--r--fs/gfs2/file.c19
-rw-r--r--fs/gfs2/inode.c1
-rw-r--r--fs/gfs2/lops.c4
-rw-r--r--fs/gfs2/rgrp.c4
-rw-r--r--fs/gfs2/super.c6
7 files changed, 71 insertions, 23 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 1dc9a13ce6bb..93b5809c20bb 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1286,17 +1286,26 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
1286 if (ret) 1286 if (ret)
1287 return ret; 1287 return ret;
1288 1288
1289 ret = get_write_access(inode);
1290 if (ret)
1291 return ret;
1292
1289 inode_dio_wait(inode); 1293 inode_dio_wait(inode);
1290 1294
1291 ret = gfs2_rs_alloc(GFS2_I(inode)); 1295 ret = gfs2_rs_alloc(GFS2_I(inode));
1292 if (ret) 1296 if (ret)
1293 return ret; 1297 goto out;
1294 1298
1295 oldsize = inode->i_size; 1299 oldsize = inode->i_size;
1296 if (newsize >= oldsize) 1300 if (newsize >= oldsize) {
1297 return do_grow(inode, newsize); 1301 ret = do_grow(inode, newsize);
1302 goto out;
1303 }
1298 1304
1299 return do_shrink(inode, oldsize, newsize); 1305 ret = do_shrink(inode, oldsize, newsize);
1306out:
1307 put_write_access(inode);
1308 return ret;
1300} 1309}
1301 1310
1302int gfs2_truncatei_resume(struct gfs2_inode *ip) 1311int gfs2_truncatei_resume(struct gfs2_inode *ip)
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index c3e82bd23179..b631c9043460 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -354,22 +354,31 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip)
354 return ERR_PTR(-EIO); 354 return ERR_PTR(-EIO);
355 } 355 }
356 356
357 hc = kmalloc(hsize, GFP_NOFS); 357 hc = kmalloc(hsize, GFP_NOFS | __GFP_NOWARN);
358 ret = -ENOMEM; 358 if (hc == NULL)
359 hc = __vmalloc(hsize, GFP_NOFS, PAGE_KERNEL);
360
359 if (hc == NULL) 361 if (hc == NULL)
360 return ERR_PTR(-ENOMEM); 362 return ERR_PTR(-ENOMEM);
361 363
362 ret = gfs2_dir_read_data(ip, hc, hsize); 364 ret = gfs2_dir_read_data(ip, hc, hsize);
363 if (ret < 0) { 365 if (ret < 0) {
364 kfree(hc); 366 if (is_vmalloc_addr(hc))
367 vfree(hc);
368 else
369 kfree(hc);
365 return ERR_PTR(ret); 370 return ERR_PTR(ret);
366 } 371 }
367 372
368 spin_lock(&inode->i_lock); 373 spin_lock(&inode->i_lock);
369 if (ip->i_hash_cache) 374 if (ip->i_hash_cache) {
370 kfree(hc); 375 if (is_vmalloc_addr(hc))
371 else 376 vfree(hc);
377 else
378 kfree(hc);
379 } else {
372 ip->i_hash_cache = hc; 380 ip->i_hash_cache = hc;
381 }
373 spin_unlock(&inode->i_lock); 382 spin_unlock(&inode->i_lock);
374 383
375 return ip->i_hash_cache; 384 return ip->i_hash_cache;
@@ -385,7 +394,10 @@ void gfs2_dir_hash_inval(struct gfs2_inode *ip)
385{ 394{
386 __be64 *hc = ip->i_hash_cache; 395 __be64 *hc = ip->i_hash_cache;
387 ip->i_hash_cache = NULL; 396 ip->i_hash_cache = NULL;
388 kfree(hc); 397 if (is_vmalloc_addr(hc))
398 vfree(hc);
399 else
400 kfree(hc);
389} 401}
390 402
391static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) 403static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
@@ -1113,7 +1125,10 @@ static int dir_double_exhash(struct gfs2_inode *dip)
1113 if (IS_ERR(hc)) 1125 if (IS_ERR(hc))
1114 return PTR_ERR(hc); 1126 return PTR_ERR(hc);
1115 1127
1116 h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS); 1128 h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN);
1129 if (hc2 == NULL)
1130 hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL);
1131
1117 if (!hc2) 1132 if (!hc2)
1118 return -ENOMEM; 1133 return -ENOMEM;
1119 1134
@@ -1145,7 +1160,10 @@ fail:
1145 gfs2_dinode_out(dip, dibh->b_data); 1160 gfs2_dinode_out(dip, dibh->b_data);
1146 brelse(dibh); 1161 brelse(dibh);
1147out_kfree: 1162out_kfree:
1148 kfree(hc2); 1163 if (is_vmalloc_addr(hc2))
1164 vfree(hc2);
1165 else
1166 kfree(hc2);
1149 return error; 1167 return error;
1150} 1168}
1151 1169
@@ -1846,6 +1864,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
1846 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); 1864 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
1847 1865
1848 ht = kzalloc(size, GFP_NOFS); 1866 ht = kzalloc(size, GFP_NOFS);
1867 if (ht == NULL)
1868 ht = vzalloc(size);
1849 if (!ht) 1869 if (!ht)
1850 return -ENOMEM; 1870 return -ENOMEM;
1851 1871
@@ -1933,7 +1953,10 @@ out_rlist:
1933 gfs2_rlist_free(&rlist); 1953 gfs2_rlist_free(&rlist);
1934 gfs2_quota_unhold(dip); 1954 gfs2_quota_unhold(dip);
1935out: 1955out:
1936 kfree(ht); 1956 if (is_vmalloc_addr(ht))
1957 vfree(ht);
1958 else
1959 kfree(ht);
1937 return error; 1960 return error;
1938} 1961}
1939 1962
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index acd16764b133..ad0dc38d87ab 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -402,16 +402,20 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
402 /* Update file times before taking page lock */ 402 /* Update file times before taking page lock */
403 file_update_time(vma->vm_file); 403 file_update_time(vma->vm_file);
404 404
405 ret = get_write_access(inode);
406 if (ret)
407 goto out;
408
405 ret = gfs2_rs_alloc(ip); 409 ret = gfs2_rs_alloc(ip);
406 if (ret) 410 if (ret)
407 return ret; 411 goto out_write_access;
408 412
409 gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); 413 gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE);
410 414
411 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 415 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
412 ret = gfs2_glock_nq(&gh); 416 ret = gfs2_glock_nq(&gh);
413 if (ret) 417 if (ret)
414 goto out; 418 goto out_uninit;
415 419
416 set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); 420 set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
417 set_bit(GIF_SW_PAGED, &ip->i_flags); 421 set_bit(GIF_SW_PAGED, &ip->i_flags);
@@ -480,12 +484,15 @@ out_quota_unlock:
480 gfs2_quota_unlock(ip); 484 gfs2_quota_unlock(ip);
481out_unlock: 485out_unlock:
482 gfs2_glock_dq(&gh); 486 gfs2_glock_dq(&gh);
483out: 487out_uninit:
484 gfs2_holder_uninit(&gh); 488 gfs2_holder_uninit(&gh);
485 if (ret == 0) { 489 if (ret == 0) {
486 set_page_dirty(page); 490 set_page_dirty(page);
487 wait_for_stable_page(page); 491 wait_for_stable_page(page);
488 } 492 }
493out_write_access:
494 put_write_access(inode);
495out:
489 sb_end_pagefault(inode->i_sb); 496 sb_end_pagefault(inode->i_sb);
490 return block_page_mkwrite_return(ret); 497 return block_page_mkwrite_return(ret);
491} 498}
@@ -594,10 +601,10 @@ static int gfs2_release(struct inode *inode, struct file *file)
594 kfree(file->private_data); 601 kfree(file->private_data);
595 file->private_data = NULL; 602 file->private_data = NULL;
596 603
597 if ((file->f_mode & FMODE_WRITE) && 604 if (!(file->f_mode & FMODE_WRITE))
598 (atomic_read(&inode->i_writecount) == 1)) 605 return 0;
599 gfs2_rs_delete(ip);
600 606
607 gfs2_rs_delete(ip);
601 return 0; 608 return 0;
602} 609}
603 610
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 8833a4f264e3..62b484e4a9e4 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -189,6 +189,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
189 return inode; 189 return inode;
190 190
191fail_refresh: 191fail_refresh:
192 ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
192 ip->i_iopen_gh.gh_gl->gl_object = NULL; 193 ip->i_iopen_gh.gh_gl->gl_object = NULL;
193 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 194 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
194fail_iopen: 195fail_iopen:
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 68b4c8f1fce8..6c33d7b6e0c4 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -419,7 +419,9 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
419 if (total > limit) 419 if (total > limit)
420 num = limit; 420 num = limit;
421 gfs2_log_unlock(sdp); 421 gfs2_log_unlock(sdp);
422 page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num); 422 page = gfs2_get_log_desc(sdp,
423 is_databuf ? GFS2_LOG_DESC_JDATA :
424 GFS2_LOG_DESC_METADATA, num + 1, num);
423 ld = page_address(page); 425 ld = page_address(page);
424 gfs2_log_lock(sdp); 426 gfs2_log_lock(sdp);
425 ptr = (__be64 *)(ld + 1); 427 ptr = (__be64 *)(ld + 1);
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 5232525934ae..9809156e3d04 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
638 */ 638 */
639void gfs2_rs_delete(struct gfs2_inode *ip) 639void gfs2_rs_delete(struct gfs2_inode *ip)
640{ 640{
641 struct inode *inode = &ip->i_inode;
642
641 down_write(&ip->i_rw_mutex); 643 down_write(&ip->i_rw_mutex);
642 if (ip->i_res) { 644 if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
643 gfs2_rs_deltree(ip->i_res); 645 gfs2_rs_deltree(ip->i_res);
644 BUG_ON(ip->i_res->rs_free); 646 BUG_ON(ip->i_res->rs_free);
645 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); 647 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 917c8e1eb4ae..e5639dec66c4 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1444,6 +1444,7 @@ static void gfs2_evict_inode(struct inode *inode)
1444 /* Must not read inode block until block type has been verified */ 1444 /* Must not read inode block until block type has been verified */
1445 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); 1445 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh);
1446 if (unlikely(error)) { 1446 if (unlikely(error)) {
1447 ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
1447 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 1448 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
1448 goto out; 1449 goto out;
1449 } 1450 }
@@ -1514,8 +1515,10 @@ out_unlock:
1514 if (gfs2_rs_active(ip->i_res)) 1515 if (gfs2_rs_active(ip->i_res))
1515 gfs2_rs_deltree(ip->i_res); 1516 gfs2_rs_deltree(ip->i_res);
1516 1517
1517 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) 1518 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
1519 ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
1518 gfs2_glock_dq(&ip->i_iopen_gh); 1520 gfs2_glock_dq(&ip->i_iopen_gh);
1521 }
1519 gfs2_holder_uninit(&ip->i_iopen_gh); 1522 gfs2_holder_uninit(&ip->i_iopen_gh);
1520 gfs2_glock_dq_uninit(&gh); 1523 gfs2_glock_dq_uninit(&gh);
1521 if (error && error != GLR_TRYFAILED && error != -EROFS) 1524 if (error && error != GLR_TRYFAILED && error != -EROFS)
@@ -1534,6 +1537,7 @@ out:
1534 ip->i_gl = NULL; 1537 ip->i_gl = NULL;
1535 if (ip->i_iopen_gh.gh_gl) { 1538 if (ip->i_iopen_gh.gh_gl) {
1536 ip->i_iopen_gh.gh_gl->gl_object = NULL; 1539 ip->i_iopen_gh.gh_gl->gl_object = NULL;
1540 ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
1537 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 1541 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
1538 } 1542 }
1539} 1543}