diff options
-rw-r--r-- | MAINTAINERS | 4 | ||||
-rw-r--r-- | fs/gfs2/acl.c | 6 | ||||
-rw-r--r-- | fs/gfs2/aops.c | 6 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 101 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 47 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 4 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 18 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 62 | ||||
-rw-r--r-- | fs/gfs2/quota.h | 8 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 20 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 3 | ||||
-rw-r--r-- | fs/gfs2/xattr.c | 2 |
13 files changed, 186 insertions, 97 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 38579ac581ce..17631e6c0151 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4337,10 +4337,10 @@ F: scripts/get_maintainer.pl | |||
4337 | 4337 | ||
4338 | GFS2 FILE SYSTEM | 4338 | GFS2 FILE SYSTEM |
4339 | M: Steven Whitehouse <swhiteho@redhat.com> | 4339 | M: Steven Whitehouse <swhiteho@redhat.com> |
4340 | M: Bob Peterson <rpeterso@redhat.com> | ||
4340 | L: cluster-devel@redhat.com | 4341 | L: cluster-devel@redhat.com |
4341 | W: http://sources.redhat.com/cluster/ | 4342 | W: http://sources.redhat.com/cluster/ |
4342 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes.git | 4343 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git |
4343 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw.git | ||
4344 | S: Supported | 4344 | S: Supported |
4345 | F: Documentation/filesystems/gfs2*.txt | 4345 | F: Documentation/filesystems/gfs2*.txt |
4346 | F: fs/gfs2/ | 4346 | F: fs/gfs2/ |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 7b3143064af1..1be3b061c05c 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -110,11 +110,7 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) | |||
110 | error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS); | 110 | error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS); |
111 | if (error) | 111 | if (error) |
112 | goto out; | 112 | goto out; |
113 | 113 | set_cached_acl(inode, type, acl); | |
114 | if (acl) | ||
115 | set_cached_acl(inode, type, acl); | ||
116 | else | ||
117 | forget_cached_acl(inode, type); | ||
118 | out: | 114 | out: |
119 | kfree(data); | 115 | kfree(data); |
120 | return error; | 116 | return error; |
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index fe6634d25d1d..a6e6990aea39 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -671,12 +671,12 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
671 | 671 | ||
672 | if (alloc_required) { | 672 | if (alloc_required) { |
673 | struct gfs2_alloc_parms ap = { .aflags = 0, }; | 673 | struct gfs2_alloc_parms ap = { .aflags = 0, }; |
674 | error = gfs2_quota_lock_check(ip); | 674 | requested = data_blocks + ind_blocks; |
675 | ap.target = requested; | ||
676 | error = gfs2_quota_lock_check(ip, &ap); | ||
675 | if (error) | 677 | if (error) |
676 | goto out_unlock; | 678 | goto out_unlock; |
677 | 679 | ||
678 | requested = data_blocks + ind_blocks; | ||
679 | ap.target = requested; | ||
680 | error = gfs2_inplace_reserve(ip, &ap); | 680 | error = gfs2_inplace_reserve(ip, &ap); |
681 | if (error) | 681 | if (error) |
682 | goto out_qunlock; | 682 | goto out_qunlock; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index f0b945ab853e..61296ecbd0e2 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -1224,7 +1224,7 @@ static int do_grow(struct inode *inode, u64 size) | |||
1224 | 1224 | ||
1225 | if (gfs2_is_stuffed(ip) && | 1225 | if (gfs2_is_stuffed(ip) && |
1226 | (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) { | 1226 | (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) { |
1227 | error = gfs2_quota_lock_check(ip); | 1227 | error = gfs2_quota_lock_check(ip, &ap); |
1228 | if (error) | 1228 | if (error) |
1229 | return error; | 1229 | return error; |
1230 | 1230 | ||
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index f6fc412b1100..8ec43ab5babf 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -428,11 +428,11 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
428 | if (ret) | 428 | if (ret) |
429 | goto out_unlock; | 429 | goto out_unlock; |
430 | 430 | ||
431 | ret = gfs2_quota_lock_check(ip); | ||
432 | if (ret) | ||
433 | goto out_unlock; | ||
434 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); | 431 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); |
435 | ap.target = data_blocks + ind_blocks; | 432 | ap.target = data_blocks + ind_blocks; |
433 | ret = gfs2_quota_lock_check(ip, &ap); | ||
434 | if (ret) | ||
435 | goto out_unlock; | ||
436 | ret = gfs2_inplace_reserve(ip, &ap); | 436 | ret = gfs2_inplace_reserve(ip, &ap); |
437 | if (ret) | 437 | if (ret) |
438 | goto out_quota_unlock; | 438 | goto out_quota_unlock; |
@@ -764,22 +764,30 @@ out: | |||
764 | brelse(dibh); | 764 | brelse(dibh); |
765 | return error; | 765 | return error; |
766 | } | 766 | } |
767 | 767 | /** | |
768 | static void calc_max_reserv(struct gfs2_inode *ip, loff_t max, loff_t *len, | 768 | * calc_max_reserv() - Reverse of write_calc_reserv. Given a number of |
769 | unsigned int *data_blocks, unsigned int *ind_blocks) | 769 | * blocks, determine how many bytes can be written. |
770 | * @ip: The inode in question. | ||
771 | * @len: Max cap of bytes. What we return in *len must be <= this. | ||
772 | * @data_blocks: Compute and return the number of data blocks needed | ||
773 | * @ind_blocks: Compute and return the number of indirect blocks needed | ||
774 | * @max_blocks: The total blocks available to work with. | ||
775 | * | ||
776 | * Returns: void, but @len, @data_blocks and @ind_blocks are filled in. | ||
777 | */ | ||
778 | static void calc_max_reserv(struct gfs2_inode *ip, loff_t *len, | ||
779 | unsigned int *data_blocks, unsigned int *ind_blocks, | ||
780 | unsigned int max_blocks) | ||
770 | { | 781 | { |
782 | loff_t max = *len; | ||
771 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 783 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
772 | unsigned int max_blocks = ip->i_rgd->rd_free_clone; | ||
773 | unsigned int tmp, max_data = max_blocks - 3 * (sdp->sd_max_height - 1); | 784 | unsigned int tmp, max_data = max_blocks - 3 * (sdp->sd_max_height - 1); |
774 | 785 | ||
775 | for (tmp = max_data; tmp > sdp->sd_diptrs;) { | 786 | for (tmp = max_data; tmp > sdp->sd_diptrs;) { |
776 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); | 787 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); |
777 | max_data -= tmp; | 788 | max_data -= tmp; |
778 | } | 789 | } |
779 | /* This calculation isn't the exact reverse of gfs2_write_calc_reserve, | 790 | |
780 | so it might end up with fewer data blocks */ | ||
781 | if (max_data <= *data_blocks) | ||
782 | return; | ||
783 | *data_blocks = max_data; | 791 | *data_blocks = max_data; |
784 | *ind_blocks = max_blocks - max_data; | 792 | *ind_blocks = max_blocks - max_data; |
785 | *len = ((loff_t)max_data - 3) << sdp->sd_sb.sb_bsize_shift; | 793 | *len = ((loff_t)max_data - 3) << sdp->sd_sb.sb_bsize_shift; |
@@ -796,7 +804,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
796 | struct gfs2_inode *ip = GFS2_I(inode); | 804 | struct gfs2_inode *ip = GFS2_I(inode); |
797 | struct gfs2_alloc_parms ap = { .aflags = 0, }; | 805 | struct gfs2_alloc_parms ap = { .aflags = 0, }; |
798 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 806 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
799 | loff_t bytes, max_bytes; | 807 | loff_t bytes, max_bytes, max_blks = UINT_MAX; |
800 | int error; | 808 | int error; |
801 | const loff_t pos = offset; | 809 | const loff_t pos = offset; |
802 | const loff_t count = len; | 810 | const loff_t count = len; |
@@ -818,6 +826,9 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
818 | 826 | ||
819 | gfs2_size_hint(file, offset, len); | 827 | gfs2_size_hint(file, offset, len); |
820 | 828 | ||
829 | gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks); | ||
830 | ap.min_target = data_blocks + ind_blocks; | ||
831 | |||
821 | while (len > 0) { | 832 | while (len > 0) { |
822 | if (len < bytes) | 833 | if (len < bytes) |
823 | bytes = len; | 834 | bytes = len; |
@@ -826,27 +837,41 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
826 | offset += bytes; | 837 | offset += bytes; |
827 | continue; | 838 | continue; |
828 | } | 839 | } |
829 | error = gfs2_quota_lock_check(ip); | 840 | |
841 | /* We need to determine how many bytes we can actually | ||
842 | * fallocate without exceeding quota or going over the | ||
843 | * end of the fs. We start off optimistically by assuming | ||
844 | * we can write max_bytes */ | ||
845 | max_bytes = (len > max_chunk_size) ? max_chunk_size : len; | ||
846 | |||
847 | /* Since max_bytes is most likely a theoretical max, we | ||
848 | * calculate a more realistic 'bytes' to serve as a good | ||
849 | * starting point for the number of bytes we may be able | ||
850 | * to write */ | ||
851 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); | ||
852 | ap.target = data_blocks + ind_blocks; | ||
853 | |||
854 | error = gfs2_quota_lock_check(ip, &ap); | ||
830 | if (error) | 855 | if (error) |
831 | return error; | 856 | return error; |
832 | retry: | 857 | /* ap.allowed tells us how many blocks quota will allow |
833 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); | 858 | * us to write. Check if this reduces max_blks */ |
859 | if (ap.allowed && ap.allowed < max_blks) | ||
860 | max_blks = ap.allowed; | ||
834 | 861 | ||
835 | ap.target = data_blocks + ind_blocks; | ||
836 | error = gfs2_inplace_reserve(ip, &ap); | 862 | error = gfs2_inplace_reserve(ip, &ap); |
837 | if (error) { | 863 | if (error) |
838 | if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { | ||
839 | bytes >>= 1; | ||
840 | bytes &= bsize_mask; | ||
841 | if (bytes == 0) | ||
842 | bytes = sdp->sd_sb.sb_bsize; | ||
843 | goto retry; | ||
844 | } | ||
845 | goto out_qunlock; | 864 | goto out_qunlock; |
846 | } | 865 | |
847 | max_bytes = bytes; | 866 | /* check if the selected rgrp limits our max_blks further */ |
848 | calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len, | 867 | if (ap.allowed && ap.allowed < max_blks) |
849 | &max_bytes, &data_blocks, &ind_blocks); | 868 | max_blks = ap.allowed; |
869 | |||
870 | /* Almost done. Calculate bytes that can be written using | ||
871 | * max_blks. We also recompute max_bytes, data_blocks and | ||
872 | * ind_blocks */ | ||
873 | calc_max_reserv(ip, &max_bytes, &data_blocks, | ||
874 | &ind_blocks, max_blks); | ||
850 | 875 | ||
851 | rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + | 876 | rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + |
852 | RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks); | 877 | RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks); |
@@ -930,6 +955,22 @@ out_uninit: | |||
930 | return ret; | 955 | return ret; |
931 | } | 956 | } |
932 | 957 | ||
958 | static ssize_t gfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
959 | struct file *out, loff_t *ppos, | ||
960 | size_t len, unsigned int flags) | ||
961 | { | ||
962 | int error; | ||
963 | struct gfs2_inode *ip = GFS2_I(out->f_mapping->host); | ||
964 | |||
965 | error = gfs2_rs_alloc(ip); | ||
966 | if (error) | ||
967 | return (ssize_t)error; | ||
968 | |||
969 | gfs2_size_hint(out, *ppos, len); | ||
970 | |||
971 | return iter_file_splice_write(pipe, out, ppos, len, flags); | ||
972 | } | ||
973 | |||
933 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM | 974 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM |
934 | 975 | ||
935 | /** | 976 | /** |
@@ -1076,7 +1117,7 @@ const struct file_operations gfs2_file_fops = { | |||
1076 | .lock = gfs2_lock, | 1117 | .lock = gfs2_lock, |
1077 | .flock = gfs2_flock, | 1118 | .flock = gfs2_flock, |
1078 | .splice_read = generic_file_splice_read, | 1119 | .splice_read = generic_file_splice_read, |
1079 | .splice_write = iter_file_splice_write, | 1120 | .splice_write = gfs2_file_splice_write, |
1080 | .setlease = simple_nosetlease, | 1121 | .setlease = simple_nosetlease, |
1081 | .fallocate = gfs2_fallocate, | 1122 | .fallocate = gfs2_fallocate, |
1082 | }; | 1123 | }; |
@@ -1106,7 +1147,7 @@ const struct file_operations gfs2_file_fops_nolock = { | |||
1106 | .release = gfs2_release, | 1147 | .release = gfs2_release, |
1107 | .fsync = gfs2_fsync, | 1148 | .fsync = gfs2_fsync, |
1108 | .splice_read = generic_file_splice_read, | 1149 | .splice_read = generic_file_splice_read, |
1109 | .splice_write = iter_file_splice_write, | 1150 | .splice_write = gfs2_file_splice_write, |
1110 | .setlease = generic_setlease, | 1151 | .setlease = generic_setlease, |
1111 | .fallocate = gfs2_fallocate, | 1152 | .fallocate = gfs2_fallocate, |
1112 | }; | 1153 | }; |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f42dffba056a..0fa8062f85a7 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -2047,34 +2047,41 @@ static const struct file_operations gfs2_sbstats_fops = { | |||
2047 | 2047 | ||
2048 | int gfs2_create_debugfs_file(struct gfs2_sbd *sdp) | 2048 | int gfs2_create_debugfs_file(struct gfs2_sbd *sdp) |
2049 | { | 2049 | { |
2050 | sdp->debugfs_dir = debugfs_create_dir(sdp->sd_table_name, gfs2_root); | 2050 | struct dentry *dent; |
2051 | if (!sdp->debugfs_dir) | 2051 | |
2052 | return -ENOMEM; | 2052 | dent = debugfs_create_dir(sdp->sd_table_name, gfs2_root); |
2053 | sdp->debugfs_dentry_glocks = debugfs_create_file("glocks", | 2053 | if (IS_ERR_OR_NULL(dent)) |
2054 | S_IFREG | S_IRUGO, | 2054 | goto fail; |
2055 | sdp->debugfs_dir, sdp, | 2055 | sdp->debugfs_dir = dent; |
2056 | &gfs2_glocks_fops); | 2056 | |
2057 | if (!sdp->debugfs_dentry_glocks) | 2057 | dent = debugfs_create_file("glocks", |
2058 | S_IFREG | S_IRUGO, | ||
2059 | sdp->debugfs_dir, sdp, | ||
2060 | &gfs2_glocks_fops); | ||
2061 | if (IS_ERR_OR_NULL(dent)) | ||
2058 | goto fail; | 2062 | goto fail; |
2063 | sdp->debugfs_dentry_glocks = dent; | ||
2059 | 2064 | ||
2060 | sdp->debugfs_dentry_glstats = debugfs_create_file("glstats", | 2065 | dent = debugfs_create_file("glstats", |
2061 | S_IFREG | S_IRUGO, | 2066 | S_IFREG | S_IRUGO, |
2062 | sdp->debugfs_dir, sdp, | 2067 | sdp->debugfs_dir, sdp, |
2063 | &gfs2_glstats_fops); | 2068 | &gfs2_glstats_fops); |
2064 | if (!sdp->debugfs_dentry_glstats) | 2069 | if (IS_ERR_OR_NULL(dent)) |
2065 | goto fail; | 2070 | goto fail; |
2071 | sdp->debugfs_dentry_glstats = dent; | ||
2066 | 2072 | ||
2067 | sdp->debugfs_dentry_sbstats = debugfs_create_file("sbstats", | 2073 | dent = debugfs_create_file("sbstats", |
2068 | S_IFREG | S_IRUGO, | 2074 | S_IFREG | S_IRUGO, |
2069 | sdp->debugfs_dir, sdp, | 2075 | sdp->debugfs_dir, sdp, |
2070 | &gfs2_sbstats_fops); | 2076 | &gfs2_sbstats_fops); |
2071 | if (!sdp->debugfs_dentry_sbstats) | 2077 | if (IS_ERR_OR_NULL(dent)) |
2072 | goto fail; | 2078 | goto fail; |
2079 | sdp->debugfs_dentry_sbstats = dent; | ||
2073 | 2080 | ||
2074 | return 0; | 2081 | return 0; |
2075 | fail: | 2082 | fail: |
2076 | gfs2_delete_debugfs_file(sdp); | 2083 | gfs2_delete_debugfs_file(sdp); |
2077 | return -ENOMEM; | 2084 | return dent ? PTR_ERR(dent) : -ENOMEM; |
2078 | } | 2085 | } |
2079 | 2086 | ||
2080 | void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp) | 2087 | void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp) |
@@ -2100,6 +2107,8 @@ void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp) | |||
2100 | int gfs2_register_debugfs(void) | 2107 | int gfs2_register_debugfs(void) |
2101 | { | 2108 | { |
2102 | gfs2_root = debugfs_create_dir("gfs2", NULL); | 2109 | gfs2_root = debugfs_create_dir("gfs2", NULL); |
2110 | if (IS_ERR(gfs2_root)) | ||
2111 | return PTR_ERR(gfs2_root); | ||
2103 | return gfs2_root ? 0 : -ENOMEM; | 2112 | return gfs2_root ? 0 : -ENOMEM; |
2104 | } | 2113 | } |
2105 | 2114 | ||
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 7a2dbbc0d634..58b75abf6ab2 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -301,8 +301,10 @@ struct gfs2_blkreserv { | |||
301 | * to the allocation code. | 301 | * to the allocation code. |
302 | */ | 302 | */ |
303 | struct gfs2_alloc_parms { | 303 | struct gfs2_alloc_parms { |
304 | u32 target; | 304 | u64 target; |
305 | u32 min_target; | ||
305 | u32 aflags; | 306 | u32 aflags; |
307 | u64 allowed; | ||
306 | }; | 308 | }; |
307 | 309 | ||
308 | enum { | 310 | enum { |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 73c72253faac..08bc84d7e768 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -382,7 +382,7 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks) | |||
382 | struct gfs2_alloc_parms ap = { .target = *dblocks, .aflags = flags, }; | 382 | struct gfs2_alloc_parms ap = { .target = *dblocks, .aflags = flags, }; |
383 | int error; | 383 | int error; |
384 | 384 | ||
385 | error = gfs2_quota_lock_check(ip); | 385 | error = gfs2_quota_lock_check(ip, &ap); |
386 | if (error) | 386 | if (error) |
387 | goto out; | 387 | goto out; |
388 | 388 | ||
@@ -525,7 +525,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
525 | int error; | 525 | int error; |
526 | 526 | ||
527 | if (da->nr_blocks) { | 527 | if (da->nr_blocks) { |
528 | error = gfs2_quota_lock_check(dip); | 528 | error = gfs2_quota_lock_check(dip, &ap); |
529 | if (error) | 529 | if (error) |
530 | goto fail_quota_locks; | 530 | goto fail_quota_locks; |
531 | 531 | ||
@@ -953,7 +953,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
953 | 953 | ||
954 | if (da.nr_blocks) { | 954 | if (da.nr_blocks) { |
955 | struct gfs2_alloc_parms ap = { .target = da.nr_blocks, }; | 955 | struct gfs2_alloc_parms ap = { .target = da.nr_blocks, }; |
956 | error = gfs2_quota_lock_check(dip); | 956 | error = gfs2_quota_lock_check(dip, &ap); |
957 | if (error) | 957 | if (error) |
958 | goto out_gunlock; | 958 | goto out_gunlock; |
959 | 959 | ||
@@ -1470,7 +1470,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1470 | 1470 | ||
1471 | if (da.nr_blocks) { | 1471 | if (da.nr_blocks) { |
1472 | struct gfs2_alloc_parms ap = { .target = da.nr_blocks, }; | 1472 | struct gfs2_alloc_parms ap = { .target = da.nr_blocks, }; |
1473 | error = gfs2_quota_lock_check(ndip); | 1473 | error = gfs2_quota_lock_check(ndip, &ap); |
1474 | if (error) | 1474 | if (error) |
1475 | goto out_gunlock; | 1475 | goto out_gunlock; |
1476 | 1476 | ||
@@ -1669,6 +1669,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1669 | kuid_t ouid, nuid; | 1669 | kuid_t ouid, nuid; |
1670 | kgid_t ogid, ngid; | 1670 | kgid_t ogid, ngid; |
1671 | int error; | 1671 | int error; |
1672 | struct gfs2_alloc_parms ap; | ||
1672 | 1673 | ||
1673 | ouid = inode->i_uid; | 1674 | ouid = inode->i_uid; |
1674 | ogid = inode->i_gid; | 1675 | ogid = inode->i_gid; |
@@ -1696,9 +1697,11 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1696 | if (error) | 1697 | if (error) |
1697 | goto out; | 1698 | goto out; |
1698 | 1699 | ||
1700 | ap.target = gfs2_get_inode_blocks(&ip->i_inode); | ||
1701 | |||
1699 | if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) || | 1702 | if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) || |
1700 | !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) { | 1703 | !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) { |
1701 | error = gfs2_quota_check(ip, nuid, ngid); | 1704 | error = gfs2_quota_check(ip, nuid, ngid, &ap); |
1702 | if (error) | 1705 | if (error) |
1703 | goto out_gunlock_q; | 1706 | goto out_gunlock_q; |
1704 | } | 1707 | } |
@@ -1713,9 +1716,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1713 | 1716 | ||
1714 | if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) || | 1717 | if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) || |
1715 | !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) { | 1718 | !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) { |
1716 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); | 1719 | gfs2_quota_change(ip, -ap.target, ouid, ogid); |
1717 | gfs2_quota_change(ip, -blocks, ouid, ogid); | 1720 | gfs2_quota_change(ip, ap.target, nuid, ngid); |
1718 | gfs2_quota_change(ip, blocks, nuid, ngid); | ||
1719 | } | 1721 | } |
1720 | 1722 | ||
1721 | out_end_trans: | 1723 | out_end_trans: |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 3aa17d4d1cfc..5c27e48aa76f 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -923,6 +923,9 @@ restart: | |||
923 | if (error) | 923 | if (error) |
924 | return error; | 924 | return error; |
925 | 925 | ||
926 | if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) | ||
927 | force_refresh = FORCE; | ||
928 | |||
926 | qd->qd_qb = *(struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; | 929 | qd->qd_qb = *(struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; |
927 | 930 | ||
928 | if (force_refresh || qd->qd_qb.qb_magic != cpu_to_be32(GFS2_MAGIC)) { | 931 | if (force_refresh || qd->qd_qb.qb_magic != cpu_to_be32(GFS2_MAGIC)) { |
@@ -974,11 +977,8 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
974 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); | 977 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); |
975 | 978 | ||
976 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 979 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
977 | int force = NO_FORCE; | ||
978 | qd = ip->i_res->rs_qa_qd[x]; | 980 | qd = ip->i_res->rs_qa_qd[x]; |
979 | if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) | 981 | error = do_glock(qd, NO_FORCE, &ip->i_res->rs_qa_qd_ghs[x]); |
980 | force = FORCE; | ||
981 | error = do_glock(qd, force, &ip->i_res->rs_qa_qd_ghs[x]); | ||
982 | if (error) | 982 | if (error) |
983 | break; | 983 | break; |
984 | } | 984 | } |
@@ -1094,14 +1094,33 @@ static int print_message(struct gfs2_quota_data *qd, char *type) | |||
1094 | return 0; | 1094 | return 0; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | 1097 | /** |
1098 | * gfs2_quota_check - check if allocating new blocks will exceed quota | ||
1099 | * @ip: The inode for which this check is being performed | ||
1100 | * @uid: The uid to check against | ||
1101 | * @gid: The gid to check against | ||
1102 | * @ap: The allocation parameters. ap->target contains the requested | ||
1103 | * blocks. ap->min_target, if set, contains the minimum blks | ||
1104 | * requested. | ||
1105 | * | ||
1106 | * Returns: 0 on success. | ||
1107 | * min_req = ap->min_target ? ap->min_target : ap->target; | ||
1108 | * quota must allow atleast min_req blks for success and | ||
1109 | * ap->allowed is set to the number of blocks allowed | ||
1110 | * | ||
1111 | * -EDQUOT otherwise, quota violation. ap->allowed is set to number | ||
1112 | * of blocks available. | ||
1113 | */ | ||
1114 | int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, | ||
1115 | struct gfs2_alloc_parms *ap) | ||
1098 | { | 1116 | { |
1099 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1117 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1100 | struct gfs2_quota_data *qd; | 1118 | struct gfs2_quota_data *qd; |
1101 | s64 value; | 1119 | s64 value, warn, limit; |
1102 | unsigned int x; | 1120 | unsigned int x; |
1103 | int error = 0; | 1121 | int error = 0; |
1104 | 1122 | ||
1123 | ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */ | ||
1105 | if (!test_bit(GIF_QD_LOCKED, &ip->i_flags)) | 1124 | if (!test_bit(GIF_QD_LOCKED, &ip->i_flags)) |
1106 | return 0; | 1125 | return 0; |
1107 | 1126 | ||
@@ -1115,30 +1134,37 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
1115 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) | 1134 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) |
1116 | continue; | 1135 | continue; |
1117 | 1136 | ||
1137 | warn = (s64)be64_to_cpu(qd->qd_qb.qb_warn); | ||
1138 | limit = (s64)be64_to_cpu(qd->qd_qb.qb_limit); | ||
1118 | value = (s64)be64_to_cpu(qd->qd_qb.qb_value); | 1139 | value = (s64)be64_to_cpu(qd->qd_qb.qb_value); |
1119 | spin_lock(&qd_lock); | 1140 | spin_lock(&qd_lock); |
1120 | value += qd->qd_change; | 1141 | value += qd->qd_change; |
1121 | spin_unlock(&qd_lock); | 1142 | spin_unlock(&qd_lock); |
1122 | 1143 | ||
1123 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { | 1144 | if (limit > 0 && (limit - value) < ap->allowed) |
1124 | print_message(qd, "exceeded"); | 1145 | ap->allowed = limit - value; |
1125 | quota_send_warning(qd->qd_id, | 1146 | /* If we can't meet the target */ |
1126 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); | 1147 | if (limit && limit < (value + (s64)ap->target)) { |
1127 | 1148 | /* If no min_target specified or we don't meet | |
1128 | error = -EDQUOT; | 1149 | * min_target, return -EDQUOT */ |
1129 | break; | 1150 | if (!ap->min_target || ap->min_target > ap->allowed) { |
1130 | } else if (be64_to_cpu(qd->qd_qb.qb_warn) && | 1151 | print_message(qd, "exceeded"); |
1131 | (s64)be64_to_cpu(qd->qd_qb.qb_warn) < value && | 1152 | quota_send_warning(qd->qd_id, |
1153 | sdp->sd_vfs->s_dev, | ||
1154 | QUOTA_NL_BHARDWARN); | ||
1155 | error = -EDQUOT; | ||
1156 | break; | ||
1157 | } | ||
1158 | } else if (warn && warn < value && | ||
1132 | time_after_eq(jiffies, qd->qd_last_warn + | 1159 | time_after_eq(jiffies, qd->qd_last_warn + |
1133 | gfs2_tune_get(sdp, | 1160 | gfs2_tune_get(sdp, gt_quota_warn_period) |
1134 | gt_quota_warn_period) * HZ)) { | 1161 | * HZ)) { |
1135 | quota_send_warning(qd->qd_id, | 1162 | quota_send_warning(qd->qd_id, |
1136 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); | 1163 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); |
1137 | error = print_message(qd, "warning"); | 1164 | error = print_message(qd, "warning"); |
1138 | qd->qd_last_warn = jiffies; | 1165 | qd->qd_last_warn = jiffies; |
1139 | } | 1166 | } |
1140 | } | 1167 | } |
1141 | |||
1142 | return error; | 1168 | return error; |
1143 | } | 1169 | } |
1144 | 1170 | ||
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index 55d506eb3c4a..ad04b3acae2b 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h | |||
@@ -24,7 +24,8 @@ extern void gfs2_quota_unhold(struct gfs2_inode *ip); | |||
24 | extern int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); | 24 | extern int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); |
25 | extern void gfs2_quota_unlock(struct gfs2_inode *ip); | 25 | extern void gfs2_quota_unlock(struct gfs2_inode *ip); |
26 | 26 | ||
27 | extern int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); | 27 | extern int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, |
28 | struct gfs2_alloc_parms *ap); | ||
28 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 29 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
29 | kuid_t uid, kgid_t gid); | 30 | kuid_t uid, kgid_t gid); |
30 | 31 | ||
@@ -37,7 +38,8 @@ extern int gfs2_quotad(void *data); | |||
37 | 38 | ||
38 | extern void gfs2_wake_up_statfs(struct gfs2_sbd *sdp); | 39 | extern void gfs2_wake_up_statfs(struct gfs2_sbd *sdp); |
39 | 40 | ||
40 | static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) | 41 | static inline int gfs2_quota_lock_check(struct gfs2_inode *ip, |
42 | struct gfs2_alloc_parms *ap) | ||
41 | { | 43 | { |
42 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 44 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
43 | int ret; | 45 | int ret; |
@@ -48,7 +50,7 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) | |||
48 | return ret; | 50 | return ret; |
49 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 51 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
50 | return 0; | 52 | return 0; |
51 | ret = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); | 53 | ret = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid, ap); |
52 | if (ret) | 54 | if (ret) |
53 | gfs2_quota_unlock(ip); | 55 | gfs2_quota_unlock(ip); |
54 | return ret; | 56 | return ret; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 9150207f365c..6af2396a317c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1946,10 +1946,18 @@ static inline int fast_to_acquire(struct gfs2_rgrpd *rgd) | |||
1946 | * @ip: the inode to reserve space for | 1946 | * @ip: the inode to reserve space for |
1947 | * @ap: the allocation parameters | 1947 | * @ap: the allocation parameters |
1948 | * | 1948 | * |
1949 | * Returns: errno | 1949 | * We try our best to find an rgrp that has at least ap->target blocks |
1950 | * available. After a couple of passes (loops == 2), the prospects of finding | ||
1951 | * such an rgrp diminish. At this stage, we return the first rgrp that has | ||
1952 | * atleast ap->min_target blocks available. Either way, we set ap->allowed to | ||
1953 | * the number of blocks available in the chosen rgrp. | ||
1954 | * | ||
1955 | * Returns: 0 on success, | ||
1956 | * -ENOMEM if a suitable rgrp can't be found | ||
1957 | * errno otherwise | ||
1950 | */ | 1958 | */ |
1951 | 1959 | ||
1952 | int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap) | 1960 | int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap) |
1953 | { | 1961 | { |
1954 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1962 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1955 | struct gfs2_rgrpd *begin = NULL; | 1963 | struct gfs2_rgrpd *begin = NULL; |
@@ -2012,7 +2020,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a | |||
2012 | /* Skip unuseable resource groups */ | 2020 | /* Skip unuseable resource groups */ |
2013 | if ((rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC | | 2021 | if ((rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC | |
2014 | GFS2_RDF_ERROR)) || | 2022 | GFS2_RDF_ERROR)) || |
2015 | (ap->target > rs->rs_rbm.rgd->rd_extfail_pt)) | 2023 | (loops == 0 && ap->target > rs->rs_rbm.rgd->rd_extfail_pt)) |
2016 | goto skip_rgrp; | 2024 | goto skip_rgrp; |
2017 | 2025 | ||
2018 | if (sdp->sd_args.ar_rgrplvb) | 2026 | if (sdp->sd_args.ar_rgrplvb) |
@@ -2027,11 +2035,13 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a | |||
2027 | goto check_rgrp; | 2035 | goto check_rgrp; |
2028 | 2036 | ||
2029 | /* If rgrp has enough free space, use it */ | 2037 | /* If rgrp has enough free space, use it */ |
2030 | if (rs->rs_rbm.rgd->rd_free_clone >= ap->target) { | 2038 | if (rs->rs_rbm.rgd->rd_free_clone >= ap->target || |
2039 | (loops == 2 && ap->min_target && | ||
2040 | rs->rs_rbm.rgd->rd_free_clone >= ap->min_target)) { | ||
2031 | ip->i_rgd = rs->rs_rbm.rgd; | 2041 | ip->i_rgd = rs->rs_rbm.rgd; |
2042 | ap->allowed = ip->i_rgd->rd_free_clone; | ||
2032 | return 0; | 2043 | return 0; |
2033 | } | 2044 | } |
2034 | |||
2035 | check_rgrp: | 2045 | check_rgrp: |
2036 | /* Check for unlinked inodes which can be reclaimed */ | 2046 | /* Check for unlinked inodes which can be reclaimed */ |
2037 | if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) | 2047 | if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index b104f4af3afd..68972ecfbb01 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -41,7 +41,8 @@ extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh); | |||
41 | extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); | 41 | extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); |
42 | 42 | ||
43 | #define GFS2_AF_ORLOV 1 | 43 | #define GFS2_AF_ORLOV 1 |
44 | extern int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap); | 44 | extern int gfs2_inplace_reserve(struct gfs2_inode *ip, |
45 | struct gfs2_alloc_parms *ap); | ||
45 | extern void gfs2_inplace_release(struct gfs2_inode *ip); | 46 | extern void gfs2_inplace_release(struct gfs2_inode *ip); |
46 | 47 | ||
47 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, | 48 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, |
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 0b81f783f787..fd260ce8869a 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -732,7 +732,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
732 | if (error) | 732 | if (error) |
733 | return error; | 733 | return error; |
734 | 734 | ||
735 | error = gfs2_quota_lock_check(ip); | 735 | error = gfs2_quota_lock_check(ip, &ap); |
736 | if (error) | 736 | if (error) |
737 | return error; | 737 | return error; |
738 | 738 | ||