diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/aops.c | 18 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 21 | ||||
-rw-r--r-- | fs/gfs2/dir.c | 9 | ||||
-rw-r--r-- | fs/gfs2/file.c | 65 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 39 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 54 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 94 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 9 | ||||
-rw-r--r-- | fs/gfs2/main.c | 1 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 5 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 36 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 72 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 833 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 45 | ||||
-rw-r--r-- | fs/gfs2/super.c | 28 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 21 | ||||
-rw-r--r-- | fs/gfs2/trace_gfs2.h | 59 | ||||
-rw-r--r-- | fs/gfs2/trans.h | 2 | ||||
-rw-r--r-- | fs/gfs2/util.h | 18 | ||||
-rw-r--r-- | fs/gfs2/xattr.c | 30 |
20 files changed, 1093 insertions, 366 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index e80a464850c8..d6526347d386 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -614,7 +614,6 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
614 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 614 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
615 | int alloc_required; | 615 | int alloc_required; |
616 | int error = 0; | 616 | int error = 0; |
617 | struct gfs2_qadata *qa = NULL; | ||
618 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 617 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
619 | unsigned from = pos & (PAGE_CACHE_SIZE - 1); | 618 | unsigned from = pos & (PAGE_CACHE_SIZE - 1); |
620 | struct page *page; | 619 | struct page *page; |
@@ -638,15 +637,9 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
638 | gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); | 637 | gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); |
639 | 638 | ||
640 | if (alloc_required) { | 639 | if (alloc_required) { |
641 | qa = gfs2_qadata_get(ip); | ||
642 | if (!qa) { | ||
643 | error = -ENOMEM; | ||
644 | goto out_unlock; | ||
645 | } | ||
646 | |||
647 | error = gfs2_quota_lock_check(ip); | 640 | error = gfs2_quota_lock_check(ip); |
648 | if (error) | 641 | if (error) |
649 | goto out_alloc_put; | 642 | goto out_unlock; |
650 | 643 | ||
651 | error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); | 644 | error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); |
652 | if (error) | 645 | if (error) |
@@ -708,8 +701,6 @@ out_trans_fail: | |||
708 | gfs2_inplace_release(ip); | 701 | gfs2_inplace_release(ip); |
709 | out_qunlock: | 702 | out_qunlock: |
710 | gfs2_quota_unlock(ip); | 703 | gfs2_quota_unlock(ip); |
711 | out_alloc_put: | ||
712 | gfs2_qadata_put(ip); | ||
713 | } | 704 | } |
714 | out_unlock: | 705 | out_unlock: |
715 | if (&ip->i_inode == sdp->sd_rindex) { | 706 | if (&ip->i_inode == sdp->sd_rindex) { |
@@ -846,7 +837,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
846 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 837 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
847 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 838 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
848 | struct buffer_head *dibh; | 839 | struct buffer_head *dibh; |
849 | struct gfs2_qadata *qa = ip->i_qadata; | ||
850 | unsigned int from = pos & (PAGE_CACHE_SIZE - 1); | 840 | unsigned int from = pos & (PAGE_CACHE_SIZE - 1); |
851 | unsigned int to = from + len; | 841 | unsigned int to = from + len; |
852 | int ret; | 842 | int ret; |
@@ -878,12 +868,10 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
878 | brelse(dibh); | 868 | brelse(dibh); |
879 | failed: | 869 | failed: |
880 | gfs2_trans_end(sdp); | 870 | gfs2_trans_end(sdp); |
881 | if (ip->i_res) | 871 | if (gfs2_mb_reserved(ip)) |
882 | gfs2_inplace_release(ip); | 872 | gfs2_inplace_release(ip); |
883 | if (qa) { | 873 | if (ip->i_res->rs_qa_qd_num) |
884 | gfs2_quota_unlock(ip); | 874 | gfs2_quota_unlock(ip); |
885 | gfs2_qadata_put(ip); | ||
886 | } | ||
887 | if (inode == sdp->sd_rindex) { | 875 | if (inode == sdp->sd_rindex) { |
888 | gfs2_glock_dq(&m_ip->i_gh); | 876 | gfs2_glock_dq(&m_ip->i_gh); |
889 | gfs2_holder_uninit(&m_ip->i_gh); | 877 | gfs2_holder_uninit(&m_ip->i_gh); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index dab54099dd98..49cd7dd4a9fa 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -785,6 +785,9 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
785 | if (error) | 785 | if (error) |
786 | goto out_rlist; | 786 | goto out_rlist; |
787 | 787 | ||
788 | if (gfs2_rs_active(ip->i_res)) /* needs to be done with the rgrp glock held */ | ||
789 | gfs2_rs_deltree(ip->i_res); | ||
790 | |||
788 | error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + | 791 | error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + |
789 | RES_INDIRECT + RES_STATFS + RES_QUOTA, | 792 | RES_INDIRECT + RES_STATFS + RES_QUOTA, |
790 | revokes); | 793 | revokes); |
@@ -1045,12 +1048,13 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size) | |||
1045 | lblock = (size - 1) >> sdp->sd_sb.sb_bsize_shift; | 1048 | lblock = (size - 1) >> sdp->sd_sb.sb_bsize_shift; |
1046 | 1049 | ||
1047 | find_metapath(sdp, lblock, &mp, ip->i_height); | 1050 | find_metapath(sdp, lblock, &mp, ip->i_height); |
1048 | if (!gfs2_qadata_get(ip)) | 1051 | error = gfs2_rindex_update(sdp); |
1049 | return -ENOMEM; | 1052 | if (error) |
1053 | return error; | ||
1050 | 1054 | ||
1051 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1055 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
1052 | if (error) | 1056 | if (error) |
1053 | goto out; | 1057 | return error; |
1054 | 1058 | ||
1055 | while (height--) { | 1059 | while (height--) { |
1056 | struct strip_mine sm; | 1060 | struct strip_mine sm; |
@@ -1064,8 +1068,6 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size) | |||
1064 | 1068 | ||
1065 | gfs2_quota_unhold(ip); | 1069 | gfs2_quota_unhold(ip); |
1066 | 1070 | ||
1067 | out: | ||
1068 | gfs2_qadata_put(ip); | ||
1069 | return error; | 1071 | return error; |
1070 | } | 1072 | } |
1071 | 1073 | ||
@@ -1167,19 +1169,14 @@ static int do_grow(struct inode *inode, u64 size) | |||
1167 | struct gfs2_inode *ip = GFS2_I(inode); | 1169 | struct gfs2_inode *ip = GFS2_I(inode); |
1168 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1170 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
1169 | struct buffer_head *dibh; | 1171 | struct buffer_head *dibh; |
1170 | struct gfs2_qadata *qa = NULL; | ||
1171 | int error; | 1172 | int error; |
1172 | int unstuff = 0; | 1173 | int unstuff = 0; |
1173 | 1174 | ||
1174 | if (gfs2_is_stuffed(ip) && | 1175 | if (gfs2_is_stuffed(ip) && |
1175 | (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) { | 1176 | (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) { |
1176 | qa = gfs2_qadata_get(ip); | ||
1177 | if (qa == NULL) | ||
1178 | return -ENOMEM; | ||
1179 | |||
1180 | error = gfs2_quota_lock_check(ip); | 1177 | error = gfs2_quota_lock_check(ip); |
1181 | if (error) | 1178 | if (error) |
1182 | goto do_grow_alloc_put; | 1179 | return error; |
1183 | 1180 | ||
1184 | error = gfs2_inplace_reserve(ip, 1); | 1181 | error = gfs2_inplace_reserve(ip, 1); |
1185 | if (error) | 1182 | if (error) |
@@ -1214,8 +1211,6 @@ do_grow_release: | |||
1214 | gfs2_inplace_release(ip); | 1211 | gfs2_inplace_release(ip); |
1215 | do_grow_qunlock: | 1212 | do_grow_qunlock: |
1216 | gfs2_quota_unlock(ip); | 1213 | gfs2_quota_unlock(ip); |
1217 | do_grow_alloc_put: | ||
1218 | gfs2_qadata_put(ip); | ||
1219 | } | 1214 | } |
1220 | return error; | 1215 | return error; |
1221 | } | 1216 | } |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 8aaeb07a07b5..259b088cfc4c 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -1854,14 +1854,9 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1854 | if (!ht) | 1854 | if (!ht) |
1855 | return -ENOMEM; | 1855 | return -ENOMEM; |
1856 | 1856 | ||
1857 | if (!gfs2_qadata_get(dip)) { | ||
1858 | error = -ENOMEM; | ||
1859 | goto out; | ||
1860 | } | ||
1861 | |||
1862 | error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1857 | error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
1863 | if (error) | 1858 | if (error) |
1864 | goto out_put; | 1859 | goto out; |
1865 | 1860 | ||
1866 | /* Count the number of leaves */ | 1861 | /* Count the number of leaves */ |
1867 | bh = leaf_bh; | 1862 | bh = leaf_bh; |
@@ -1942,8 +1937,6 @@ out_rg_gunlock: | |||
1942 | out_rlist: | 1937 | out_rlist: |
1943 | gfs2_rlist_free(&rlist); | 1938 | gfs2_rlist_free(&rlist); |
1944 | gfs2_quota_unhold(dip); | 1939 | gfs2_quota_unhold(dip); |
1945 | out_put: | ||
1946 | gfs2_qadata_put(dip); | ||
1947 | out: | 1940 | out: |
1948 | kfree(ht); | 1941 | kfree(ht); |
1949 | return error; | 1942 | return error; |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 31b199f6efc1..9aa6af13823c 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -142,6 +142,7 @@ static const u32 fsflags_to_gfs2[32] = { | |||
142 | [7] = GFS2_DIF_NOATIME, | 142 | [7] = GFS2_DIF_NOATIME, |
143 | [12] = GFS2_DIF_EXHASH, | 143 | [12] = GFS2_DIF_EXHASH, |
144 | [14] = GFS2_DIF_INHERIT_JDATA, | 144 | [14] = GFS2_DIF_INHERIT_JDATA, |
145 | [17] = GFS2_DIF_TOPDIR, | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | static const u32 gfs2_to_fsflags[32] = { | 148 | static const u32 gfs2_to_fsflags[32] = { |
@@ -150,6 +151,7 @@ static const u32 gfs2_to_fsflags[32] = { | |||
150 | [gfs2fl_AppendOnly] = FS_APPEND_FL, | 151 | [gfs2fl_AppendOnly] = FS_APPEND_FL, |
151 | [gfs2fl_NoAtime] = FS_NOATIME_FL, | 152 | [gfs2fl_NoAtime] = FS_NOATIME_FL, |
152 | [gfs2fl_ExHash] = FS_INDEX_FL, | 153 | [gfs2fl_ExHash] = FS_INDEX_FL, |
154 | [gfs2fl_TopLevel] = FS_TOPDIR_FL, | ||
153 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, | 155 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, |
154 | }; | 156 | }; |
155 | 157 | ||
@@ -203,6 +205,7 @@ void gfs2_set_inode_flags(struct inode *inode) | |||
203 | GFS2_DIF_NOATIME| \ | 205 | GFS2_DIF_NOATIME| \ |
204 | GFS2_DIF_SYNC| \ | 206 | GFS2_DIF_SYNC| \ |
205 | GFS2_DIF_SYSTEM| \ | 207 | GFS2_DIF_SYSTEM| \ |
208 | GFS2_DIF_TOPDIR| \ | ||
206 | GFS2_DIF_INHERIT_JDATA) | 209 | GFS2_DIF_INHERIT_JDATA) |
207 | 210 | ||
208 | /** | 211 | /** |
@@ -298,6 +301,7 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) | |||
298 | 301 | ||
299 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); | 302 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); |
300 | if (!S_ISDIR(inode->i_mode)) { | 303 | if (!S_ISDIR(inode->i_mode)) { |
304 | gfsflags &= ~GFS2_DIF_TOPDIR; | ||
301 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) | 305 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) |
302 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); | 306 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); |
303 | return do_gfs2_set_flags(filp, gfsflags, ~0); | 307 | return do_gfs2_set_flags(filp, gfsflags, ~0); |
@@ -366,7 +370,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
366 | u64 pos = page->index << PAGE_CACHE_SHIFT; | 370 | u64 pos = page->index << PAGE_CACHE_SHIFT; |
367 | unsigned int data_blocks, ind_blocks, rblocks; | 371 | unsigned int data_blocks, ind_blocks, rblocks; |
368 | struct gfs2_holder gh; | 372 | struct gfs2_holder gh; |
369 | struct gfs2_qadata *qa; | ||
370 | loff_t size; | 373 | loff_t size; |
371 | int ret; | 374 | int ret; |
372 | 375 | ||
@@ -376,6 +379,13 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
376 | */ | 379 | */ |
377 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); | 380 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); |
378 | 381 | ||
382 | ret = gfs2_rs_alloc(ip); | ||
383 | if (ret) | ||
384 | return ret; | ||
385 | |||
386 | atomic_set(&ip->i_res->rs_sizehint, | ||
387 | PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift); | ||
388 | |||
379 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 389 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
380 | ret = gfs2_glock_nq(&gh); | 390 | ret = gfs2_glock_nq(&gh); |
381 | if (ret) | 391 | if (ret) |
@@ -393,14 +403,13 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
393 | goto out_unlock; | 403 | goto out_unlock; |
394 | } | 404 | } |
395 | 405 | ||
396 | ret = -ENOMEM; | 406 | ret = gfs2_rindex_update(sdp); |
397 | qa = gfs2_qadata_get(ip); | 407 | if (ret) |
398 | if (qa == NULL) | ||
399 | goto out_unlock; | 408 | goto out_unlock; |
400 | 409 | ||
401 | ret = gfs2_quota_lock_check(ip); | 410 | ret = gfs2_quota_lock_check(ip); |
402 | if (ret) | 411 | if (ret) |
403 | goto out_alloc_put; | 412 | goto out_unlock; |
404 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); | 413 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); |
405 | ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); | 414 | ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); |
406 | if (ret) | 415 | if (ret) |
@@ -447,8 +456,6 @@ out_trans_fail: | |||
447 | gfs2_inplace_release(ip); | 456 | gfs2_inplace_release(ip); |
448 | out_quota_unlock: | 457 | out_quota_unlock: |
449 | gfs2_quota_unlock(ip); | 458 | gfs2_quota_unlock(ip); |
450 | out_alloc_put: | ||
451 | gfs2_qadata_put(ip); | ||
452 | out_unlock: | 459 | out_unlock: |
453 | gfs2_glock_dq(&gh); | 460 | gfs2_glock_dq(&gh); |
454 | out: | 461 | out: |
@@ -567,16 +574,14 @@ fail: | |||
567 | 574 | ||
568 | static int gfs2_release(struct inode *inode, struct file *file) | 575 | static int gfs2_release(struct inode *inode, struct file *file) |
569 | { | 576 | { |
570 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | 577 | struct gfs2_inode *ip = GFS2_I(inode); |
571 | struct gfs2_file *fp; | ||
572 | 578 | ||
573 | fp = file->private_data; | 579 | kfree(file->private_data); |
574 | file->private_data = NULL; | 580 | file->private_data = NULL; |
575 | 581 | ||
576 | if (gfs2_assert_warn(sdp, fp)) | 582 | if ((file->f_mode & FMODE_WRITE) && |
577 | return -EIO; | 583 | (atomic_read(&inode->i_writecount) == 1)) |
578 | 584 | gfs2_rs_delete(ip); | |
579 | kfree(fp); | ||
580 | 585 | ||
581 | return 0; | 586 | return 0; |
582 | } | 587 | } |
@@ -653,12 +658,20 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
653 | unsigned long nr_segs, loff_t pos) | 658 | unsigned long nr_segs, loff_t pos) |
654 | { | 659 | { |
655 | struct file *file = iocb->ki_filp; | 660 | struct file *file = iocb->ki_filp; |
661 | size_t writesize = iov_length(iov, nr_segs); | ||
662 | struct dentry *dentry = file->f_dentry; | ||
663 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
664 | struct gfs2_sbd *sdp; | ||
665 | int ret; | ||
656 | 666 | ||
667 | sdp = GFS2_SB(file->f_mapping->host); | ||
668 | ret = gfs2_rs_alloc(ip); | ||
669 | if (ret) | ||
670 | return ret; | ||
671 | |||
672 | atomic_set(&ip->i_res->rs_sizehint, writesize >> sdp->sd_sb.sb_bsize_shift); | ||
657 | if (file->f_flags & O_APPEND) { | 673 | if (file->f_flags & O_APPEND) { |
658 | struct dentry *dentry = file->f_dentry; | ||
659 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
660 | struct gfs2_holder gh; | 674 | struct gfs2_holder gh; |
661 | int ret; | ||
662 | 675 | ||
663 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | 676 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
664 | if (ret) | 677 | if (ret) |
@@ -751,7 +764,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
751 | struct gfs2_inode *ip = GFS2_I(inode); | 764 | struct gfs2_inode *ip = GFS2_I(inode); |
752 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 765 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
753 | loff_t bytes, max_bytes; | 766 | loff_t bytes, max_bytes; |
754 | struct gfs2_qadata *qa; | ||
755 | int error; | 767 | int error; |
756 | const loff_t pos = offset; | 768 | const loff_t pos = offset; |
757 | const loff_t count = len; | 769 | const loff_t count = len; |
@@ -774,11 +786,17 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
774 | if (bytes == 0) | 786 | if (bytes == 0) |
775 | bytes = sdp->sd_sb.sb_bsize; | 787 | bytes = sdp->sd_sb.sb_bsize; |
776 | 788 | ||
789 | error = gfs2_rs_alloc(ip); | ||
790 | if (error) | ||
791 | return error; | ||
792 | |||
777 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); | 793 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); |
778 | error = gfs2_glock_nq(&ip->i_gh); | 794 | error = gfs2_glock_nq(&ip->i_gh); |
779 | if (unlikely(error)) | 795 | if (unlikely(error)) |
780 | goto out_uninit; | 796 | goto out_uninit; |
781 | 797 | ||
798 | atomic_set(&ip->i_res->rs_sizehint, len >> sdp->sd_sb.sb_bsize_shift); | ||
799 | |||
782 | while (len > 0) { | 800 | while (len > 0) { |
783 | if (len < bytes) | 801 | if (len < bytes) |
784 | bytes = len; | 802 | bytes = len; |
@@ -787,15 +805,9 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
787 | offset += bytes; | 805 | offset += bytes; |
788 | continue; | 806 | continue; |
789 | } | 807 | } |
790 | qa = gfs2_qadata_get(ip); | ||
791 | if (!qa) { | ||
792 | error = -ENOMEM; | ||
793 | goto out_unlock; | ||
794 | } | ||
795 | |||
796 | error = gfs2_quota_lock_check(ip); | 808 | error = gfs2_quota_lock_check(ip); |
797 | if (error) | 809 | if (error) |
798 | goto out_alloc_put; | 810 | goto out_unlock; |
799 | 811 | ||
800 | retry: | 812 | retry: |
801 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); | 813 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); |
@@ -835,7 +847,6 @@ retry: | |||
835 | offset += max_bytes; | 847 | offset += max_bytes; |
836 | gfs2_inplace_release(ip); | 848 | gfs2_inplace_release(ip); |
837 | gfs2_quota_unlock(ip); | 849 | gfs2_quota_unlock(ip); |
838 | gfs2_qadata_put(ip); | ||
839 | } | 850 | } |
840 | 851 | ||
841 | if (error == 0) | 852 | if (error == 0) |
@@ -846,8 +857,6 @@ out_trans_fail: | |||
846 | gfs2_inplace_release(ip); | 857 | gfs2_inplace_release(ip); |
847 | out_qunlock: | 858 | out_qunlock: |
848 | gfs2_quota_unlock(ip); | 859 | gfs2_quota_unlock(ip); |
849 | out_alloc_put: | ||
850 | gfs2_qadata_put(ip); | ||
851 | out_unlock: | 860 | out_unlock: |
852 | gfs2_glock_dq(&ip->i_gh); | 861 | gfs2_glock_dq(&ip->i_gh); |
853 | out_uninit: | 862 | out_uninit: |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index dab2526071cc..1ed81f40da0d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -46,10 +46,11 @@ | |||
46 | #include "trace_gfs2.h" | 46 | #include "trace_gfs2.h" |
47 | 47 | ||
48 | struct gfs2_glock_iter { | 48 | struct gfs2_glock_iter { |
49 | int hash; /* hash bucket index */ | 49 | int hash; /* hash bucket index */ |
50 | struct gfs2_sbd *sdp; /* incore superblock */ | 50 | unsigned nhash; /* Index within current bucket */ |
51 | struct gfs2_glock *gl; /* current glock struct */ | 51 | struct gfs2_sbd *sdp; /* incore superblock */ |
52 | char string[512]; /* scratch space */ | 52 | struct gfs2_glock *gl; /* current glock struct */ |
53 | loff_t last_pos; /* last position */ | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | typedef void (*glock_examiner) (struct gfs2_glock * gl); | 56 | typedef void (*glock_examiner) (struct gfs2_glock * gl); |
@@ -767,6 +768,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
767 | gl->gl_stats.stats[GFS2_LKS_DCOUNT] = 0; | 768 | gl->gl_stats.stats[GFS2_LKS_DCOUNT] = 0; |
768 | gl->gl_stats.stats[GFS2_LKS_QCOUNT] = 0; | 769 | gl->gl_stats.stats[GFS2_LKS_QCOUNT] = 0; |
769 | memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb)); | 770 | memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb)); |
771 | memset(gl->gl_lvb, 0, 32 * sizeof(char)); | ||
770 | gl->gl_lksb.sb_lvbptr = gl->gl_lvb; | 772 | gl->gl_lksb.sb_lvbptr = gl->gl_lvb; |
771 | gl->gl_tchange = jiffies; | 773 | gl->gl_tchange = jiffies; |
772 | gl->gl_object = NULL; | 774 | gl->gl_object = NULL; |
@@ -948,9 +950,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) | |||
948 | va_start(args, fmt); | 950 | va_start(args, fmt); |
949 | 951 | ||
950 | if (seq) { | 952 | if (seq) { |
951 | struct gfs2_glock_iter *gi = seq->private; | 953 | seq_vprintf(seq, fmt, args); |
952 | vsprintf(gi->string, fmt, args); | ||
953 | seq_printf(seq, gi->string); | ||
954 | } else { | 954 | } else { |
955 | vaf.fmt = fmt; | 955 | vaf.fmt = fmt; |
956 | vaf.va = &args; | 956 | vaf.va = &args; |
@@ -1854,8 +1854,14 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | |||
1854 | gl = gi->gl; | 1854 | gl = gi->gl; |
1855 | if (gl) { | 1855 | if (gl) { |
1856 | gi->gl = glock_hash_next(gl); | 1856 | gi->gl = glock_hash_next(gl); |
1857 | gi->nhash++; | ||
1857 | } else { | 1858 | } else { |
1859 | if (gi->hash >= GFS2_GL_HASH_SIZE) { | ||
1860 | rcu_read_unlock(); | ||
1861 | return 1; | ||
1862 | } | ||
1858 | gi->gl = glock_hash_chain(gi->hash); | 1863 | gi->gl = glock_hash_chain(gi->hash); |
1864 | gi->nhash = 0; | ||
1859 | } | 1865 | } |
1860 | while (gi->gl == NULL) { | 1866 | while (gi->gl == NULL) { |
1861 | gi->hash++; | 1867 | gi->hash++; |
@@ -1864,6 +1870,7 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | |||
1864 | return 1; | 1870 | return 1; |
1865 | } | 1871 | } |
1866 | gi->gl = glock_hash_chain(gi->hash); | 1872 | gi->gl = glock_hash_chain(gi->hash); |
1873 | gi->nhash = 0; | ||
1867 | } | 1874 | } |
1868 | /* Skip entries for other sb and dead entries */ | 1875 | /* Skip entries for other sb and dead entries */ |
1869 | } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0); | 1876 | } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0); |
@@ -1876,7 +1883,12 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) | |||
1876 | struct gfs2_glock_iter *gi = seq->private; | 1883 | struct gfs2_glock_iter *gi = seq->private; |
1877 | loff_t n = *pos; | 1884 | loff_t n = *pos; |
1878 | 1885 | ||
1879 | gi->hash = 0; | 1886 | if (gi->last_pos <= *pos) |
1887 | n = gi->nhash + (*pos - gi->last_pos); | ||
1888 | else | ||
1889 | gi->hash = 0; | ||
1890 | |||
1891 | gi->nhash = 0; | ||
1880 | rcu_read_lock(); | 1892 | rcu_read_lock(); |
1881 | 1893 | ||
1882 | do { | 1894 | do { |
@@ -1884,6 +1896,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) | |||
1884 | return NULL; | 1896 | return NULL; |
1885 | } while (n--); | 1897 | } while (n--); |
1886 | 1898 | ||
1899 | gi->last_pos = *pos; | ||
1887 | return gi->gl; | 1900 | return gi->gl; |
1888 | } | 1901 | } |
1889 | 1902 | ||
@@ -1893,7 +1906,7 @@ static void *gfs2_glock_seq_next(struct seq_file *seq, void *iter_ptr, | |||
1893 | struct gfs2_glock_iter *gi = seq->private; | 1906 | struct gfs2_glock_iter *gi = seq->private; |
1894 | 1907 | ||
1895 | (*pos)++; | 1908 | (*pos)++; |
1896 | 1909 | gi->last_pos = *pos; | |
1897 | if (gfs2_glock_iter_next(gi)) | 1910 | if (gfs2_glock_iter_next(gi)) |
1898 | return NULL; | 1911 | return NULL; |
1899 | 1912 | ||
@@ -1964,6 +1977,8 @@ static const struct seq_operations gfs2_sbstats_seq_ops = { | |||
1964 | .show = gfs2_sbstats_seq_show, | 1977 | .show = gfs2_sbstats_seq_show, |
1965 | }; | 1978 | }; |
1966 | 1979 | ||
1980 | #define GFS2_SEQ_GOODSIZE min(PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER, 65536UL) | ||
1981 | |||
1967 | static int gfs2_glocks_open(struct inode *inode, struct file *file) | 1982 | static int gfs2_glocks_open(struct inode *inode, struct file *file) |
1968 | { | 1983 | { |
1969 | int ret = seq_open_private(file, &gfs2_glock_seq_ops, | 1984 | int ret = seq_open_private(file, &gfs2_glock_seq_ops, |
@@ -1972,6 +1987,9 @@ static int gfs2_glocks_open(struct inode *inode, struct file *file) | |||
1972 | struct seq_file *seq = file->private_data; | 1987 | struct seq_file *seq = file->private_data; |
1973 | struct gfs2_glock_iter *gi = seq->private; | 1988 | struct gfs2_glock_iter *gi = seq->private; |
1974 | gi->sdp = inode->i_private; | 1989 | gi->sdp = inode->i_private; |
1990 | seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); | ||
1991 | if (seq->buf) | ||
1992 | seq->size = GFS2_SEQ_GOODSIZE; | ||
1975 | } | 1993 | } |
1976 | return ret; | 1994 | return ret; |
1977 | } | 1995 | } |
@@ -1984,6 +2002,9 @@ static int gfs2_glstats_open(struct inode *inode, struct file *file) | |||
1984 | struct seq_file *seq = file->private_data; | 2002 | struct seq_file *seq = file->private_data; |
1985 | struct gfs2_glock_iter *gi = seq->private; | 2003 | struct gfs2_glock_iter *gi = seq->private; |
1986 | gi->sdp = inode->i_private; | 2004 | gi->sdp = inode->i_private; |
2005 | seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); | ||
2006 | if (seq->buf) | ||
2007 | seq->size = GFS2_SEQ_GOODSIZE; | ||
1987 | } | 2008 | } |
1988 | return ret; | 2009 | return ret; |
1989 | } | 2010 | } |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 67fd6beffece..aaecc8085fc5 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -84,17 +84,22 @@ struct gfs2_rgrpd { | |||
84 | u32 rd_data; /* num of data blocks in rgrp */ | 84 | u32 rd_data; /* num of data blocks in rgrp */ |
85 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ | 85 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ |
86 | u32 rd_free; | 86 | u32 rd_free; |
87 | u32 rd_reserved; /* number of blocks reserved */ | ||
87 | u32 rd_free_clone; | 88 | u32 rd_free_clone; |
88 | u32 rd_dinodes; | 89 | u32 rd_dinodes; |
89 | u64 rd_igeneration; | 90 | u64 rd_igeneration; |
90 | struct gfs2_bitmap *rd_bits; | 91 | struct gfs2_bitmap *rd_bits; |
91 | struct gfs2_sbd *rd_sbd; | 92 | struct gfs2_sbd *rd_sbd; |
93 | struct gfs2_rgrp_lvb *rd_rgl; | ||
92 | u32 rd_last_alloc; | 94 | u32 rd_last_alloc; |
93 | u32 rd_flags; | 95 | u32 rd_flags; |
94 | #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ | 96 | #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ |
95 | #define GFS2_RDF_UPTODATE 0x20000000 /* rg is up to date */ | 97 | #define GFS2_RDF_UPTODATE 0x20000000 /* rg is up to date */ |
96 | #define GFS2_RDF_ERROR 0x40000000 /* error in rg */ | 98 | #define GFS2_RDF_ERROR 0x40000000 /* error in rg */ |
97 | #define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */ | 99 | #define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */ |
100 | spinlock_t rd_rsspin; /* protects reservation related vars */ | ||
101 | struct rb_root rd_rstree; /* multi-block reservation tree */ | ||
102 | u32 rd_rs_cnt; /* count of current reservations */ | ||
98 | }; | 103 | }; |
99 | 104 | ||
100 | enum gfs2_state_bits { | 105 | enum gfs2_state_bits { |
@@ -232,6 +237,38 @@ struct gfs2_holder { | |||
232 | unsigned long gh_ip; | 237 | unsigned long gh_ip; |
233 | }; | 238 | }; |
234 | 239 | ||
240 | /* Resource group multi-block reservation, in order of appearance: | ||
241 | |||
242 | Step 1. Function prepares to write, allocates a mb, sets the size hint. | ||
243 | Step 2. User calls inplace_reserve to target an rgrp, sets the rgrp info | ||
244 | Step 3. Function get_local_rgrp locks the rgrp, determines which bits to use | ||
245 | Step 4. Bits are assigned from the rgrp based on either the reservation | ||
246 | or wherever it can. | ||
247 | */ | ||
248 | |||
249 | struct gfs2_blkreserv { | ||
250 | /* components used during write (step 1): */ | ||
251 | atomic_t rs_sizehint; /* hint of the write size */ | ||
252 | |||
253 | /* components used during inplace_reserve (step 2): */ | ||
254 | u32 rs_requested; /* Filled in by caller of gfs2_inplace_reserve() */ | ||
255 | |||
256 | /* components used during get_local_rgrp (step 3): */ | ||
257 | struct gfs2_rgrpd *rs_rgd; /* pointer to the gfs2_rgrpd */ | ||
258 | struct gfs2_holder rs_rgd_gh; /* Filled in by get_local_rgrp */ | ||
259 | struct rb_node rs_node; /* link to other block reservations */ | ||
260 | |||
261 | /* components used during block searches and assignments (step 4): */ | ||
262 | struct gfs2_bitmap *rs_bi; /* bitmap for the current allocation */ | ||
263 | u32 rs_biblk; /* start block relative to the bi */ | ||
264 | u32 rs_free; /* how many blocks are still free */ | ||
265 | |||
266 | /* ancillary quota stuff */ | ||
267 | struct gfs2_quota_data *rs_qa_qd[2 * MAXQUOTAS]; | ||
268 | struct gfs2_holder rs_qa_qd_ghs[2 * MAXQUOTAS]; | ||
269 | unsigned int rs_qa_qd_num; | ||
270 | }; | ||
271 | |||
235 | enum { | 272 | enum { |
236 | GLF_LOCK = 1, | 273 | GLF_LOCK = 1, |
237 | GLF_DEMOTE = 3, | 274 | GLF_DEMOTE = 3, |
@@ -289,18 +326,6 @@ struct gfs2_glock { | |||
289 | 326 | ||
290 | #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */ | 327 | #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */ |
291 | 328 | ||
292 | struct gfs2_qadata { /* quota allocation data */ | ||
293 | /* Quota stuff */ | ||
294 | struct gfs2_quota_data *qa_qd[2*MAXQUOTAS]; | ||
295 | struct gfs2_holder qa_qd_ghs[2*MAXQUOTAS]; | ||
296 | unsigned int qa_qd_num; | ||
297 | }; | ||
298 | |||
299 | struct gfs2_blkreserv { | ||
300 | u32 rs_requested; /* Filled in by caller of gfs2_inplace_reserve() */ | ||
301 | struct gfs2_holder rs_rgd_gh; /* Filled in by gfs2_inplace_reserve() */ | ||
302 | }; | ||
303 | |||
304 | enum { | 329 | enum { |
305 | GIF_INVALID = 0, | 330 | GIF_INVALID = 0, |
306 | GIF_QD_LOCKED = 1, | 331 | GIF_QD_LOCKED = 1, |
@@ -308,7 +333,6 @@ enum { | |||
308 | GIF_SW_PAGED = 3, | 333 | GIF_SW_PAGED = 3, |
309 | }; | 334 | }; |
310 | 335 | ||
311 | |||
312 | struct gfs2_inode { | 336 | struct gfs2_inode { |
313 | struct inode i_inode; | 337 | struct inode i_inode; |
314 | u64 i_no_addr; | 338 | u64 i_no_addr; |
@@ -319,8 +343,7 @@ struct gfs2_inode { | |||
319 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 343 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
320 | struct gfs2_holder i_iopen_gh; | 344 | struct gfs2_holder i_iopen_gh; |
321 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ | 345 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ |
322 | struct gfs2_qadata *i_qadata; /* quota allocation data */ | 346 | struct gfs2_blkreserv *i_res; /* rgrp multi-block reservation */ |
323 | struct gfs2_blkreserv *i_res; /* resource group block reservation */ | ||
324 | struct gfs2_rgrpd *i_rgd; | 347 | struct gfs2_rgrpd *i_rgd; |
325 | u64 i_goal; /* goal block for allocations */ | 348 | u64 i_goal; /* goal block for allocations */ |
326 | struct rw_semaphore i_rw_mutex; | 349 | struct rw_semaphore i_rw_mutex; |
@@ -473,6 +496,7 @@ struct gfs2_args { | |||
473 | unsigned int ar_discard:1; /* discard requests */ | 496 | unsigned int ar_discard:1; /* discard requests */ |
474 | unsigned int ar_errors:2; /* errors=withdraw | panic */ | 497 | unsigned int ar_errors:2; /* errors=withdraw | panic */ |
475 | unsigned int ar_nobarrier:1; /* do not send barriers */ | 498 | unsigned int ar_nobarrier:1; /* do not send barriers */ |
499 | unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */ | ||
476 | int ar_commit; /* Commit interval */ | 500 | int ar_commit; /* Commit interval */ |
477 | int ar_statfs_quantum; /* The fast statfs interval */ | 501 | int ar_statfs_quantum; /* The fast statfs interval */ |
478 | int ar_quota_quantum; /* The quota interval */ | 502 | int ar_quota_quantum; /* The quota interval */ |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 867674785fcf..4ce22e547308 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -521,12 +521,13 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
521 | int error; | 521 | int error; |
522 | 522 | ||
523 | munge_mode_uid_gid(dip, &mode, &uid, &gid); | 523 | munge_mode_uid_gid(dip, &mode, &uid, &gid); |
524 | if (!gfs2_qadata_get(dip)) | 524 | error = gfs2_rindex_update(sdp); |
525 | return -ENOMEM; | 525 | if (error) |
526 | return error; | ||
526 | 527 | ||
527 | error = gfs2_quota_lock(dip, uid, gid); | 528 | error = gfs2_quota_lock(dip, uid, gid); |
528 | if (error) | 529 | if (error) |
529 | goto out; | 530 | return error; |
530 | 531 | ||
531 | error = gfs2_quota_check(dip, uid, gid); | 532 | error = gfs2_quota_check(dip, uid, gid); |
532 | if (error) | 533 | if (error) |
@@ -542,8 +543,6 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
542 | 543 | ||
543 | out_quota: | 544 | out_quota: |
544 | gfs2_quota_unlock(dip); | 545 | gfs2_quota_unlock(dip); |
545 | out: | ||
546 | gfs2_qadata_put(dip); | ||
547 | return error; | 546 | return error; |
548 | } | 547 | } |
549 | 548 | ||
@@ -551,14 +550,13 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
551 | struct gfs2_inode *ip) | 550 | struct gfs2_inode *ip) |
552 | { | 551 | { |
553 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 552 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
554 | struct gfs2_qadata *qa; | ||
555 | int alloc_required; | 553 | int alloc_required; |
556 | struct buffer_head *dibh; | 554 | struct buffer_head *dibh; |
557 | int error; | 555 | int error; |
558 | 556 | ||
559 | qa = gfs2_qadata_get(dip); | 557 | error = gfs2_rindex_update(sdp); |
560 | if (!qa) | 558 | if (error) |
561 | return -ENOMEM; | 559 | return error; |
562 | 560 | ||
563 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 561 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
564 | if (error) | 562 | if (error) |
@@ -605,13 +603,13 @@ fail_end_trans: | |||
605 | gfs2_trans_end(sdp); | 603 | gfs2_trans_end(sdp); |
606 | 604 | ||
607 | fail_ipreserv: | 605 | fail_ipreserv: |
608 | gfs2_inplace_release(dip); | 606 | if (alloc_required) |
607 | gfs2_inplace_release(dip); | ||
609 | 608 | ||
610 | fail_quota_locks: | 609 | fail_quota_locks: |
611 | gfs2_quota_unlock(dip); | 610 | gfs2_quota_unlock(dip); |
612 | 611 | ||
613 | fail: | 612 | fail: |
614 | gfs2_qadata_put(dip); | ||
615 | return error; | 613 | return error; |
616 | } | 614 | } |
617 | 615 | ||
@@ -657,7 +655,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
657 | const struct qstr *name = &dentry->d_name; | 655 | const struct qstr *name = &dentry->d_name; |
658 | struct gfs2_holder ghs[2]; | 656 | struct gfs2_holder ghs[2]; |
659 | struct inode *inode = NULL; | 657 | struct inode *inode = NULL; |
660 | struct gfs2_inode *dip = GFS2_I(dir); | 658 | struct gfs2_inode *dip = GFS2_I(dir), *ip; |
661 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 659 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
662 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 660 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
663 | int error; | 661 | int error; |
@@ -667,6 +665,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
667 | if (!name->len || name->len > GFS2_FNAMESIZE) | 665 | if (!name->len || name->len > GFS2_FNAMESIZE) |
668 | return -ENAMETOOLONG; | 666 | return -ENAMETOOLONG; |
669 | 667 | ||
668 | /* We need a reservation to allocate the new dinode block. The | ||
669 | directory ip temporarily points to the reservation, but this is | ||
670 | being done to get a set of contiguous blocks for the new dinode. | ||
671 | Since this is a create, we don't have a sizehint yet, so it will | ||
672 | have to use the minimum reservation size. */ | ||
673 | error = gfs2_rs_alloc(dip); | ||
674 | if (error) | ||
675 | return error; | ||
676 | |||
670 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 677 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
671 | if (error) | 678 | if (error) |
672 | goto fail; | 679 | goto fail; |
@@ -700,19 +707,29 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
700 | if (IS_ERR(inode)) | 707 | if (IS_ERR(inode)) |
701 | goto fail_gunlock2; | 708 | goto fail_gunlock2; |
702 | 709 | ||
703 | error = gfs2_inode_refresh(GFS2_I(inode)); | 710 | ip = GFS2_I(inode); |
711 | error = gfs2_inode_refresh(ip); | ||
704 | if (error) | 712 | if (error) |
705 | goto fail_gunlock2; | 713 | goto fail_gunlock2; |
706 | 714 | ||
715 | /* The newly created inode needs a reservation so it can allocate | ||
716 | xattrs. At the same time, we want new blocks allocated to the new | ||
717 | dinode to be as contiguous as possible. Since we allocated the | ||
718 | dinode block under the directory's reservation, we transfer | ||
719 | ownership of that reservation to the new inode. The directory | ||
720 | doesn't need a reservation unless it needs a new allocation. */ | ||
721 | ip->i_res = dip->i_res; | ||
722 | dip->i_res = NULL; | ||
723 | |||
707 | error = gfs2_acl_create(dip, inode); | 724 | error = gfs2_acl_create(dip, inode); |
708 | if (error) | 725 | if (error) |
709 | goto fail_gunlock2; | 726 | goto fail_gunlock2; |
710 | 727 | ||
711 | error = gfs2_security_init(dip, GFS2_I(inode), name); | 728 | error = gfs2_security_init(dip, ip, name); |
712 | if (error) | 729 | if (error) |
713 | goto fail_gunlock2; | 730 | goto fail_gunlock2; |
714 | 731 | ||
715 | error = link_dinode(dip, name, GFS2_I(inode)); | 732 | error = link_dinode(dip, name, ip); |
716 | if (error) | 733 | if (error) |
717 | goto fail_gunlock2; | 734 | goto fail_gunlock2; |
718 | 735 | ||
@@ -722,10 +739,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
722 | gfs2_trans_end(sdp); | 739 | gfs2_trans_end(sdp); |
723 | /* Check if we reserved space in the rgrp. Function link_dinode may | 740 | /* Check if we reserved space in the rgrp. Function link_dinode may |
724 | not, depending on whether alloc is required. */ | 741 | not, depending on whether alloc is required. */ |
725 | if (dip->i_res) | 742 | if (gfs2_mb_reserved(dip)) |
726 | gfs2_inplace_release(dip); | 743 | gfs2_inplace_release(dip); |
727 | gfs2_quota_unlock(dip); | 744 | gfs2_quota_unlock(dip); |
728 | gfs2_qadata_put(dip); | ||
729 | mark_inode_dirty(inode); | 745 | mark_inode_dirty(inode); |
730 | gfs2_glock_dq_uninit_m(2, ghs); | 746 | gfs2_glock_dq_uninit_m(2, ghs); |
731 | d_instantiate(dentry, inode); | 747 | d_instantiate(dentry, inode); |
@@ -740,6 +756,7 @@ fail_gunlock: | |||
740 | iput(inode); | 756 | iput(inode); |
741 | } | 757 | } |
742 | fail: | 758 | fail: |
759 | gfs2_rs_delete(dip); | ||
743 | if (bh) | 760 | if (bh) |
744 | brelse(bh); | 761 | brelse(bh); |
745 | return error; | 762 | return error; |
@@ -816,6 +833,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
816 | if (S_ISDIR(inode->i_mode)) | 833 | if (S_ISDIR(inode->i_mode)) |
817 | return -EPERM; | 834 | return -EPERM; |
818 | 835 | ||
836 | error = gfs2_rs_alloc(dip); | ||
837 | if (error) | ||
838 | return error; | ||
839 | |||
819 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 840 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
820 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 841 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
821 | 842 | ||
@@ -867,16 +888,9 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
867 | error = 0; | 888 | error = 0; |
868 | 889 | ||
869 | if (alloc_required) { | 890 | if (alloc_required) { |
870 | struct gfs2_qadata *qa = gfs2_qadata_get(dip); | ||
871 | |||
872 | if (!qa) { | ||
873 | error = -ENOMEM; | ||
874 | goto out_gunlock; | ||
875 | } | ||
876 | |||
877 | error = gfs2_quota_lock_check(dip); | 891 | error = gfs2_quota_lock_check(dip); |
878 | if (error) | 892 | if (error) |
879 | goto out_alloc; | 893 | goto out_gunlock; |
880 | 894 | ||
881 | error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres); | 895 | error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres); |
882 | if (error) | 896 | if (error) |
@@ -919,9 +933,6 @@ out_ipres: | |||
919 | out_gunlock_q: | 933 | out_gunlock_q: |
920 | if (alloc_required) | 934 | if (alloc_required) |
921 | gfs2_quota_unlock(dip); | 935 | gfs2_quota_unlock(dip); |
922 | out_alloc: | ||
923 | if (alloc_required) | ||
924 | gfs2_qadata_put(dip); | ||
925 | out_gunlock: | 936 | out_gunlock: |
926 | gfs2_glock_dq(ghs + 1); | 937 | gfs2_glock_dq(ghs + 1); |
927 | out_child: | 938 | out_child: |
@@ -1231,6 +1242,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1231 | if (error) | 1242 | if (error) |
1232 | return error; | 1243 | return error; |
1233 | 1244 | ||
1245 | error = gfs2_rs_alloc(ndip); | ||
1246 | if (error) | ||
1247 | return error; | ||
1248 | |||
1234 | if (odip != ndip) { | 1249 | if (odip != ndip) { |
1235 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, | 1250 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, |
1236 | 0, &r_gh); | 1251 | 0, &r_gh); |
@@ -1354,16 +1369,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1354 | goto out_gunlock; | 1369 | goto out_gunlock; |
1355 | 1370 | ||
1356 | if (alloc_required) { | 1371 | if (alloc_required) { |
1357 | struct gfs2_qadata *qa = gfs2_qadata_get(ndip); | ||
1358 | |||
1359 | if (!qa) { | ||
1360 | error = -ENOMEM; | ||
1361 | goto out_gunlock; | ||
1362 | } | ||
1363 | |||
1364 | error = gfs2_quota_lock_check(ndip); | 1372 | error = gfs2_quota_lock_check(ndip); |
1365 | if (error) | 1373 | if (error) |
1366 | goto out_alloc; | 1374 | goto out_gunlock; |
1367 | 1375 | ||
1368 | error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres); | 1376 | error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres); |
1369 | if (error) | 1377 | if (error) |
@@ -1424,9 +1432,6 @@ out_ipreserv: | |||
1424 | out_gunlock_q: | 1432 | out_gunlock_q: |
1425 | if (alloc_required) | 1433 | if (alloc_required) |
1426 | gfs2_quota_unlock(ndip); | 1434 | gfs2_quota_unlock(ndip); |
1427 | out_alloc: | ||
1428 | if (alloc_required) | ||
1429 | gfs2_qadata_put(ndip); | ||
1430 | out_gunlock: | 1435 | out_gunlock: |
1431 | while (x--) { | 1436 | while (x--) { |
1432 | gfs2_glock_dq(ghs + x); | 1437 | gfs2_glock_dq(ghs + x); |
@@ -1587,12 +1592,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1587 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) | 1592 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) |
1588 | ogid = ngid = NO_QUOTA_CHANGE; | 1593 | ogid = ngid = NO_QUOTA_CHANGE; |
1589 | 1594 | ||
1590 | if (!gfs2_qadata_get(ip)) | ||
1591 | return -ENOMEM; | ||
1592 | |||
1593 | error = gfs2_quota_lock(ip, nuid, ngid); | 1595 | error = gfs2_quota_lock(ip, nuid, ngid); |
1594 | if (error) | 1596 | if (error) |
1595 | goto out_alloc; | 1597 | return error; |
1596 | 1598 | ||
1597 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1599 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
1598 | error = gfs2_quota_check(ip, nuid, ngid); | 1600 | error = gfs2_quota_check(ip, nuid, ngid); |
@@ -1618,8 +1620,6 @@ out_end_trans: | |||
1618 | gfs2_trans_end(sdp); | 1620 | gfs2_trans_end(sdp); |
1619 | out_gunlock_q: | 1621 | out_gunlock_q: |
1620 | gfs2_quota_unlock(ip); | 1622 | gfs2_quota_unlock(ip); |
1621 | out_alloc: | ||
1622 | gfs2_qadata_put(ip); | ||
1623 | return error; | 1623 | return error; |
1624 | } | 1624 | } |
1625 | 1625 | ||
@@ -1641,6 +1641,10 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1641 | struct gfs2_holder i_gh; | 1641 | struct gfs2_holder i_gh; |
1642 | int error; | 1642 | int error; |
1643 | 1643 | ||
1644 | error = gfs2_rs_alloc(ip); | ||
1645 | if (error) | ||
1646 | return error; | ||
1647 | |||
1644 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | 1648 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); |
1645 | if (error) | 1649 | if (error) |
1646 | return error; | 1650 | return error; |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 852c1be1dd3b..8ff95a2d54ee 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -401,9 +401,14 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) | |||
401 | goto out; | 401 | goto out; |
402 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); | 402 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
403 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); | 403 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); |
404 | gfs2_meta_check(sdp, bd->bd_bh); | ||
405 | gfs2_pin(sdp, bd->bd_bh); | ||
406 | mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; | 404 | mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; |
405 | if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) { | ||
406 | printk(KERN_ERR | ||
407 | "Attempting to add uninitialised block to journal (inplace block=%lld)\n", | ||
408 | (unsigned long long)bd->bd_bh->b_blocknr); | ||
409 | BUG(); | ||
410 | } | ||
411 | gfs2_pin(sdp, bd->bd_bh); | ||
407 | mh->__pad0 = cpu_to_be64(0); | 412 | mh->__pad0 = cpu_to_be64(0); |
408 | mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); | 413 | mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); |
409 | sdp->sd_log_num_buf++; | 414 | sdp->sd_log_num_buf++; |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 6cdb0f2a1b09..e04d0e09ee7b 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -43,7 +43,6 @@ static void gfs2_init_inode_once(void *foo) | |||
43 | inode_init_once(&ip->i_inode); | 43 | inode_init_once(&ip->i_inode); |
44 | init_rwsem(&ip->i_rw_mutex); | 44 | init_rwsem(&ip->i_rw_mutex); |
45 | INIT_LIST_HEAD(&ip->i_trunc_list); | 45 | INIT_LIST_HEAD(&ip->i_trunc_list); |
46 | ip->i_qadata = NULL; | ||
47 | ip->i_res = NULL; | 46 | ip->i_res = NULL; |
48 | ip->i_hash_cache = NULL; | 47 | ip->i_hash_cache = NULL; |
49 | } | 48 | } |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 6c1e5d1c404a..3a56c8d94de0 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -213,8 +213,10 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | |||
213 | struct gfs2_sbd *sdp = gl->gl_sbd; | 213 | struct gfs2_sbd *sdp = gl->gl_sbd; |
214 | struct buffer_head *bh; | 214 | struct buffer_head *bh; |
215 | 215 | ||
216 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 216 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { |
217 | *bhp = NULL; | ||
217 | return -EIO; | 218 | return -EIO; |
219 | } | ||
218 | 220 | ||
219 | *bhp = bh = gfs2_getbuf(gl, blkno, CREATE); | 221 | *bhp = bh = gfs2_getbuf(gl, blkno, CREATE); |
220 | 222 | ||
@@ -235,6 +237,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | |||
235 | if (tr && tr->tr_touched) | 237 | if (tr && tr->tr_touched) |
236 | gfs2_io_error_bh(sdp, bh); | 238 | gfs2_io_error_bh(sdp, bh); |
237 | brelse(bh); | 239 | brelse(bh); |
240 | *bhp = NULL; | ||
238 | return -EIO; | 241 | return -EIO; |
239 | } | 242 | } |
240 | 243 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 6c906078f657..e5af9dc420ef 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -1118,20 +1118,33 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent | |||
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | error = init_names(sdp, silent); | 1120 | error = init_names(sdp, silent); |
1121 | if (error) | 1121 | if (error) { |
1122 | goto fail; | 1122 | /* In this case, we haven't initialized sysfs, so we have to |
1123 | manually free the sdp. */ | ||
1124 | free_percpu(sdp->sd_lkstats); | ||
1125 | kfree(sdp); | ||
1126 | sb->s_fs_info = NULL; | ||
1127 | return error; | ||
1128 | } | ||
1123 | 1129 | ||
1124 | snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s", sdp->sd_table_name); | 1130 | snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s", sdp->sd_table_name); |
1125 | 1131 | ||
1126 | gfs2_create_debugfs_file(sdp); | ||
1127 | |||
1128 | error = gfs2_sys_fs_add(sdp); | 1132 | error = gfs2_sys_fs_add(sdp); |
1133 | /* | ||
1134 | * If we hit an error here, gfs2_sys_fs_add will have called function | ||
1135 | * kobject_put which causes the sysfs usage count to go to zero, which | ||
1136 | * causes sysfs to call function gfs2_sbd_release, which frees sdp. | ||
1137 | * Subsequent error paths here will call gfs2_sys_fs_del, which also | ||
1138 | * kobject_put to free sdp. | ||
1139 | */ | ||
1129 | if (error) | 1140 | if (error) |
1130 | goto fail; | 1141 | return error; |
1142 | |||
1143 | gfs2_create_debugfs_file(sdp); | ||
1131 | 1144 | ||
1132 | error = gfs2_lm_mount(sdp, silent); | 1145 | error = gfs2_lm_mount(sdp, silent); |
1133 | if (error) | 1146 | if (error) |
1134 | goto fail_sys; | 1147 | goto fail_debug; |
1135 | 1148 | ||
1136 | error = init_locking(sdp, &mount_gh, DO); | 1149 | error = init_locking(sdp, &mount_gh, DO); |
1137 | if (error) | 1150 | if (error) |
@@ -1215,12 +1228,12 @@ fail_locking: | |||
1215 | fail_lm: | 1228 | fail_lm: |
1216 | gfs2_gl_hash_clear(sdp); | 1229 | gfs2_gl_hash_clear(sdp); |
1217 | gfs2_lm_unmount(sdp); | 1230 | gfs2_lm_unmount(sdp); |
1218 | fail_sys: | 1231 | fail_debug: |
1219 | gfs2_sys_fs_del(sdp); | ||
1220 | fail: | ||
1221 | gfs2_delete_debugfs_file(sdp); | 1232 | gfs2_delete_debugfs_file(sdp); |
1222 | free_percpu(sdp->sd_lkstats); | 1233 | free_percpu(sdp->sd_lkstats); |
1223 | kfree(sdp); | 1234 | /* gfs2_sys_fs_del must be the last thing we do, since it causes |
1235 | * sysfs to call function gfs2_sbd_release, which frees sdp. */ | ||
1236 | gfs2_sys_fs_del(sdp); | ||
1224 | sb->s_fs_info = NULL; | 1237 | sb->s_fs_info = NULL; |
1225 | return error; | 1238 | return error; |
1226 | } | 1239 | } |
@@ -1389,10 +1402,9 @@ static void gfs2_kill_sb(struct super_block *sb) | |||
1389 | sdp->sd_root_dir = NULL; | 1402 | sdp->sd_root_dir = NULL; |
1390 | sdp->sd_master_dir = NULL; | 1403 | sdp->sd_master_dir = NULL; |
1391 | shrink_dcache_sb(sb); | 1404 | shrink_dcache_sb(sb); |
1392 | kill_block_super(sb); | ||
1393 | gfs2_delete_debugfs_file(sdp); | 1405 | gfs2_delete_debugfs_file(sdp); |
1394 | free_percpu(sdp->sd_lkstats); | 1406 | free_percpu(sdp->sd_lkstats); |
1395 | kfree(sdp); | 1407 | kill_block_super(sb); |
1396 | } | 1408 | } |
1397 | 1409 | ||
1398 | struct file_system_type gfs2_fs_type = { | 1410 | struct file_system_type gfs2_fs_type = { |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 27b5cc7d6881..a3bde91645c2 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -494,11 +494,15 @@ static void qdsb_put(struct gfs2_quota_data *qd) | |||
494 | int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | 494 | int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) |
495 | { | 495 | { |
496 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 496 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
497 | struct gfs2_qadata *qa = ip->i_qadata; | 497 | struct gfs2_quota_data **qd; |
498 | struct gfs2_quota_data **qd = qa->qa_qd; | ||
499 | int error; | 498 | int error; |
500 | 499 | ||
501 | if (gfs2_assert_warn(sdp, !qa->qa_qd_num) || | 500 | if (ip->i_res == NULL) |
501 | gfs2_rs_alloc(ip); | ||
502 | |||
503 | qd = ip->i_res->rs_qa_qd; | ||
504 | |||
505 | if (gfs2_assert_warn(sdp, !ip->i_res->rs_qa_qd_num) || | ||
502 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) | 506 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) |
503 | return -EIO; | 507 | return -EIO; |
504 | 508 | ||
@@ -508,20 +512,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
508 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); | 512 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); |
509 | if (error) | 513 | if (error) |
510 | goto out; | 514 | goto out; |
511 | qa->qa_qd_num++; | 515 | ip->i_res->rs_qa_qd_num++; |
512 | qd++; | 516 | qd++; |
513 | 517 | ||
514 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); | 518 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); |
515 | if (error) | 519 | if (error) |
516 | goto out; | 520 | goto out; |
517 | qa->qa_qd_num++; | 521 | ip->i_res->rs_qa_qd_num++; |
518 | qd++; | 522 | qd++; |
519 | 523 | ||
520 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { | 524 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { |
521 | error = qdsb_get(sdp, QUOTA_USER, uid, qd); | 525 | error = qdsb_get(sdp, QUOTA_USER, uid, qd); |
522 | if (error) | 526 | if (error) |
523 | goto out; | 527 | goto out; |
524 | qa->qa_qd_num++; | 528 | ip->i_res->rs_qa_qd_num++; |
525 | qd++; | 529 | qd++; |
526 | } | 530 | } |
527 | 531 | ||
@@ -529,7 +533,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
529 | error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); | 533 | error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); |
530 | if (error) | 534 | if (error) |
531 | goto out; | 535 | goto out; |
532 | qa->qa_qd_num++; | 536 | ip->i_res->rs_qa_qd_num++; |
533 | qd++; | 537 | qd++; |
534 | } | 538 | } |
535 | 539 | ||
@@ -542,16 +546,17 @@ out: | |||
542 | void gfs2_quota_unhold(struct gfs2_inode *ip) | 546 | void gfs2_quota_unhold(struct gfs2_inode *ip) |
543 | { | 547 | { |
544 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 548 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
545 | struct gfs2_qadata *qa = ip->i_qadata; | ||
546 | unsigned int x; | 549 | unsigned int x; |
547 | 550 | ||
551 | if (ip->i_res == NULL) | ||
552 | return; | ||
548 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); | 553 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); |
549 | 554 | ||
550 | for (x = 0; x < qa->qa_qd_num; x++) { | 555 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
551 | qdsb_put(qa->qa_qd[x]); | 556 | qdsb_put(ip->i_res->rs_qa_qd[x]); |
552 | qa->qa_qd[x] = NULL; | 557 | ip->i_res->rs_qa_qd[x] = NULL; |
553 | } | 558 | } |
554 | qa->qa_qd_num = 0; | 559 | ip->i_res->rs_qa_qd_num = 0; |
555 | } | 560 | } |
556 | 561 | ||
557 | static int sort_qd(const void *a, const void *b) | 562 | static int sort_qd(const void *a, const void *b) |
@@ -764,6 +769,10 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
764 | unsigned int nalloc = 0, blocks; | 769 | unsigned int nalloc = 0, blocks; |
765 | int error; | 770 | int error; |
766 | 771 | ||
772 | error = gfs2_rs_alloc(ip); | ||
773 | if (error) | ||
774 | return error; | ||
775 | |||
767 | gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), | 776 | gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), |
768 | &data_blocks, &ind_blocks); | 777 | &data_blocks, &ind_blocks); |
769 | 778 | ||
@@ -915,7 +924,6 @@ fail: | |||
915 | int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | 924 | int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) |
916 | { | 925 | { |
917 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 926 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
918 | struct gfs2_qadata *qa = ip->i_qadata; | ||
919 | struct gfs2_quota_data *qd; | 927 | struct gfs2_quota_data *qd; |
920 | unsigned int x; | 928 | unsigned int x; |
921 | int error = 0; | 929 | int error = 0; |
@@ -928,15 +936,15 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
928 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 936 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
929 | return 0; | 937 | return 0; |
930 | 938 | ||
931 | sort(qa->qa_qd, qa->qa_qd_num, sizeof(struct gfs2_quota_data *), | 939 | sort(ip->i_res->rs_qa_qd, ip->i_res->rs_qa_qd_num, |
932 | sort_qd, NULL); | 940 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); |
933 | 941 | ||
934 | for (x = 0; x < qa->qa_qd_num; x++) { | 942 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
935 | int force = NO_FORCE; | 943 | int force = NO_FORCE; |
936 | qd = qa->qa_qd[x]; | 944 | qd = ip->i_res->rs_qa_qd[x]; |
937 | if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) | 945 | if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) |
938 | force = FORCE; | 946 | force = FORCE; |
939 | error = do_glock(qd, force, &qa->qa_qd_ghs[x]); | 947 | error = do_glock(qd, force, &ip->i_res->rs_qa_qd_ghs[x]); |
940 | if (error) | 948 | if (error) |
941 | break; | 949 | break; |
942 | } | 950 | } |
@@ -945,7 +953,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
945 | set_bit(GIF_QD_LOCKED, &ip->i_flags); | 953 | set_bit(GIF_QD_LOCKED, &ip->i_flags); |
946 | else { | 954 | else { |
947 | while (x--) | 955 | while (x--) |
948 | gfs2_glock_dq_uninit(&qa->qa_qd_ghs[x]); | 956 | gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); |
949 | gfs2_quota_unhold(ip); | 957 | gfs2_quota_unhold(ip); |
950 | } | 958 | } |
951 | 959 | ||
@@ -990,7 +998,6 @@ static int need_sync(struct gfs2_quota_data *qd) | |||
990 | 998 | ||
991 | void gfs2_quota_unlock(struct gfs2_inode *ip) | 999 | void gfs2_quota_unlock(struct gfs2_inode *ip) |
992 | { | 1000 | { |
993 | struct gfs2_qadata *qa = ip->i_qadata; | ||
994 | struct gfs2_quota_data *qda[4]; | 1001 | struct gfs2_quota_data *qda[4]; |
995 | unsigned int count = 0; | 1002 | unsigned int count = 0; |
996 | unsigned int x; | 1003 | unsigned int x; |
@@ -998,14 +1005,14 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) | |||
998 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) | 1005 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) |
999 | goto out; | 1006 | goto out; |
1000 | 1007 | ||
1001 | for (x = 0; x < qa->qa_qd_num; x++) { | 1008 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
1002 | struct gfs2_quota_data *qd; | 1009 | struct gfs2_quota_data *qd; |
1003 | int sync; | 1010 | int sync; |
1004 | 1011 | ||
1005 | qd = qa->qa_qd[x]; | 1012 | qd = ip->i_res->rs_qa_qd[x]; |
1006 | sync = need_sync(qd); | 1013 | sync = need_sync(qd); |
1007 | 1014 | ||
1008 | gfs2_glock_dq_uninit(&qa->qa_qd_ghs[x]); | 1015 | gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); |
1009 | 1016 | ||
1010 | if (sync && qd_trylock(qd)) | 1017 | if (sync && qd_trylock(qd)) |
1011 | qda[count++] = qd; | 1018 | qda[count++] = qd; |
@@ -1038,7 +1045,6 @@ static int print_message(struct gfs2_quota_data *qd, char *type) | |||
1038 | int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | 1045 | int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) |
1039 | { | 1046 | { |
1040 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1047 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1041 | struct gfs2_qadata *qa = ip->i_qadata; | ||
1042 | struct gfs2_quota_data *qd; | 1048 | struct gfs2_quota_data *qd; |
1043 | s64 value; | 1049 | s64 value; |
1044 | unsigned int x; | 1050 | unsigned int x; |
@@ -1050,8 +1056,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1050 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 1056 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
1051 | return 0; | 1057 | return 0; |
1052 | 1058 | ||
1053 | for (x = 0; x < qa->qa_qd_num; x++) { | 1059 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
1054 | qd = qa->qa_qd[x]; | 1060 | qd = ip->i_res->rs_qa_qd[x]; |
1055 | 1061 | ||
1056 | if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || | 1062 | if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || |
1057 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) | 1063 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) |
@@ -1089,7 +1095,6 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1089 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 1095 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
1090 | u32 uid, u32 gid) | 1096 | u32 uid, u32 gid) |
1091 | { | 1097 | { |
1092 | struct gfs2_qadata *qa = ip->i_qadata; | ||
1093 | struct gfs2_quota_data *qd; | 1098 | struct gfs2_quota_data *qd; |
1094 | unsigned int x; | 1099 | unsigned int x; |
1095 | 1100 | ||
@@ -1098,8 +1103,8 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1098 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) | 1103 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) |
1099 | return; | 1104 | return; |
1100 | 1105 | ||
1101 | for (x = 0; x < qa->qa_qd_num; x++) { | 1106 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
1102 | qd = qa->qa_qd[x]; | 1107 | qd = ip->i_res->rs_qa_qd[x]; |
1103 | 1108 | ||
1104 | if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || | 1109 | if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || |
1105 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { | 1110 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { |
@@ -1549,10 +1554,14 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1549 | if (error) | 1554 | if (error) |
1550 | return error; | 1555 | return error; |
1551 | 1556 | ||
1557 | error = gfs2_rs_alloc(ip); | ||
1558 | if (error) | ||
1559 | goto out_put; | ||
1560 | |||
1552 | mutex_lock(&ip->i_inode.i_mutex); | 1561 | mutex_lock(&ip->i_inode.i_mutex); |
1553 | error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh); | 1562 | error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh); |
1554 | if (error) | 1563 | if (error) |
1555 | goto out_put; | 1564 | goto out_unlockput; |
1556 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | 1565 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); |
1557 | if (error) | 1566 | if (error) |
1558 | goto out_q; | 1567 | goto out_q; |
@@ -1609,8 +1618,9 @@ out_i: | |||
1609 | gfs2_glock_dq_uninit(&i_gh); | 1618 | gfs2_glock_dq_uninit(&i_gh); |
1610 | out_q: | 1619 | out_q: |
1611 | gfs2_glock_dq_uninit(&q_gh); | 1620 | gfs2_glock_dq_uninit(&q_gh); |
1612 | out_put: | 1621 | out_unlockput: |
1613 | mutex_unlock(&ip->i_inode.i_mutex); | 1622 | mutex_unlock(&ip->i_inode.i_mutex); |
1623 | out_put: | ||
1614 | qd_put(qd); | 1624 | qd_put(qd); |
1615 | return error; | 1625 | return error; |
1616 | } | 1626 | } |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index f74fb9bd1973..4d34887a601d 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -35,6 +35,9 @@ | |||
35 | #define BFITNOENT ((u32)~0) | 35 | #define BFITNOENT ((u32)~0) |
36 | #define NO_BLOCK ((u64)~0) | 36 | #define NO_BLOCK ((u64)~0) |
37 | 37 | ||
38 | #define RSRV_CONTENTION_FACTOR 4 | ||
39 | #define RGRP_RSRV_MAX_CONTENDERS 2 | ||
40 | |||
38 | #if BITS_PER_LONG == 32 | 41 | #if BITS_PER_LONG == 32 |
39 | #define LBITMASK (0x55555555UL) | 42 | #define LBITMASK (0x55555555UL) |
40 | #define LBITSKIP55 (0x55555555UL) | 43 | #define LBITSKIP55 (0x55555555UL) |
@@ -178,6 +181,57 @@ static inline u64 gfs2_bit_search(const __le64 *ptr, u64 mask, u8 state) | |||
178 | } | 181 | } |
179 | 182 | ||
180 | /** | 183 | /** |
184 | * rs_cmp - multi-block reservation range compare | ||
185 | * @blk: absolute file system block number of the new reservation | ||
186 | * @len: number of blocks in the new reservation | ||
187 | * @rs: existing reservation to compare against | ||
188 | * | ||
189 | * returns: 1 if the block range is beyond the reach of the reservation | ||
190 | * -1 if the block range is before the start of the reservation | ||
191 | * 0 if the block range overlaps with the reservation | ||
192 | */ | ||
193 | static inline int rs_cmp(u64 blk, u32 len, struct gfs2_blkreserv *rs) | ||
194 | { | ||
195 | u64 startblk = gfs2_rs_startblk(rs); | ||
196 | |||
197 | if (blk >= startblk + rs->rs_free) | ||
198 | return 1; | ||
199 | if (blk + len - 1 < startblk) | ||
200 | return -1; | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * rs_find - Find a rgrp multi-block reservation that contains a given block | ||
206 | * @rgd: The rgrp | ||
207 | * @rgblk: The block we're looking for, relative to the rgrp | ||
208 | */ | ||
209 | static struct gfs2_blkreserv *rs_find(struct gfs2_rgrpd *rgd, u32 rgblk) | ||
210 | { | ||
211 | struct rb_node **newn; | ||
212 | int rc; | ||
213 | u64 fsblk = rgblk + rgd->rd_data0; | ||
214 | |||
215 | spin_lock(&rgd->rd_rsspin); | ||
216 | newn = &rgd->rd_rstree.rb_node; | ||
217 | while (*newn) { | ||
218 | struct gfs2_blkreserv *cur = | ||
219 | rb_entry(*newn, struct gfs2_blkreserv, rs_node); | ||
220 | rc = rs_cmp(fsblk, 1, cur); | ||
221 | if (rc < 0) | ||
222 | newn = &((*newn)->rb_left); | ||
223 | else if (rc > 0) | ||
224 | newn = &((*newn)->rb_right); | ||
225 | else { | ||
226 | spin_unlock(&rgd->rd_rsspin); | ||
227 | return cur; | ||
228 | } | ||
229 | } | ||
230 | spin_unlock(&rgd->rd_rsspin); | ||
231 | return NULL; | ||
232 | } | ||
233 | |||
234 | /** | ||
181 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing | 235 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing |
182 | * a block in a given allocation state. | 236 | * a block in a given allocation state. |
183 | * @buf: the buffer that holds the bitmaps | 237 | * @buf: the buffer that holds the bitmaps |
@@ -417,6 +471,137 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) | |||
417 | } | 471 | } |
418 | } | 472 | } |
419 | 473 | ||
474 | /** | ||
475 | * gfs2_rs_alloc - make sure we have a reservation assigned to the inode | ||
476 | * @ip: the inode for this reservation | ||
477 | */ | ||
478 | int gfs2_rs_alloc(struct gfs2_inode *ip) | ||
479 | { | ||
480 | int error = 0; | ||
481 | struct gfs2_blkreserv *res; | ||
482 | |||
483 | if (ip->i_res) | ||
484 | return 0; | ||
485 | |||
486 | res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); | ||
487 | if (!res) | ||
488 | error = -ENOMEM; | ||
489 | |||
490 | down_write(&ip->i_rw_mutex); | ||
491 | if (ip->i_res) | ||
492 | kmem_cache_free(gfs2_rsrv_cachep, res); | ||
493 | else | ||
494 | ip->i_res = res; | ||
495 | up_write(&ip->i_rw_mutex); | ||
496 | return error; | ||
497 | } | ||
498 | |||
499 | static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs) | ||
500 | { | ||
501 | gfs2_print_dbg(seq, " r: %llu s:%llu b:%u f:%u\n", | ||
502 | rs->rs_rgd->rd_addr, gfs2_rs_startblk(rs), rs->rs_biblk, | ||
503 | rs->rs_free); | ||
504 | } | ||
505 | |||
506 | /** | ||
507 | * __rs_deltree - remove a multi-block reservation from the rgd tree | ||
508 | * @rs: The reservation to remove | ||
509 | * | ||
510 | */ | ||
511 | static void __rs_deltree(struct gfs2_blkreserv *rs) | ||
512 | { | ||
513 | struct gfs2_rgrpd *rgd; | ||
514 | |||
515 | if (!gfs2_rs_active(rs)) | ||
516 | return; | ||
517 | |||
518 | rgd = rs->rs_rgd; | ||
519 | /* We can't do this: The reason is that when the rgrp is invalidated, | ||
520 | it's in the "middle" of acquiring the glock, but the HOLDER bit | ||
521 | isn't set yet: | ||
522 | BUG_ON(!gfs2_glock_is_locked_by_me(rs->rs_rgd->rd_gl));*/ | ||
523 | trace_gfs2_rs(NULL, rs, TRACE_RS_TREEDEL); | ||
524 | |||
525 | if (!RB_EMPTY_ROOT(&rgd->rd_rstree)) | ||
526 | rb_erase(&rs->rs_node, &rgd->rd_rstree); | ||
527 | BUG_ON(!rgd->rd_rs_cnt); | ||
528 | rgd->rd_rs_cnt--; | ||
529 | |||
530 | if (rs->rs_free) { | ||
531 | /* return reserved blocks to the rgrp and the ip */ | ||
532 | BUG_ON(rs->rs_rgd->rd_reserved < rs->rs_free); | ||
533 | rs->rs_rgd->rd_reserved -= rs->rs_free; | ||
534 | rs->rs_free = 0; | ||
535 | clear_bit(GBF_FULL, &rs->rs_bi->bi_flags); | ||
536 | smp_mb__after_clear_bit(); | ||
537 | } | ||
538 | /* We can't change any of the step 1 or step 2 components of the rs. | ||
539 | E.g. We can't set rs_rgd to NULL because the rgd glock is held and | ||
540 | dequeued through this pointer. | ||
541 | Can't: atomic_set(&rs->rs_sizehint, 0); | ||
542 | Can't: rs->rs_requested = 0; | ||
543 | Can't: rs->rs_rgd = NULL;*/ | ||
544 | rs->rs_bi = NULL; | ||
545 | rs->rs_biblk = 0; | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * gfs2_rs_deltree - remove a multi-block reservation from the rgd tree | ||
550 | * @rs: The reservation to remove | ||
551 | * | ||
552 | */ | ||
553 | void gfs2_rs_deltree(struct gfs2_blkreserv *rs) | ||
554 | { | ||
555 | struct gfs2_rgrpd *rgd; | ||
556 | |||
557 | if (!gfs2_rs_active(rs)) | ||
558 | return; | ||
559 | |||
560 | rgd = rs->rs_rgd; | ||
561 | spin_lock(&rgd->rd_rsspin); | ||
562 | __rs_deltree(rs); | ||
563 | spin_unlock(&rgd->rd_rsspin); | ||
564 | } | ||
565 | |||
566 | /** | ||
567 | * gfs2_rs_delete - delete a multi-block reservation | ||
568 | * @ip: The inode for this reservation | ||
569 | * | ||
570 | */ | ||
571 | void gfs2_rs_delete(struct gfs2_inode *ip) | ||
572 | { | ||
573 | down_write(&ip->i_rw_mutex); | ||
574 | if (ip->i_res) { | ||
575 | gfs2_rs_deltree(ip->i_res); | ||
576 | trace_gfs2_rs(ip, ip->i_res, TRACE_RS_DELETE); | ||
577 | BUG_ON(ip->i_res->rs_free); | ||
578 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | ||
579 | ip->i_res = NULL; | ||
580 | } | ||
581 | up_write(&ip->i_rw_mutex); | ||
582 | } | ||
583 | |||
584 | /** | ||
585 | * return_all_reservations - return all reserved blocks back to the rgrp. | ||
586 | * @rgd: the rgrp that needs its space back | ||
587 | * | ||
588 | * We previously reserved a bunch of blocks for allocation. Now we need to | ||
589 | * give them back. This leave the reservation structures in tact, but removes | ||
590 | * all of their corresponding "no-fly zones". | ||
591 | */ | ||
592 | static void return_all_reservations(struct gfs2_rgrpd *rgd) | ||
593 | { | ||
594 | struct rb_node *n; | ||
595 | struct gfs2_blkreserv *rs; | ||
596 | |||
597 | spin_lock(&rgd->rd_rsspin); | ||
598 | while ((n = rb_first(&rgd->rd_rstree))) { | ||
599 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
600 | __rs_deltree(rs); | ||
601 | } | ||
602 | spin_unlock(&rgd->rd_rsspin); | ||
603 | } | ||
604 | |||
420 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | 605 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) |
421 | { | 606 | { |
422 | struct rb_node *n; | 607 | struct rb_node *n; |
@@ -439,6 +624,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | |||
439 | 624 | ||
440 | gfs2_free_clones(rgd); | 625 | gfs2_free_clones(rgd); |
441 | kfree(rgd->rd_bits); | 626 | kfree(rgd->rd_bits); |
627 | return_all_reservations(rgd); | ||
442 | kmem_cache_free(gfs2_rgrpd_cachep, rgd); | 628 | kmem_cache_free(gfs2_rgrpd_cachep, rgd); |
443 | } | 629 | } |
444 | } | 630 | } |
@@ -616,6 +802,7 @@ static int read_rindex_entry(struct gfs2_inode *ip) | |||
616 | rgd->rd_data0 = be64_to_cpu(buf.ri_data0); | 802 | rgd->rd_data0 = be64_to_cpu(buf.ri_data0); |
617 | rgd->rd_data = be32_to_cpu(buf.ri_data); | 803 | rgd->rd_data = be32_to_cpu(buf.ri_data); |
618 | rgd->rd_bitbytes = be32_to_cpu(buf.ri_bitbytes); | 804 | rgd->rd_bitbytes = be32_to_cpu(buf.ri_bitbytes); |
805 | spin_lock_init(&rgd->rd_rsspin); | ||
619 | 806 | ||
620 | error = compute_bitstructs(rgd); | 807 | error = compute_bitstructs(rgd); |
621 | if (error) | 808 | if (error) |
@@ -627,6 +814,7 @@ static int read_rindex_entry(struct gfs2_inode *ip) | |||
627 | goto fail; | 814 | goto fail; |
628 | 815 | ||
629 | rgd->rd_gl->gl_object = rgd; | 816 | rgd->rd_gl->gl_object = rgd; |
817 | rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lvb; | ||
630 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; | 818 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
631 | if (rgd->rd_data > sdp->sd_max_rg_data) | 819 | if (rgd->rd_data > sdp->sd_max_rg_data) |
632 | sdp->sd_max_rg_data = rgd->rd_data; | 820 | sdp->sd_max_rg_data = rgd->rd_data; |
@@ -736,9 +924,65 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | |||
736 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | 924 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); |
737 | } | 925 | } |
738 | 926 | ||
927 | static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd) | ||
928 | { | ||
929 | struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; | ||
930 | struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bits[0].bi_bh->b_data; | ||
931 | |||
932 | if (rgl->rl_flags != str->rg_flags || rgl->rl_free != str->rg_free || | ||
933 | rgl->rl_dinodes != str->rg_dinodes || | ||
934 | rgl->rl_igeneration != str->rg_igeneration) | ||
935 | return 0; | ||
936 | return 1; | ||
937 | } | ||
938 | |||
939 | static void gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb *rgl, const void *buf) | ||
940 | { | ||
941 | const struct gfs2_rgrp *str = buf; | ||
942 | |||
943 | rgl->rl_magic = cpu_to_be32(GFS2_MAGIC); | ||
944 | rgl->rl_flags = str->rg_flags; | ||
945 | rgl->rl_free = str->rg_free; | ||
946 | rgl->rl_dinodes = str->rg_dinodes; | ||
947 | rgl->rl_igeneration = str->rg_igeneration; | ||
948 | rgl->__pad = 0UL; | ||
949 | } | ||
950 | |||
951 | static void update_rgrp_lvb_unlinked(struct gfs2_rgrpd *rgd, u32 change) | ||
952 | { | ||
953 | struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; | ||
954 | u32 unlinked = be32_to_cpu(rgl->rl_unlinked) + change; | ||
955 | rgl->rl_unlinked = cpu_to_be32(unlinked); | ||
956 | } | ||
957 | |||
958 | static u32 count_unlinked(struct gfs2_rgrpd *rgd) | ||
959 | { | ||
960 | struct gfs2_bitmap *bi; | ||
961 | const u32 length = rgd->rd_length; | ||
962 | const u8 *buffer = NULL; | ||
963 | u32 i, goal, count = 0; | ||
964 | |||
965 | for (i = 0, bi = rgd->rd_bits; i < length; i++, bi++) { | ||
966 | goal = 0; | ||
967 | buffer = bi->bi_bh->b_data + bi->bi_offset; | ||
968 | WARN_ON(!buffer_uptodate(bi->bi_bh)); | ||
969 | while (goal < bi->bi_len * GFS2_NBBY) { | ||
970 | goal = gfs2_bitfit(buffer, bi->bi_len, goal, | ||
971 | GFS2_BLKST_UNLINKED); | ||
972 | if (goal == BFITNOENT) | ||
973 | break; | ||
974 | count++; | ||
975 | goal++; | ||
976 | } | ||
977 | } | ||
978 | |||
979 | return count; | ||
980 | } | ||
981 | |||
982 | |||
739 | /** | 983 | /** |
740 | * gfs2_rgrp_go_lock - Read in a RG's header and bitmaps | 984 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps |
741 | * @gh: The glock holder for the resource group | 985 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
742 | * | 986 | * |
743 | * Read in all of a Resource Group's header and bitmap blocks. | 987 | * Read in all of a Resource Group's header and bitmap blocks. |
744 | * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. | 988 | * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. |
@@ -746,9 +990,8 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | |||
746 | * Returns: errno | 990 | * Returns: errno |
747 | */ | 991 | */ |
748 | 992 | ||
749 | int gfs2_rgrp_go_lock(struct gfs2_holder *gh) | 993 | int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) |
750 | { | 994 | { |
751 | struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; | ||
752 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 995 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
753 | struct gfs2_glock *gl = rgd->rd_gl; | 996 | struct gfs2_glock *gl = rgd->rd_gl; |
754 | unsigned int length = rgd->rd_length; | 997 | unsigned int length = rgd->rd_length; |
@@ -756,6 +999,9 @@ int gfs2_rgrp_go_lock(struct gfs2_holder *gh) | |||
756 | unsigned int x, y; | 999 | unsigned int x, y; |
757 | int error; | 1000 | int error; |
758 | 1001 | ||
1002 | if (rgd->rd_bits[0].bi_bh != NULL) | ||
1003 | return 0; | ||
1004 | |||
759 | for (x = 0; x < length; x++) { | 1005 | for (x = 0; x < length; x++) { |
760 | bi = rgd->rd_bits + x; | 1006 | bi = rgd->rd_bits + x; |
761 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); | 1007 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); |
@@ -782,7 +1028,20 @@ int gfs2_rgrp_go_lock(struct gfs2_holder *gh) | |||
782 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); | 1028 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); |
783 | rgd->rd_free_clone = rgd->rd_free; | 1029 | rgd->rd_free_clone = rgd->rd_free; |
784 | } | 1030 | } |
785 | 1031 | if (be32_to_cpu(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) { | |
1032 | rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd)); | ||
1033 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, | ||
1034 | rgd->rd_bits[0].bi_bh->b_data); | ||
1035 | } | ||
1036 | else if (sdp->sd_args.ar_rgrplvb) { | ||
1037 | if (!gfs2_rgrp_lvb_valid(rgd)){ | ||
1038 | gfs2_consist_rgrpd(rgd); | ||
1039 | error = -EIO; | ||
1040 | goto fail; | ||
1041 | } | ||
1042 | if (rgd->rd_rgl->rl_unlinked == 0) | ||
1043 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | ||
1044 | } | ||
786 | return 0; | 1045 | return 0; |
787 | 1046 | ||
788 | fail: | 1047 | fail: |
@@ -796,6 +1055,39 @@ fail: | |||
796 | return error; | 1055 | return error; |
797 | } | 1056 | } |
798 | 1057 | ||
1058 | int update_rgrp_lvb(struct gfs2_rgrpd *rgd) | ||
1059 | { | ||
1060 | u32 rl_flags; | ||
1061 | |||
1062 | if (rgd->rd_flags & GFS2_RDF_UPTODATE) | ||
1063 | return 0; | ||
1064 | |||
1065 | if (be32_to_cpu(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) | ||
1066 | return gfs2_rgrp_bh_get(rgd); | ||
1067 | |||
1068 | rl_flags = be32_to_cpu(rgd->rd_rgl->rl_flags); | ||
1069 | rl_flags &= ~GFS2_RDF_MASK; | ||
1070 | rgd->rd_flags &= GFS2_RDF_MASK; | ||
1071 | rgd->rd_flags |= (rl_flags | GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); | ||
1072 | if (rgd->rd_rgl->rl_unlinked == 0) | ||
1073 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | ||
1074 | rgd->rd_free = be32_to_cpu(rgd->rd_rgl->rl_free); | ||
1075 | rgd->rd_free_clone = rgd->rd_free; | ||
1076 | rgd->rd_dinodes = be32_to_cpu(rgd->rd_rgl->rl_dinodes); | ||
1077 | rgd->rd_igeneration = be64_to_cpu(rgd->rd_rgl->rl_igeneration); | ||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | int gfs2_rgrp_go_lock(struct gfs2_holder *gh) | ||
1082 | { | ||
1083 | struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; | ||
1084 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
1085 | |||
1086 | if (gh->gh_flags & GL_SKIP && sdp->sd_args.ar_rgrplvb) | ||
1087 | return 0; | ||
1088 | return gfs2_rgrp_bh_get((struct gfs2_rgrpd *)gh->gh_gl->gl_object); | ||
1089 | } | ||
1090 | |||
799 | /** | 1091 | /** |
800 | * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get() | 1092 | * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get() |
801 | * @gh: The glock holder for the resource group | 1093 | * @gh: The glock holder for the resource group |
@@ -809,8 +1101,10 @@ void gfs2_rgrp_go_unlock(struct gfs2_holder *gh) | |||
809 | 1101 | ||
810 | for (x = 0; x < length; x++) { | 1102 | for (x = 0; x < length; x++) { |
811 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | 1103 | struct gfs2_bitmap *bi = rgd->rd_bits + x; |
812 | brelse(bi->bi_bh); | 1104 | if (bi->bi_bh) { |
813 | bi->bi_bh = NULL; | 1105 | brelse(bi->bi_bh); |
1106 | bi->bi_bh = NULL; | ||
1107 | } | ||
814 | } | 1108 | } |
815 | 1109 | ||
816 | } | 1110 | } |
@@ -954,6 +1248,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) | |||
954 | rgd->rd_flags |= GFS2_RGF_TRIMMED; | 1248 | rgd->rd_flags |= GFS2_RGF_TRIMMED; |
955 | gfs2_trans_add_bh(rgd->rd_gl, bh, 1); | 1249 | gfs2_trans_add_bh(rgd->rd_gl, bh, 1); |
956 | gfs2_rgrp_out(rgd, bh->b_data); | 1250 | gfs2_rgrp_out(rgd, bh->b_data); |
1251 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, bh->b_data); | ||
957 | gfs2_trans_end(sdp); | 1252 | gfs2_trans_end(sdp); |
958 | } | 1253 | } |
959 | } | 1254 | } |
@@ -974,38 +1269,184 @@ out: | |||
974 | } | 1269 | } |
975 | 1270 | ||
976 | /** | 1271 | /** |
977 | * gfs2_qadata_get - get the struct gfs2_qadata structure for an inode | 1272 | * rs_insert - insert a new multi-block reservation into the rgrp's rb_tree |
978 | * @ip: the incore GFS2 inode structure | 1273 | * @bi: the bitmap with the blocks |
1274 | * @ip: the inode structure | ||
1275 | * @biblk: the 32-bit block number relative to the start of the bitmap | ||
1276 | * @amount: the number of blocks to reserve | ||
979 | * | 1277 | * |
980 | * Returns: the struct gfs2_qadata | 1278 | * Returns: NULL - reservation was already taken, so not inserted |
1279 | * pointer to the inserted reservation | ||
981 | */ | 1280 | */ |
1281 | static struct gfs2_blkreserv *rs_insert(struct gfs2_bitmap *bi, | ||
1282 | struct gfs2_inode *ip, u32 biblk, | ||
1283 | int amount) | ||
1284 | { | ||
1285 | struct rb_node **newn, *parent = NULL; | ||
1286 | int rc; | ||
1287 | struct gfs2_blkreserv *rs = ip->i_res; | ||
1288 | struct gfs2_rgrpd *rgd = rs->rs_rgd; | ||
1289 | u64 fsblock = gfs2_bi2rgd_blk(bi, biblk) + rgd->rd_data0; | ||
982 | 1290 | ||
983 | struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip) | 1291 | spin_lock(&rgd->rd_rsspin); |
1292 | newn = &rgd->rd_rstree.rb_node; | ||
1293 | BUG_ON(!ip->i_res); | ||
1294 | BUG_ON(gfs2_rs_active(rs)); | ||
1295 | /* Figure out where to put new node */ | ||
1296 | /*BUG_ON(!gfs2_glock_is_locked_by_me(rgd->rd_gl));*/ | ||
1297 | while (*newn) { | ||
1298 | struct gfs2_blkreserv *cur = | ||
1299 | rb_entry(*newn, struct gfs2_blkreserv, rs_node); | ||
1300 | |||
1301 | parent = *newn; | ||
1302 | rc = rs_cmp(fsblock, amount, cur); | ||
1303 | if (rc > 0) | ||
1304 | newn = &((*newn)->rb_right); | ||
1305 | else if (rc < 0) | ||
1306 | newn = &((*newn)->rb_left); | ||
1307 | else { | ||
1308 | spin_unlock(&rgd->rd_rsspin); | ||
1309 | return NULL; /* reservation already in use */ | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | /* Do our reservation work */ | ||
1314 | rs = ip->i_res; | ||
1315 | rs->rs_free = amount; | ||
1316 | rs->rs_biblk = biblk; | ||
1317 | rs->rs_bi = bi; | ||
1318 | rb_link_node(&rs->rs_node, parent, newn); | ||
1319 | rb_insert_color(&rs->rs_node, &rgd->rd_rstree); | ||
1320 | |||
1321 | /* Do our inode accounting for the reservation */ | ||
1322 | /*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ | ||
1323 | |||
1324 | /* Do our rgrp accounting for the reservation */ | ||
1325 | rgd->rd_reserved += amount; /* blocks reserved */ | ||
1326 | rgd->rd_rs_cnt++; /* number of in-tree reservations */ | ||
1327 | spin_unlock(&rgd->rd_rsspin); | ||
1328 | trace_gfs2_rs(ip, rs, TRACE_RS_INSERT); | ||
1329 | return rs; | ||
1330 | } | ||
1331 | |||
1332 | /** | ||
1333 | * unclaimed_blocks - return number of blocks that aren't spoken for | ||
1334 | */ | ||
1335 | static u32 unclaimed_blocks(struct gfs2_rgrpd *rgd) | ||
984 | { | 1336 | { |
985 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1337 | return rgd->rd_free_clone - rgd->rd_reserved; |
986 | int error; | ||
987 | BUG_ON(ip->i_qadata != NULL); | ||
988 | ip->i_qadata = kzalloc(sizeof(struct gfs2_qadata), GFP_NOFS); | ||
989 | error = gfs2_rindex_update(sdp); | ||
990 | if (error) | ||
991 | fs_warn(sdp, "rindex update returns %d\n", error); | ||
992 | return ip->i_qadata; | ||
993 | } | 1338 | } |
994 | 1339 | ||
995 | /** | 1340 | /** |
996 | * gfs2_blkrsv_get - get the struct gfs2_blkreserv structure for an inode | 1341 | * rg_mblk_search - find a group of multiple free blocks |
997 | * @ip: the incore GFS2 inode structure | 1342 | * @rgd: the resource group descriptor |
1343 | * @rs: the block reservation | ||
1344 | * @ip: pointer to the inode for which we're reserving blocks | ||
998 | * | 1345 | * |
999 | * Returns: the struct gfs2_qadata | 1346 | * This is very similar to rgblk_search, except we're looking for whole |
1347 | * 64-bit words that represent a chunk of 32 free blocks. I'm only focusing | ||
1348 | * on aligned dwords for speed's sake. | ||
1349 | * | ||
1350 | * Returns: 0 if successful or BFITNOENT if there isn't enough free space | ||
1000 | */ | 1351 | */ |
1001 | 1352 | ||
1002 | static int gfs2_blkrsv_get(struct gfs2_inode *ip) | 1353 | static int rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
1003 | { | 1354 | { |
1004 | BUG_ON(ip->i_res != NULL); | 1355 | struct gfs2_bitmap *bi = rgd->rd_bits; |
1005 | ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); | 1356 | const u32 length = rgd->rd_length; |
1006 | if (!ip->i_res) | 1357 | u32 blk; |
1007 | return -ENOMEM; | 1358 | unsigned int buf, x, search_bytes; |
1008 | return 0; | 1359 | u8 *buffer = NULL; |
1360 | u8 *ptr, *end, *nonzero; | ||
1361 | u32 goal, rsv_bytes; | ||
1362 | struct gfs2_blkreserv *rs; | ||
1363 | u32 best_rs_bytes, unclaimed; | ||
1364 | int best_rs_blocks; | ||
1365 | |||
1366 | /* Find bitmap block that contains bits for goal block */ | ||
1367 | if (rgrp_contains_block(rgd, ip->i_goal)) | ||
1368 | goal = ip->i_goal - rgd->rd_data0; | ||
1369 | else | ||
1370 | goal = rgd->rd_last_alloc; | ||
1371 | for (buf = 0; buf < length; buf++) { | ||
1372 | bi = rgd->rd_bits + buf; | ||
1373 | /* Convert scope of "goal" from rgrp-wide to within | ||
1374 | found bit block */ | ||
1375 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) { | ||
1376 | goal -= bi->bi_start * GFS2_NBBY; | ||
1377 | goto do_search; | ||
1378 | } | ||
1379 | } | ||
1380 | buf = 0; | ||
1381 | goal = 0; | ||
1382 | |||
1383 | do_search: | ||
1384 | best_rs_blocks = max_t(int, atomic_read(&ip->i_res->rs_sizehint), | ||
1385 | (RGRP_RSRV_MINBLKS * rgd->rd_length)); | ||
1386 | best_rs_bytes = (best_rs_blocks * | ||
1387 | (1 + (RSRV_CONTENTION_FACTOR * rgd->rd_rs_cnt))) / | ||
1388 | GFS2_NBBY; /* 1 + is for our not-yet-created reservation */ | ||
1389 | best_rs_bytes = ALIGN(best_rs_bytes, sizeof(u64)); | ||
1390 | unclaimed = unclaimed_blocks(rgd); | ||
1391 | if (best_rs_bytes * GFS2_NBBY > unclaimed) | ||
1392 | best_rs_bytes = unclaimed >> GFS2_BIT_SIZE; | ||
1393 | |||
1394 | for (x = 0; x <= length; x++) { | ||
1395 | bi = rgd->rd_bits + buf; | ||
1396 | |||
1397 | if (test_bit(GBF_FULL, &bi->bi_flags)) | ||
1398 | goto skip; | ||
1399 | |||
1400 | WARN_ON(!buffer_uptodate(bi->bi_bh)); | ||
1401 | if (bi->bi_clone) | ||
1402 | buffer = bi->bi_clone + bi->bi_offset; | ||
1403 | else | ||
1404 | buffer = bi->bi_bh->b_data + bi->bi_offset; | ||
1405 | |||
1406 | /* We have to keep the reservations aligned on u64 boundaries | ||
1407 | otherwise we could get situations where a byte can't be | ||
1408 | used because it's after a reservation, but a free bit still | ||
1409 | is within the reservation's area. */ | ||
1410 | ptr = buffer + ALIGN(goal >> GFS2_BIT_SIZE, sizeof(u64)); | ||
1411 | end = (buffer + bi->bi_len); | ||
1412 | while (ptr < end) { | ||
1413 | rsv_bytes = 0; | ||
1414 | if ((ptr + best_rs_bytes) <= end) | ||
1415 | search_bytes = best_rs_bytes; | ||
1416 | else | ||
1417 | search_bytes = end - ptr; | ||
1418 | BUG_ON(!search_bytes); | ||
1419 | nonzero = memchr_inv(ptr, 0, search_bytes); | ||
1420 | /* If the lot is all zeroes, reserve the whole size. If | ||
1421 | there's enough zeroes to satisfy the request, use | ||
1422 | what we can. If there's not enough, keep looking. */ | ||
1423 | if (nonzero == NULL) | ||
1424 | rsv_bytes = search_bytes; | ||
1425 | else if ((nonzero - ptr) * GFS2_NBBY >= | ||
1426 | ip->i_res->rs_requested) | ||
1427 | rsv_bytes = (nonzero - ptr); | ||
1428 | |||
1429 | if (rsv_bytes) { | ||
1430 | blk = ((ptr - buffer) * GFS2_NBBY); | ||
1431 | BUG_ON(blk >= bi->bi_len * GFS2_NBBY); | ||
1432 | rs = rs_insert(bi, ip, blk, | ||
1433 | rsv_bytes * GFS2_NBBY); | ||
1434 | if (IS_ERR(rs)) | ||
1435 | return PTR_ERR(rs); | ||
1436 | if (rs) | ||
1437 | return 0; | ||
1438 | } | ||
1439 | ptr += ALIGN(search_bytes, sizeof(u64)); | ||
1440 | } | ||
1441 | skip: | ||
1442 | /* Try next bitmap block (wrap back to rgrp header | ||
1443 | if at end) */ | ||
1444 | buf++; | ||
1445 | buf %= length; | ||
1446 | goal = 0; | ||
1447 | } | ||
1448 | |||
1449 | return BFITNOENT; | ||
1009 | } | 1450 | } |
1010 | 1451 | ||
1011 | /** | 1452 | /** |
@@ -1014,24 +1455,26 @@ static int gfs2_blkrsv_get(struct gfs2_inode *ip) | |||
1014 | * @ip: the inode | 1455 | * @ip: the inode |
1015 | * | 1456 | * |
1016 | * If there's room for the requested blocks to be allocated from the RG: | 1457 | * If there's room for the requested blocks to be allocated from the RG: |
1458 | * This will try to get a multi-block reservation first, and if that doesn't | ||
1459 | * fit, it will take what it can. | ||
1017 | * | 1460 | * |
1018 | * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) | 1461 | * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) |
1019 | */ | 1462 | */ |
1020 | 1463 | ||
1021 | static int try_rgrp_fit(const struct gfs2_rgrpd *rgd, const struct gfs2_inode *ip) | 1464 | static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
1022 | { | 1465 | { |
1023 | const struct gfs2_blkreserv *rs = ip->i_res; | 1466 | struct gfs2_blkreserv *rs = ip->i_res; |
1024 | 1467 | ||
1025 | if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) | 1468 | if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) |
1026 | return 0; | 1469 | return 0; |
1027 | if (rgd->rd_free_clone >= rs->rs_requested) | 1470 | /* Look for a multi-block reservation. */ |
1471 | if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS && | ||
1472 | rg_mblk_search(rgd, ip) != BFITNOENT) | ||
1473 | return 1; | ||
1474 | if (unclaimed_blocks(rgd) >= rs->rs_requested) | ||
1028 | return 1; | 1475 | return 1; |
1029 | return 0; | ||
1030 | } | ||
1031 | 1476 | ||
1032 | static inline u32 gfs2_bi2rgd_blk(struct gfs2_bitmap *bi, u32 blk) | 1477 | return 0; |
1033 | { | ||
1034 | return (bi->bi_start * GFS2_NBBY) + blk; | ||
1035 | } | 1478 | } |
1036 | 1479 | ||
1037 | /** | 1480 | /** |
@@ -1101,119 +1544,120 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip | |||
1101 | } | 1544 | } |
1102 | 1545 | ||
1103 | /** | 1546 | /** |
1104 | * get_local_rgrp - Choose and lock a rgrp for allocation | 1547 | * gfs2_inplace_reserve - Reserve space in the filesystem |
1105 | * @ip: the inode to reserve space for | 1548 | * @ip: the inode to reserve space for |
1106 | * @last_unlinked: the last unlinked block | 1549 | * @requested: the number of blocks to be reserved |
1107 | * | ||
1108 | * Try to acquire rgrp in way which avoids contending with others. | ||
1109 | * | 1550 | * |
1110 | * Returns: errno | 1551 | * Returns: errno |
1111 | */ | 1552 | */ |
1112 | 1553 | ||
1113 | static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | 1554 | int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) |
1114 | { | 1555 | { |
1115 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1556 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1116 | struct gfs2_rgrpd *rgd, *begin = NULL; | 1557 | struct gfs2_rgrpd *begin = NULL; |
1117 | struct gfs2_blkreserv *rs = ip->i_res; | 1558 | struct gfs2_blkreserv *rs = ip->i_res; |
1118 | int error, rg_locked, flags = LM_FLAG_TRY; | 1559 | int error = 0, rg_locked, flags = LM_FLAG_TRY; |
1560 | u64 last_unlinked = NO_BLOCK; | ||
1119 | int loops = 0; | 1561 | int loops = 0; |
1120 | 1562 | ||
1121 | if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) | 1563 | if (sdp->sd_args.ar_rgrplvb) |
1122 | rgd = begin = ip->i_rgd; | 1564 | flags |= GL_SKIP; |
1123 | else | 1565 | rs->rs_requested = requested; |
1124 | rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); | 1566 | if (gfs2_assert_warn(sdp, requested)) { |
1125 | 1567 | error = -EINVAL; | |
1126 | if (rgd == NULL) | 1568 | goto out; |
1569 | } | ||
1570 | if (gfs2_rs_active(rs)) { | ||
1571 | begin = rs->rs_rgd; | ||
1572 | flags = 0; /* Yoda: Do or do not. There is no try */ | ||
1573 | } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { | ||
1574 | rs->rs_rgd = begin = ip->i_rgd; | ||
1575 | } else { | ||
1576 | rs->rs_rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); | ||
1577 | } | ||
1578 | if (rs->rs_rgd == NULL) | ||
1127 | return -EBADSLT; | 1579 | return -EBADSLT; |
1128 | 1580 | ||
1129 | while (loops < 3) { | 1581 | while (loops < 3) { |
1130 | rg_locked = 0; | 1582 | rg_locked = 0; |
1131 | 1583 | ||
1132 | if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { | 1584 | if (gfs2_glock_is_locked_by_me(rs->rs_rgd->rd_gl)) { |
1133 | rg_locked = 1; | 1585 | rg_locked = 1; |
1134 | error = 0; | 1586 | error = 0; |
1587 | } else if (!loops && !gfs2_rs_active(rs) && | ||
1588 | rs->rs_rgd->rd_rs_cnt > RGRP_RSRV_MAX_CONTENDERS) { | ||
1589 | /* If the rgrp already is maxed out for contenders, | ||
1590 | we can eliminate it as a "first pass" without even | ||
1591 | requesting the rgrp glock. */ | ||
1592 | error = GLR_TRYFAILED; | ||
1135 | } else { | 1593 | } else { |
1136 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, | 1594 | error = gfs2_glock_nq_init(rs->rs_rgd->rd_gl, |
1137 | flags, &rs->rs_rgd_gh); | 1595 | LM_ST_EXCLUSIVE, flags, |
1596 | &rs->rs_rgd_gh); | ||
1597 | if (!error && sdp->sd_args.ar_rgrplvb) { | ||
1598 | error = update_rgrp_lvb(rs->rs_rgd); | ||
1599 | if (error) { | ||
1600 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | ||
1601 | return error; | ||
1602 | } | ||
1603 | } | ||
1138 | } | 1604 | } |
1139 | switch (error) { | 1605 | switch (error) { |
1140 | case 0: | 1606 | case 0: |
1141 | if (try_rgrp_fit(rgd, ip)) { | 1607 | if (gfs2_rs_active(rs)) { |
1142 | ip->i_rgd = rgd; | 1608 | if (unclaimed_blocks(rs->rs_rgd) + |
1609 | rs->rs_free >= rs->rs_requested) { | ||
1610 | ip->i_rgd = rs->rs_rgd; | ||
1611 | return 0; | ||
1612 | } | ||
1613 | /* We have a multi-block reservation, but the | ||
1614 | rgrp doesn't have enough free blocks to | ||
1615 | satisfy the request. Free the reservation | ||
1616 | and look for a suitable rgrp. */ | ||
1617 | gfs2_rs_deltree(rs); | ||
1618 | } | ||
1619 | if (try_rgrp_fit(rs->rs_rgd, ip)) { | ||
1620 | if (sdp->sd_args.ar_rgrplvb) | ||
1621 | gfs2_rgrp_bh_get(rs->rs_rgd); | ||
1622 | ip->i_rgd = rs->rs_rgd; | ||
1143 | return 0; | 1623 | return 0; |
1144 | } | 1624 | } |
1145 | if (rgd->rd_flags & GFS2_RDF_CHECK) | 1625 | if (rs->rs_rgd->rd_flags & GFS2_RDF_CHECK) { |
1146 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1626 | if (sdp->sd_args.ar_rgrplvb) |
1627 | gfs2_rgrp_bh_get(rs->rs_rgd); | ||
1628 | try_rgrp_unlink(rs->rs_rgd, &last_unlinked, | ||
1629 | ip->i_no_addr); | ||
1630 | } | ||
1147 | if (!rg_locked) | 1631 | if (!rg_locked) |
1148 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | 1632 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); |
1149 | /* fall through */ | 1633 | /* fall through */ |
1150 | case GLR_TRYFAILED: | 1634 | case GLR_TRYFAILED: |
1151 | rgd = gfs2_rgrpd_get_next(rgd); | 1635 | rs->rs_rgd = gfs2_rgrpd_get_next(rs->rs_rgd); |
1152 | if (rgd == begin) { | 1636 | rs->rs_rgd = rs->rs_rgd ? : begin; /* if NULL, wrap */ |
1153 | flags = 0; | 1637 | if (rs->rs_rgd != begin) /* If we didn't wrap */ |
1154 | loops++; | 1638 | break; |
1155 | } | 1639 | |
1640 | flags &= ~LM_FLAG_TRY; | ||
1641 | loops++; | ||
1642 | /* Check that fs hasn't grown if writing to rindex */ | ||
1643 | if (ip == GFS2_I(sdp->sd_rindex) && | ||
1644 | !sdp->sd_rindex_uptodate) { | ||
1645 | error = gfs2_ri_update(ip); | ||
1646 | if (error) | ||
1647 | goto out; | ||
1648 | } else if (loops == 2) | ||
1649 | /* Flushing the log may release space */ | ||
1650 | gfs2_log_flush(sdp, NULL); | ||
1156 | break; | 1651 | break; |
1157 | default: | 1652 | default: |
1158 | return error; | 1653 | goto out; |
1159 | } | 1654 | } |
1160 | } | 1655 | } |
1161 | 1656 | error = -ENOSPC; | |
1162 | return -ENOSPC; | ||
1163 | } | ||
1164 | |||
1165 | static void gfs2_blkrsv_put(struct gfs2_inode *ip) | ||
1166 | { | ||
1167 | BUG_ON(ip->i_res == NULL); | ||
1168 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | ||
1169 | ip->i_res = NULL; | ||
1170 | } | ||
1171 | |||
1172 | /** | ||
1173 | * gfs2_inplace_reserve - Reserve space in the filesystem | ||
1174 | * @ip: the inode to reserve space for | ||
1175 | * @requested: the number of blocks to be reserved | ||
1176 | * | ||
1177 | * Returns: errno | ||
1178 | */ | ||
1179 | |||
1180 | int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) | ||
1181 | { | ||
1182 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1183 | struct gfs2_blkreserv *rs; | ||
1184 | int error; | ||
1185 | u64 last_unlinked = NO_BLOCK; | ||
1186 | int tries = 0; | ||
1187 | |||
1188 | error = gfs2_blkrsv_get(ip); | ||
1189 | if (error) | ||
1190 | return error; | ||
1191 | |||
1192 | rs = ip->i_res; | ||
1193 | rs->rs_requested = requested; | ||
1194 | if (gfs2_assert_warn(sdp, requested)) { | ||
1195 | error = -EINVAL; | ||
1196 | goto out; | ||
1197 | } | ||
1198 | |||
1199 | do { | ||
1200 | error = get_local_rgrp(ip, &last_unlinked); | ||
1201 | if (error != -ENOSPC) | ||
1202 | break; | ||
1203 | /* Check that fs hasn't grown if writing to rindex */ | ||
1204 | if (ip == GFS2_I(sdp->sd_rindex) && !sdp->sd_rindex_uptodate) { | ||
1205 | error = gfs2_ri_update(ip); | ||
1206 | if (error) | ||
1207 | break; | ||
1208 | continue; | ||
1209 | } | ||
1210 | /* Flushing the log may release space */ | ||
1211 | gfs2_log_flush(sdp, NULL); | ||
1212 | } while (tries++ < 3); | ||
1213 | 1657 | ||
1214 | out: | 1658 | out: |
1215 | if (error) | 1659 | if (error) |
1216 | gfs2_blkrsv_put(ip); | 1660 | rs->rs_requested = 0; |
1217 | return error; | 1661 | return error; |
1218 | } | 1662 | } |
1219 | 1663 | ||
@@ -1228,9 +1672,15 @@ void gfs2_inplace_release(struct gfs2_inode *ip) | |||
1228 | { | 1672 | { |
1229 | struct gfs2_blkreserv *rs = ip->i_res; | 1673 | struct gfs2_blkreserv *rs = ip->i_res; |
1230 | 1674 | ||
1675 | if (!rs) | ||
1676 | return; | ||
1677 | |||
1678 | if (!rs->rs_free) | ||
1679 | gfs2_rs_deltree(rs); | ||
1680 | |||
1231 | if (rs->rs_rgd_gh.gh_gl) | 1681 | if (rs->rs_rgd_gh.gh_gl) |
1232 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | 1682 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); |
1233 | gfs2_blkrsv_put(ip); | 1683 | rs->rs_requested = 0; |
1234 | } | 1684 | } |
1235 | 1685 | ||
1236 | /** | 1686 | /** |
@@ -1326,7 +1776,27 @@ do_search: | |||
1326 | if (state != GFS2_BLKST_UNLINKED && bi->bi_clone) | 1776 | if (state != GFS2_BLKST_UNLINKED && bi->bi_clone) |
1327 | buffer = bi->bi_clone + bi->bi_offset; | 1777 | buffer = bi->bi_clone + bi->bi_offset; |
1328 | 1778 | ||
1329 | biblk = gfs2_bitfit(buffer, bi->bi_len, goal, state); | 1779 | while (1) { |
1780 | struct gfs2_blkreserv *rs; | ||
1781 | u32 rgblk; | ||
1782 | |||
1783 | biblk = gfs2_bitfit(buffer, bi->bi_len, goal, state); | ||
1784 | if (biblk == BFITNOENT) | ||
1785 | break; | ||
1786 | /* Check if this block is reserved() */ | ||
1787 | rgblk = gfs2_bi2rgd_blk(bi, biblk); | ||
1788 | rs = rs_find(rgd, rgblk); | ||
1789 | if (rs == NULL) | ||
1790 | break; | ||
1791 | |||
1792 | BUG_ON(rs->rs_bi != bi); | ||
1793 | biblk = BFITNOENT; | ||
1794 | /* This should jump to the first block after the | ||
1795 | reservation. */ | ||
1796 | goal = rs->rs_biblk + rs->rs_free; | ||
1797 | if (goal >= bi->bi_len * GFS2_NBBY) | ||
1798 | break; | ||
1799 | } | ||
1330 | if (biblk != BFITNOENT) | 1800 | if (biblk != BFITNOENT) |
1331 | break; | 1801 | break; |
1332 | 1802 | ||
@@ -1362,8 +1832,9 @@ static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi, | |||
1362 | u32 blk, bool dinode, unsigned int *n) | 1832 | u32 blk, bool dinode, unsigned int *n) |
1363 | { | 1833 | { |
1364 | const unsigned int elen = *n; | 1834 | const unsigned int elen = *n; |
1365 | u32 goal; | 1835 | u32 goal, rgblk; |
1366 | const u8 *buffer = NULL; | 1836 | const u8 *buffer = NULL; |
1837 | struct gfs2_blkreserv *rs; | ||
1367 | 1838 | ||
1368 | *n = 0; | 1839 | *n = 0; |
1369 | buffer = bi->bi_bh->b_data + bi->bi_offset; | 1840 | buffer = bi->bi_bh->b_data + bi->bi_offset; |
@@ -1376,6 +1847,10 @@ static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi, | |||
1376 | goal++; | 1847 | goal++; |
1377 | if (goal >= (bi->bi_len * GFS2_NBBY)) | 1848 | if (goal >= (bi->bi_len * GFS2_NBBY)) |
1378 | break; | 1849 | break; |
1850 | rgblk = gfs2_bi2rgd_blk(bi, goal); | ||
1851 | rs = rs_find(rgd, rgblk); | ||
1852 | if (rs) /* Oops, we bumped into someone's reservation */ | ||
1853 | break; | ||
1379 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | 1854 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != |
1380 | GFS2_BLKST_FREE) | 1855 | GFS2_BLKST_FREE) |
1381 | break; | 1856 | break; |
@@ -1451,12 +1926,22 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
1451 | 1926 | ||
1452 | int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl) | 1927 | int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl) |
1453 | { | 1928 | { |
1454 | const struct gfs2_rgrpd *rgd = gl->gl_object; | 1929 | struct gfs2_rgrpd *rgd = gl->gl_object; |
1930 | struct gfs2_blkreserv *trs; | ||
1931 | const struct rb_node *n; | ||
1932 | |||
1455 | if (rgd == NULL) | 1933 | if (rgd == NULL) |
1456 | return 0; | 1934 | return 0; |
1457 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u\n", | 1935 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u\n", |
1458 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, | 1936 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, |
1459 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes); | 1937 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes, |
1938 | rgd->rd_reserved); | ||
1939 | spin_lock(&rgd->rd_rsspin); | ||
1940 | for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) { | ||
1941 | trs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
1942 | dump_rs(seq, trs); | ||
1943 | } | ||
1944 | spin_unlock(&rgd->rd_rsspin); | ||
1460 | return 0; | 1945 | return 0; |
1461 | } | 1946 | } |
1462 | 1947 | ||
@@ -1471,10 +1956,63 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
1471 | } | 1956 | } |
1472 | 1957 | ||
1473 | /** | 1958 | /** |
1959 | * claim_reserved_blks - Claim previously reserved blocks | ||
1960 | * @ip: the inode that's claiming the reservation | ||
1961 | * @dinode: 1 if this block is a dinode block, otherwise data block | ||
1962 | * @nblocks: desired extent length | ||
1963 | * | ||
1964 | * Lay claim to previously allocated block reservation blocks. | ||
1965 | * Returns: Starting block number of the blocks claimed. | ||
1966 | * Sets *nblocks to the actual extent length allocated. | ||
1967 | */ | ||
1968 | static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | ||
1969 | unsigned int *nblocks) | ||
1970 | { | ||
1971 | struct gfs2_blkreserv *rs = ip->i_res; | ||
1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; | ||
1973 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1974 | struct gfs2_bitmap *bi; | ||
1975 | u64 start_block = gfs2_rs_startblk(rs); | ||
1976 | const unsigned int elen = *nblocks; | ||
1977 | |||
1978 | /*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ | ||
1979 | gfs2_assert_withdraw(sdp, rgd); | ||
1980 | /*BUG_ON(!gfs2_glock_is_locked_by_me(rgd->rd_gl));*/ | ||
1981 | bi = rs->rs_bi; | ||
1982 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1983 | |||
1984 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { | ||
1985 | /* Make sure the bitmap hasn't changed */ | ||
1986 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, | ||
1987 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | ||
1988 | rs->rs_biblk++; | ||
1989 | rs->rs_free--; | ||
1990 | |||
1991 | BUG_ON(!rgd->rd_reserved); | ||
1992 | rgd->rd_reserved--; | ||
1993 | dinode = false; | ||
1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); | ||
1995 | } | ||
1996 | |||
1997 | if (!rs->rs_free) { | ||
1998 | struct gfs2_rgrpd *rgd = ip->i_res->rs_rgd; | ||
1999 | |||
2000 | gfs2_rs_deltree(rs); | ||
2001 | /* -nblocks because we haven't returned to do the math yet. | ||
2002 | I'm doing the math backwards to prevent negative numbers, | ||
2003 | but think of it as: | ||
2004 | if (unclaimed_blocks(rgd) - *nblocks >= RGRP_RSRV_MINBLKS */ | ||
2005 | if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS + *nblocks) | ||
2006 | rg_mblk_search(rgd, ip); | ||
2007 | } | ||
2008 | return start_block; | ||
2009 | } | ||
2010 | |||
2011 | /** | ||
1474 | * gfs2_alloc_blocks - Allocate one or more blocks of data and/or a dinode | 2012 | * gfs2_alloc_blocks - Allocate one or more blocks of data and/or a dinode |
1475 | * @ip: the inode to allocate the block for | 2013 | * @ip: the inode to allocate the block for |
1476 | * @bn: Used to return the starting block number | 2014 | * @bn: Used to return the starting block number |
1477 | * @ndata: requested number of blocks/extent length (value/result) | 2015 | * @nblocks: requested number of blocks/extent length (value/result) |
1478 | * @dinode: 1 if we're allocating a dinode block, else 0 | 2016 | * @dinode: 1 if we're allocating a dinode block, else 0 |
1479 | * @generation: the generation number of the inode | 2017 | * @generation: the generation number of the inode |
1480 | * | 2018 | * |
@@ -1496,23 +2034,37 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
1496 | /* Only happens if there is a bug in gfs2, return something distinctive | 2034 | /* Only happens if there is a bug in gfs2, return something distinctive |
1497 | * to ensure that it is noticed. | 2035 | * to ensure that it is noticed. |
1498 | */ | 2036 | */ |
1499 | if (ip->i_res == NULL) | 2037 | if (ip->i_res->rs_requested == 0) |
1500 | return -ECANCELED; | 2038 | return -ECANCELED; |
1501 | 2039 | ||
1502 | rgd = ip->i_rgd; | 2040 | /* Check if we have a multi-block reservation, and if so, claim the |
1503 | 2041 | next free block from it. */ | |
1504 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) | 2042 | if (gfs2_rs_active(ip->i_res)) { |
1505 | goal = ip->i_goal - rgd->rd_data0; | 2043 | BUG_ON(!ip->i_res->rs_free); |
1506 | else | 2044 | rgd = ip->i_res->rs_rgd; |
1507 | goal = rgd->rd_last_alloc; | 2045 | block = claim_reserved_blks(ip, dinode, nblocks); |
1508 | 2046 | } else { | |
1509 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | 2047 | rgd = ip->i_rgd; |
1510 | 2048 | ||
1511 | /* Since all blocks are reserved in advance, this shouldn't happen */ | 2049 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) |
1512 | if (blk == BFITNOENT) | 2050 | goal = ip->i_goal - rgd->rd_data0; |
1513 | goto rgrp_error; | 2051 | else |
2052 | goal = rgd->rd_last_alloc; | ||
2053 | |||
2054 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
2055 | |||
2056 | /* Since all blocks are reserved in advance, this shouldn't | ||
2057 | happen */ | ||
2058 | if (blk == BFITNOENT) { | ||
2059 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", | ||
2060 | *nblocks); | ||
2061 | printk(KERN_WARNING "FULL=%d\n", | ||
2062 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
2063 | goto rgrp_error; | ||
2064 | } | ||
1514 | 2065 | ||
1515 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | 2066 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); |
2067 | } | ||
1516 | ndata = *nblocks; | 2068 | ndata = *nblocks; |
1517 | if (dinode) | 2069 | if (dinode) |
1518 | ndata--; | 2070 | ndata--; |
@@ -1529,8 +2081,10 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
1529 | brelse(dibh); | 2081 | brelse(dibh); |
1530 | } | 2082 | } |
1531 | } | 2083 | } |
1532 | if (rgd->rd_free < *nblocks) | 2084 | if (rgd->rd_free < *nblocks) { |
2085 | printk(KERN_WARNING "nblocks=%u\n", *nblocks); | ||
1533 | goto rgrp_error; | 2086 | goto rgrp_error; |
2087 | } | ||
1534 | 2088 | ||
1535 | rgd->rd_free -= *nblocks; | 2089 | rgd->rd_free -= *nblocks; |
1536 | if (dinode) { | 2090 | if (dinode) { |
@@ -1542,6 +2096,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
1542 | 2096 | ||
1543 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 2097 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1544 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 2098 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2099 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | ||
1545 | 2100 | ||
1546 | gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); | 2101 | gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); |
1547 | if (dinode) | 2102 | if (dinode) |
@@ -1588,6 +2143,7 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta) | |||
1588 | rgd->rd_flags &= ~GFS2_RGF_TRIMMED; | 2143 | rgd->rd_flags &= ~GFS2_RGF_TRIMMED; |
1589 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 2144 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1590 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 2145 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2146 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | ||
1591 | 2147 | ||
1592 | /* Directories keep their data in the metadata address space */ | 2148 | /* Directories keep their data in the metadata address space */ |
1593 | if (meta || ip->i_depth) | 2149 | if (meta || ip->i_depth) |
@@ -1624,6 +2180,8 @@ void gfs2_unlink_di(struct inode *inode) | |||
1624 | trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED); | 2180 | trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED); |
1625 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 2181 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1626 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 2182 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2183 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | ||
2184 | update_rgrp_lvb_unlinked(rgd, 1); | ||
1627 | } | 2185 | } |
1628 | 2186 | ||
1629 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | 2187 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) |
@@ -1643,6 +2201,8 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1643 | 2201 | ||
1644 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 2202 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1645 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 2203 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2204 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | ||
2205 | update_rgrp_lvb_unlinked(rgd, -1); | ||
1646 | 2206 | ||
1647 | gfs2_statfs_change(sdp, 0, +1, -1); | 2207 | gfs2_statfs_change(sdp, 0, +1, -1); |
1648 | } | 2208 | } |
@@ -1784,6 +2344,7 @@ void gfs2_rlist_free(struct gfs2_rgrp_list *rlist) | |||
1784 | for (x = 0; x < rlist->rl_rgrps; x++) | 2344 | for (x = 0; x < rlist->rl_rgrps; x++) |
1785 | gfs2_holder_uninit(&rlist->rl_ghs[x]); | 2345 | gfs2_holder_uninit(&rlist->rl_ghs[x]); |
1786 | kfree(rlist->rl_ghs); | 2346 | kfree(rlist->rl_ghs); |
2347 | rlist->rl_ghs = NULL; | ||
1787 | } | 2348 | } |
1788 | } | 2349 | } |
1789 | 2350 | ||
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index b4b10f4de25f..ca6e26729b86 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -13,6 +13,14 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | 15 | ||
16 | /* Since each block in the file system is represented by two bits in the | ||
17 | * bitmap, one 64-bit word in the bitmap will represent 32 blocks. | ||
18 | * By reserving 32 blocks at a time, we can optimize / shortcut how we search | ||
19 | * through the bitmaps by looking a word at a time. | ||
20 | */ | ||
21 | #define RGRP_RSRV_MINBYTES 8 | ||
22 | #define RGRP_RSRV_MINBLKS ((u32)(RGRP_RSRV_MINBYTES * GFS2_NBBY)) | ||
23 | |||
16 | struct gfs2_rgrpd; | 24 | struct gfs2_rgrpd; |
17 | struct gfs2_sbd; | 25 | struct gfs2_sbd; |
18 | struct gfs2_holder; | 26 | struct gfs2_holder; |
@@ -29,13 +37,7 @@ extern void gfs2_free_clones(struct gfs2_rgrpd *rgd); | |||
29 | extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh); | 37 | extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh); |
30 | extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh); | 38 | extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh); |
31 | 39 | ||
32 | extern struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip); | 40 | extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); |
33 | static inline void gfs2_qadata_put(struct gfs2_inode *ip) | ||
34 | { | ||
35 | BUG_ON(ip->i_qadata == NULL); | ||
36 | kfree(ip->i_qadata); | ||
37 | ip->i_qadata = NULL; | ||
38 | } | ||
39 | 41 | ||
40 | extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested); | 42 | extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested); |
41 | extern void gfs2_inplace_release(struct gfs2_inode *ip); | 43 | extern void gfs2_inplace_release(struct gfs2_inode *ip); |
@@ -43,6 +45,9 @@ extern void gfs2_inplace_release(struct gfs2_inode *ip); | |||
43 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, | 45 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, |
44 | bool dinode, u64 *generation); | 46 | bool dinode, u64 *generation); |
45 | 47 | ||
48 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); | ||
49 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); | ||
50 | extern void gfs2_rs_delete(struct gfs2_inode *ip); | ||
46 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); | 51 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
47 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 52 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
48 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); | 53 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); |
@@ -68,4 +73,30 @@ extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
68 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed); | 73 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed); |
69 | extern int gfs2_fitrim(struct file *filp, void __user *argp); | 74 | extern int gfs2_fitrim(struct file *filp, void __user *argp); |
70 | 75 | ||
76 | /* This is how to tell if a multi-block reservation is "inplace" reserved: */ | ||
77 | static inline int gfs2_mb_reserved(struct gfs2_inode *ip) | ||
78 | { | ||
79 | if (ip->i_res && ip->i_res->rs_requested) | ||
80 | return 1; | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | /* This is how to tell if a multi-block reservation is in the rgrp tree: */ | ||
85 | static inline int gfs2_rs_active(struct gfs2_blkreserv *rs) | ||
86 | { | ||
87 | if (rs && rs->rs_bi) | ||
88 | return 1; | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static inline u32 gfs2_bi2rgd_blk(const struct gfs2_bitmap *bi, u32 blk) | ||
93 | { | ||
94 | return (bi->bi_start * GFS2_NBBY) + blk; | ||
95 | } | ||
96 | |||
97 | static inline u64 gfs2_rs_startblk(const struct gfs2_blkreserv *rs) | ||
98 | { | ||
99 | return gfs2_bi2rgd_blk(rs->rs_bi, rs->rs_biblk) + rs->rs_rgd->rd_data0; | ||
100 | } | ||
101 | |||
71 | #endif /* __RGRP_DOT_H__ */ | 102 | #endif /* __RGRP_DOT_H__ */ |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index f3d6bbfb32c5..fc3168f47a14 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -78,6 +78,8 @@ enum { | |||
78 | Opt_quota_quantum, | 78 | Opt_quota_quantum, |
79 | Opt_barrier, | 79 | Opt_barrier, |
80 | Opt_nobarrier, | 80 | Opt_nobarrier, |
81 | Opt_rgrplvb, | ||
82 | Opt_norgrplvb, | ||
81 | Opt_error, | 83 | Opt_error, |
82 | }; | 84 | }; |
83 | 85 | ||
@@ -115,6 +117,8 @@ static const match_table_t tokens = { | |||
115 | {Opt_quota_quantum, "quota_quantum=%d"}, | 117 | {Opt_quota_quantum, "quota_quantum=%d"}, |
116 | {Opt_barrier, "barrier"}, | 118 | {Opt_barrier, "barrier"}, |
117 | {Opt_nobarrier, "nobarrier"}, | 119 | {Opt_nobarrier, "nobarrier"}, |
120 | {Opt_rgrplvb, "rgrplvb"}, | ||
121 | {Opt_norgrplvb, "norgrplvb"}, | ||
118 | {Opt_error, NULL} | 122 | {Opt_error, NULL} |
119 | }; | 123 | }; |
120 | 124 | ||
@@ -267,6 +271,12 @@ int gfs2_mount_args(struct gfs2_args *args, char *options) | |||
267 | case Opt_nobarrier: | 271 | case Opt_nobarrier: |
268 | args->ar_nobarrier = 1; | 272 | args->ar_nobarrier = 1; |
269 | break; | 273 | break; |
274 | case Opt_rgrplvb: | ||
275 | args->ar_rgrplvb = 1; | ||
276 | break; | ||
277 | case Opt_norgrplvb: | ||
278 | args->ar_rgrplvb = 0; | ||
279 | break; | ||
270 | case Opt_error: | 280 | case Opt_error: |
271 | default: | 281 | default: |
272 | printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o); | 282 | printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o); |
@@ -1381,6 +1391,8 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) | |||
1381 | seq_printf(s, ",nobarrier"); | 1391 | seq_printf(s, ",nobarrier"); |
1382 | if (test_bit(SDF_DEMOTE, &sdp->sd_flags)) | 1392 | if (test_bit(SDF_DEMOTE, &sdp->sd_flags)) |
1383 | seq_printf(s, ",demote_interface_used"); | 1393 | seq_printf(s, ",demote_interface_used"); |
1394 | if (args->ar_rgrplvb) | ||
1395 | seq_printf(s, ",rgrplvb"); | ||
1384 | return 0; | 1396 | return 0; |
1385 | } | 1397 | } |
1386 | 1398 | ||
@@ -1401,7 +1413,6 @@ static void gfs2_final_release_pages(struct gfs2_inode *ip) | |||
1401 | static int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 1413 | static int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
1402 | { | 1414 | { |
1403 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1415 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1404 | struct gfs2_qadata *qa; | ||
1405 | struct gfs2_rgrpd *rgd; | 1416 | struct gfs2_rgrpd *rgd; |
1406 | struct gfs2_holder gh; | 1417 | struct gfs2_holder gh; |
1407 | int error; | 1418 | int error; |
@@ -1411,13 +1422,13 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
1411 | return -EIO; | 1422 | return -EIO; |
1412 | } | 1423 | } |
1413 | 1424 | ||
1414 | qa = gfs2_qadata_get(ip); | 1425 | error = gfs2_rindex_update(sdp); |
1415 | if (!qa) | 1426 | if (error) |
1416 | return -ENOMEM; | 1427 | return error; |
1417 | 1428 | ||
1418 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1429 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
1419 | if (error) | 1430 | if (error) |
1420 | goto out; | 1431 | return error; |
1421 | 1432 | ||
1422 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1); | 1433 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1); |
1423 | if (!rgd) { | 1434 | if (!rgd) { |
@@ -1445,8 +1456,6 @@ out_rg_gunlock: | |||
1445 | gfs2_glock_dq_uninit(&gh); | 1456 | gfs2_glock_dq_uninit(&gh); |
1446 | out_qs: | 1457 | out_qs: |
1447 | gfs2_quota_unhold(ip); | 1458 | gfs2_quota_unhold(ip); |
1448 | out: | ||
1449 | gfs2_qadata_put(ip); | ||
1450 | return error; | 1459 | return error; |
1451 | } | 1460 | } |
1452 | 1461 | ||
@@ -1547,6 +1556,9 @@ out_truncate: | |||
1547 | 1556 | ||
1548 | out_unlock: | 1557 | out_unlock: |
1549 | /* Error path for case 1 */ | 1558 | /* Error path for case 1 */ |
1559 | if (gfs2_rs_active(ip->i_res)) | ||
1560 | gfs2_rs_deltree(ip->i_res); | ||
1561 | |||
1550 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) | 1562 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) |
1551 | gfs2_glock_dq(&ip->i_iopen_gh); | 1563 | gfs2_glock_dq(&ip->i_iopen_gh); |
1552 | gfs2_holder_uninit(&ip->i_iopen_gh); | 1564 | gfs2_holder_uninit(&ip->i_iopen_gh); |
@@ -1556,6 +1568,7 @@ out_unlock: | |||
1556 | out: | 1568 | out: |
1557 | /* Case 3 starts here */ | 1569 | /* Case 3 starts here */ |
1558 | truncate_inode_pages(&inode->i_data, 0); | 1570 | truncate_inode_pages(&inode->i_data, 0); |
1571 | gfs2_rs_delete(ip); | ||
1559 | clear_inode(inode); | 1572 | clear_inode(inode); |
1560 | gfs2_dir_hash_inval(ip); | 1573 | gfs2_dir_hash_inval(ip); |
1561 | ip->i_gl->gl_object = NULL; | 1574 | ip->i_gl->gl_object = NULL; |
@@ -1578,6 +1591,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb) | |||
1578 | ip->i_flags = 0; | 1591 | ip->i_flags = 0; |
1579 | ip->i_gl = NULL; | 1592 | ip->i_gl = NULL; |
1580 | ip->i_rgd = NULL; | 1593 | ip->i_rgd = NULL; |
1594 | ip->i_res = NULL; | ||
1581 | } | 1595 | } |
1582 | return &ip->i_inode; | 1596 | return &ip->i_inode; |
1583 | } | 1597 | } |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 73ecc34c4342..8056b7b7238e 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -276,7 +276,15 @@ static struct attribute *gfs2_attrs[] = { | |||
276 | NULL, | 276 | NULL, |
277 | }; | 277 | }; |
278 | 278 | ||
279 | static void gfs2_sbd_release(struct kobject *kobj) | ||
280 | { | ||
281 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | ||
282 | |||
283 | kfree(sdp); | ||
284 | } | ||
285 | |||
279 | static struct kobj_type gfs2_ktype = { | 286 | static struct kobj_type gfs2_ktype = { |
287 | .release = gfs2_sbd_release, | ||
280 | .default_attrs = gfs2_attrs, | 288 | .default_attrs = gfs2_attrs, |
281 | .sysfs_ops = &gfs2_attr_ops, | 289 | .sysfs_ops = &gfs2_attr_ops, |
282 | }; | 290 | }; |
@@ -583,6 +591,7 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
583 | char ro[20]; | 591 | char ro[20]; |
584 | char spectator[20]; | 592 | char spectator[20]; |
585 | char *envp[] = { ro, spectator, NULL }; | 593 | char *envp[] = { ro, spectator, NULL }; |
594 | int sysfs_frees_sdp = 0; | ||
586 | 595 | ||
587 | sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0); | 596 | sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0); |
588 | sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); | 597 | sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); |
@@ -591,8 +600,10 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
591 | error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, | 600 | error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, |
592 | "%s", sdp->sd_table_name); | 601 | "%s", sdp->sd_table_name); |
593 | if (error) | 602 | if (error) |
594 | goto fail; | 603 | goto fail_reg; |
595 | 604 | ||
605 | sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling | ||
606 | function gfs2_sbd_release. */ | ||
596 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); | 607 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); |
597 | if (error) | 608 | if (error) |
598 | goto fail_reg; | 609 | goto fail_reg; |
@@ -615,9 +626,13 @@ fail_lock_module: | |||
615 | fail_tune: | 626 | fail_tune: |
616 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 627 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
617 | fail_reg: | 628 | fail_reg: |
618 | kobject_put(&sdp->sd_kobj); | 629 | free_percpu(sdp->sd_lkstats); |
619 | fail: | ||
620 | fs_err(sdp, "error %d adding sysfs files", error); | 630 | fs_err(sdp, "error %d adding sysfs files", error); |
631 | if (sysfs_frees_sdp) | ||
632 | kobject_put(&sdp->sd_kobj); | ||
633 | else | ||
634 | kfree(sdp); | ||
635 | sb->s_fs_info = NULL; | ||
621 | return error; | 636 | return error; |
622 | } | 637 | } |
623 | 638 | ||
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index 1b8b81588199..a25c252fe412 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/ktime.h> | 14 | #include <linux/ktime.h> |
15 | #include "incore.h" | 15 | #include "incore.h" |
16 | #include "glock.h" | 16 | #include "glock.h" |
17 | #include "rgrp.h" | ||
17 | 18 | ||
18 | #define dlm_state_name(nn) { DLM_LOCK_##nn, #nn } | 19 | #define dlm_state_name(nn) { DLM_LOCK_##nn, #nn } |
19 | #define glock_trace_name(x) __print_symbolic(x, \ | 20 | #define glock_trace_name(x) __print_symbolic(x, \ |
@@ -31,6 +32,17 @@ | |||
31 | { GFS2_BLKST_DINODE, "dinode" }, \ | 32 | { GFS2_BLKST_DINODE, "dinode" }, \ |
32 | { GFS2_BLKST_UNLINKED, "unlinked" }) | 33 | { GFS2_BLKST_UNLINKED, "unlinked" }) |
33 | 34 | ||
35 | #define TRACE_RS_DELETE 0 | ||
36 | #define TRACE_RS_TREEDEL 1 | ||
37 | #define TRACE_RS_INSERT 2 | ||
38 | #define TRACE_RS_CLAIM 3 | ||
39 | |||
40 | #define rs_func_name(x) __print_symbolic(x, \ | ||
41 | { 0, "del " }, \ | ||
42 | { 1, "tdel" }, \ | ||
43 | { 2, "ins " }, \ | ||
44 | { 3, "clm " }) | ||
45 | |||
34 | #define show_glock_flags(flags) __print_flags(flags, "", \ | 46 | #define show_glock_flags(flags) __print_flags(flags, "", \ |
35 | {(1UL << GLF_LOCK), "l" }, \ | 47 | {(1UL << GLF_LOCK), "l" }, \ |
36 | {(1UL << GLF_DEMOTE), "D" }, \ | 48 | {(1UL << GLF_DEMOTE), "D" }, \ |
@@ -470,6 +482,7 @@ TRACE_EVENT(gfs2_block_alloc, | |||
470 | __field( u8, block_state ) | 482 | __field( u8, block_state ) |
471 | __field( u64, rd_addr ) | 483 | __field( u64, rd_addr ) |
472 | __field( u32, rd_free_clone ) | 484 | __field( u32, rd_free_clone ) |
485 | __field( u32, rd_reserved ) | ||
473 | ), | 486 | ), |
474 | 487 | ||
475 | TP_fast_assign( | 488 | TP_fast_assign( |
@@ -480,16 +493,58 @@ TRACE_EVENT(gfs2_block_alloc, | |||
480 | __entry->block_state = block_state; | 493 | __entry->block_state = block_state; |
481 | __entry->rd_addr = rgd->rd_addr; | 494 | __entry->rd_addr = rgd->rd_addr; |
482 | __entry->rd_free_clone = rgd->rd_free_clone; | 495 | __entry->rd_free_clone = rgd->rd_free_clone; |
496 | __entry->rd_reserved = rgd->rd_reserved; | ||
483 | ), | 497 | ), |
484 | 498 | ||
485 | TP_printk("%u,%u bmap %llu alloc %llu/%lu %s rg:%llu rf:%u", | 499 | TP_printk("%u,%u bmap %llu alloc %llu/%lu %s rg:%llu rf:%u rr:%lu", |
486 | MAJOR(__entry->dev), MINOR(__entry->dev), | 500 | MAJOR(__entry->dev), MINOR(__entry->dev), |
487 | (unsigned long long)__entry->inum, | 501 | (unsigned long long)__entry->inum, |
488 | (unsigned long long)__entry->start, | 502 | (unsigned long long)__entry->start, |
489 | (unsigned long)__entry->len, | 503 | (unsigned long)__entry->len, |
490 | block_state_name(__entry->block_state), | 504 | block_state_name(__entry->block_state), |
491 | (unsigned long long)__entry->rd_addr, | 505 | (unsigned long long)__entry->rd_addr, |
492 | __entry->rd_free_clone) | 506 | __entry->rd_free_clone, (unsigned long)__entry->rd_reserved) |
507 | ); | ||
508 | |||
509 | /* Keep track of multi-block reservations as they are allocated/freed */ | ||
510 | TRACE_EVENT(gfs2_rs, | ||
511 | |||
512 | TP_PROTO(const struct gfs2_inode *ip, const struct gfs2_blkreserv *rs, | ||
513 | u8 func), | ||
514 | |||
515 | TP_ARGS(ip, rs, func), | ||
516 | |||
517 | TP_STRUCT__entry( | ||
518 | __field( dev_t, dev ) | ||
519 | __field( u64, rd_addr ) | ||
520 | __field( u32, rd_free_clone ) | ||
521 | __field( u32, rd_reserved ) | ||
522 | __field( u64, inum ) | ||
523 | __field( u64, start ) | ||
524 | __field( u32, free ) | ||
525 | __field( u8, func ) | ||
526 | ), | ||
527 | |||
528 | TP_fast_assign( | ||
529 | __entry->dev = rs->rs_rgd ? rs->rs_rgd->rd_sbd->sd_vfs->s_dev : 0; | ||
530 | __entry->rd_addr = rs->rs_rgd ? rs->rs_rgd->rd_addr : 0; | ||
531 | __entry->rd_free_clone = rs->rs_rgd ? rs->rs_rgd->rd_free_clone : 0; | ||
532 | __entry->rd_reserved = rs->rs_rgd ? rs->rs_rgd->rd_reserved : 0; | ||
533 | __entry->inum = ip ? ip->i_no_addr : 0; | ||
534 | __entry->start = gfs2_rs_startblk(rs); | ||
535 | __entry->free = rs->rs_free; | ||
536 | __entry->func = func; | ||
537 | ), | ||
538 | |||
539 | TP_printk("%u,%u bmap %llu resrv %llu rg:%llu rf:%lu rr:%lu %s " | ||
540 | "f:%lu", | ||
541 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
542 | (unsigned long long)__entry->inum, | ||
543 | (unsigned long long)__entry->start, | ||
544 | (unsigned long long)__entry->rd_addr, | ||
545 | (unsigned long)__entry->rd_free_clone, | ||
546 | (unsigned long)__entry->rd_reserved, | ||
547 | rs_func_name(__entry->func), (unsigned long)__entry->free) | ||
493 | ); | 548 | ); |
494 | 549 | ||
495 | #endif /* _TRACE_GFS2_H */ | 550 | #endif /* _TRACE_GFS2_H */ |
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h index 125d4572e1c0..41f42cdccbb8 100644 --- a/fs/gfs2/trans.h +++ b/fs/gfs2/trans.h | |||
@@ -31,7 +31,7 @@ struct gfs2_glock; | |||
31 | static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip) | 31 | static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip) |
32 | { | 32 | { |
33 | const struct gfs2_blkreserv *rs = ip->i_res; | 33 | const struct gfs2_blkreserv *rs = ip->i_res; |
34 | if (rs->rs_requested < ip->i_rgd->rd_length) | 34 | if (rs && rs->rs_requested < ip->i_rgd->rd_length) |
35 | return rs->rs_requested + 1; | 35 | return rs->rs_requested + 1; |
36 | return ip->i_rgd->rd_length; | 36 | return ip->i_rgd->rd_length; |
37 | } | 37 | } |
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 3586b0dd6aa7..80535739ac7b 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -79,23 +79,19 @@ int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
79 | const char *type, const char *function, | 79 | const char *type, const char *function, |
80 | char *file, unsigned int line); | 80 | char *file, unsigned int line); |
81 | 81 | ||
82 | static inline int gfs2_meta_check_i(struct gfs2_sbd *sdp, | 82 | static inline int gfs2_meta_check(struct gfs2_sbd *sdp, |
83 | struct buffer_head *bh, | 83 | struct buffer_head *bh) |
84 | const char *function, | ||
85 | char *file, unsigned int line) | ||
86 | { | 84 | { |
87 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
88 | u32 magic = be32_to_cpu(mh->mh_magic); | 86 | u32 magic = be32_to_cpu(mh->mh_magic); |
89 | if (unlikely(magic != GFS2_MAGIC)) | 87 | if (unlikely(magic != GFS2_MAGIC)) { |
90 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 88 | printk(KERN_ERR "GFS2: Magic number missing at %llu\n", |
91 | file, line); | 89 | (unsigned long long)bh->b_blocknr); |
90 | return -EIO; | ||
91 | } | ||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | #define gfs2_meta_check(sdp, bh) \ | ||
96 | gfs2_meta_check_i((sdp), (bh), __func__, __FILE__, __LINE__) | ||
97 | |||
98 | |||
99 | int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, | 95 | int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, |
100 | u16 type, u16 t, | 96 | u16 type, u16 t, |
101 | const char *function, | 97 | const char *function, |
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 927f4df874ae..27a0b4a901f5 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -325,12 +325,11 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
325 | struct gfs2_ea_header *ea, | 325 | struct gfs2_ea_header *ea, |
326 | struct gfs2_ea_header *prev, int leave) | 326 | struct gfs2_ea_header *prev, int leave) |
327 | { | 327 | { |
328 | struct gfs2_qadata *qa; | ||
329 | int error; | 328 | int error; |
330 | 329 | ||
331 | qa = gfs2_qadata_get(ip); | 330 | error = gfs2_rindex_update(GFS2_SB(&ip->i_inode)); |
332 | if (!qa) | 331 | if (error) |
333 | return -ENOMEM; | 332 | return error; |
334 | 333 | ||
335 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 334 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
336 | if (error) | 335 | if (error) |
@@ -340,7 +339,6 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
340 | 339 | ||
341 | gfs2_quota_unhold(ip); | 340 | gfs2_quota_unhold(ip); |
342 | out_alloc: | 341 | out_alloc: |
343 | gfs2_qadata_put(ip); | ||
344 | return error; | 342 | return error; |
345 | } | 343 | } |
346 | 344 | ||
@@ -713,17 +711,16 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
713 | unsigned int blks, | 711 | unsigned int blks, |
714 | ea_skeleton_call_t skeleton_call, void *private) | 712 | ea_skeleton_call_t skeleton_call, void *private) |
715 | { | 713 | { |
716 | struct gfs2_qadata *qa; | ||
717 | struct buffer_head *dibh; | 714 | struct buffer_head *dibh; |
718 | int error; | 715 | int error; |
719 | 716 | ||
720 | qa = gfs2_qadata_get(ip); | 717 | error = gfs2_rindex_update(GFS2_SB(&ip->i_inode)); |
721 | if (!qa) | 718 | if (error) |
722 | return -ENOMEM; | 719 | return error; |
723 | 720 | ||
724 | error = gfs2_quota_lock_check(ip); | 721 | error = gfs2_quota_lock_check(ip); |
725 | if (error) | 722 | if (error) |
726 | goto out; | 723 | return error; |
727 | 724 | ||
728 | error = gfs2_inplace_reserve(ip, blks); | 725 | error = gfs2_inplace_reserve(ip, blks); |
729 | if (error) | 726 | if (error) |
@@ -753,8 +750,6 @@ out_ipres: | |||
753 | gfs2_inplace_release(ip); | 750 | gfs2_inplace_release(ip); |
754 | out_gunlock_q: | 751 | out_gunlock_q: |
755 | gfs2_quota_unlock(ip); | 752 | gfs2_quota_unlock(ip); |
756 | out: | ||
757 | gfs2_qadata_put(ip); | ||
758 | return error; | 753 | return error; |
759 | } | 754 | } |
760 | 755 | ||
@@ -1494,16 +1489,15 @@ out_gunlock: | |||
1494 | 1489 | ||
1495 | int gfs2_ea_dealloc(struct gfs2_inode *ip) | 1490 | int gfs2_ea_dealloc(struct gfs2_inode *ip) |
1496 | { | 1491 | { |
1497 | struct gfs2_qadata *qa; | ||
1498 | int error; | 1492 | int error; |
1499 | 1493 | ||
1500 | qa = gfs2_qadata_get(ip); | 1494 | error = gfs2_rindex_update(GFS2_SB(&ip->i_inode)); |
1501 | if (!qa) | 1495 | if (error) |
1502 | return -ENOMEM; | 1496 | return error; |
1503 | 1497 | ||
1504 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1498 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
1505 | if (error) | 1499 | if (error) |
1506 | goto out_alloc; | 1500 | return error; |
1507 | 1501 | ||
1508 | error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); | 1502 | error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); |
1509 | if (error) | 1503 | if (error) |
@@ -1519,8 +1513,6 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip) | |||
1519 | 1513 | ||
1520 | out_quota: | 1514 | out_quota: |
1521 | gfs2_quota_unhold(ip); | 1515 | gfs2_quota_unhold(ip); |
1522 | out_alloc: | ||
1523 | gfs2_qadata_put(ip); | ||
1524 | return error; | 1516 | return error; |
1525 | } | 1517 | } |
1526 | 1518 | ||