diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/acl.c | 6 | ||||
-rw-r--r-- | fs/gfs2/aops.c | 24 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 108 | ||||
-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 | 90 | ||||
-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 |
12 files changed, 208 insertions, 124 deletions
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 4ad4f94edebe..5551fea0afd7 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/swap.h> | 20 | #include <linux/swap.h> |
21 | #include <linux/gfs2_ondisk.h> | 21 | #include <linux/gfs2_ondisk.h> |
22 | #include <linux/backing-dev.h> | 22 | #include <linux/backing-dev.h> |
23 | #include <linux/aio.h> | 23 | #include <linux/uio.h> |
24 | #include <trace/events/writeback.h> | 24 | #include <trace/events/writeback.h> |
25 | 25 | ||
26 | #include "gfs2.h" | 26 | #include "gfs2.h" |
@@ -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; |
@@ -1016,13 +1016,12 @@ out: | |||
1016 | /** | 1016 | /** |
1017 | * gfs2_ok_for_dio - check that dio is valid on this file | 1017 | * gfs2_ok_for_dio - check that dio is valid on this file |
1018 | * @ip: The inode | 1018 | * @ip: The inode |
1019 | * @rw: READ or WRITE | ||
1020 | * @offset: The offset at which we are reading or writing | 1019 | * @offset: The offset at which we are reading or writing |
1021 | * | 1020 | * |
1022 | * Returns: 0 (to ignore the i/o request and thus fall back to buffered i/o) | 1021 | * Returns: 0 (to ignore the i/o request and thus fall back to buffered i/o) |
1023 | * 1 (to accept the i/o request) | 1022 | * 1 (to accept the i/o request) |
1024 | */ | 1023 | */ |
1025 | static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset) | 1024 | static int gfs2_ok_for_dio(struct gfs2_inode *ip, loff_t offset) |
1026 | { | 1025 | { |
1027 | /* | 1026 | /* |
1028 | * Should we return an error here? I can't see that O_DIRECT for | 1027 | * Should we return an error here? I can't see that O_DIRECT for |
@@ -1039,8 +1038,8 @@ static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset) | |||
1039 | 1038 | ||
1040 | 1039 | ||
1041 | 1040 | ||
1042 | static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | 1041 | static ssize_t gfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter, |
1043 | struct iov_iter *iter, loff_t offset) | 1042 | loff_t offset) |
1044 | { | 1043 | { |
1045 | struct file *file = iocb->ki_filp; | 1044 | struct file *file = iocb->ki_filp; |
1046 | struct inode *inode = file->f_mapping->host; | 1045 | struct inode *inode = file->f_mapping->host; |
@@ -1061,7 +1060,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
1061 | rv = gfs2_glock_nq(&gh); | 1060 | rv = gfs2_glock_nq(&gh); |
1062 | if (rv) | 1061 | if (rv) |
1063 | return rv; | 1062 | return rv; |
1064 | rv = gfs2_ok_for_dio(ip, rw, offset); | 1063 | rv = gfs2_ok_for_dio(ip, offset); |
1065 | if (rv != 1) | 1064 | if (rv != 1) |
1066 | goto out; /* dio not valid, fall back to buffered i/o */ | 1065 | goto out; /* dio not valid, fall back to buffered i/o */ |
1067 | 1066 | ||
@@ -1091,13 +1090,12 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
1091 | rv = filemap_write_and_wait_range(mapping, lstart, end); | 1090 | rv = filemap_write_and_wait_range(mapping, lstart, end); |
1092 | if (rv) | 1091 | if (rv) |
1093 | goto out; | 1092 | goto out; |
1094 | if (rw == WRITE) | 1093 | if (iov_iter_rw(iter) == WRITE) |
1095 | truncate_inode_pages_range(mapping, lstart, end); | 1094 | truncate_inode_pages_range(mapping, lstart, end); |
1096 | } | 1095 | } |
1097 | 1096 | ||
1098 | rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, | 1097 | rv = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter, |
1099 | iter, offset, | 1098 | offset, gfs2_get_block_direct, NULL, NULL, 0); |
1100 | gfs2_get_block_direct, NULL, NULL, 0); | ||
1101 | out: | 1099 | out: |
1102 | gfs2_glock_dq(&gh); | 1100 | gfs2_glock_dq(&gh); |
1103 | gfs2_holder_uninit(&gh); | 1101 | gfs2_holder_uninit(&gh); |
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 3e32bb8e2d7e..31892871ea87 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | #include <linux/dlm.h> | 26 | #include <linux/dlm.h> |
27 | #include <linux/dlm_plock.h> | 27 | #include <linux/dlm_plock.h> |
28 | #include <linux/aio.h> | ||
29 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
30 | 29 | ||
31 | #include "gfs2.h" | 30 | #include "gfs2.h" |
@@ -429,11 +428,11 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
429 | if (ret) | 428 | if (ret) |
430 | goto out_unlock; | 429 | goto out_unlock; |
431 | 430 | ||
432 | ret = gfs2_quota_lock_check(ip); | ||
433 | if (ret) | ||
434 | goto out_unlock; | ||
435 | 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); |
436 | 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; | ||
437 | ret = gfs2_inplace_reserve(ip, &ap); | 436 | ret = gfs2_inplace_reserve(ip, &ap); |
438 | if (ret) | 437 | if (ret) |
439 | goto out_quota_unlock; | 438 | goto out_quota_unlock; |
@@ -710,7 +709,7 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
710 | 709 | ||
711 | gfs2_size_hint(file, iocb->ki_pos, iov_iter_count(from)); | 710 | gfs2_size_hint(file, iocb->ki_pos, iov_iter_count(from)); |
712 | 711 | ||
713 | if (file->f_flags & O_APPEND) { | 712 | if (iocb->ki_flags & IOCB_APPEND) { |
714 | struct gfs2_holder gh; | 713 | struct gfs2_holder gh; |
715 | 714 | ||
716 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | 715 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
@@ -765,22 +764,30 @@ out: | |||
765 | brelse(dibh); | 764 | brelse(dibh); |
766 | return error; | 765 | return error; |
767 | } | 766 | } |
768 | 767 | /** | |
769 | 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 |
770 | 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) | ||
771 | { | 781 | { |
782 | loff_t max = *len; | ||
772 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 783 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
773 | unsigned int max_blocks = ip->i_rgd->rd_free_clone; | ||
774 | 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); |
775 | 785 | ||
776 | for (tmp = max_data; tmp > sdp->sd_diptrs;) { | 786 | for (tmp = max_data; tmp > sdp->sd_diptrs;) { |
777 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); | 787 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); |
778 | max_data -= tmp; | 788 | max_data -= tmp; |
779 | } | 789 | } |
780 | /* This calculation isn't the exact reverse of gfs2_write_calc_reserve, | 790 | |
781 | so it might end up with fewer data blocks */ | ||
782 | if (max_data <= *data_blocks) | ||
783 | return; | ||
784 | *data_blocks = max_data; | 791 | *data_blocks = max_data; |
785 | *ind_blocks = max_blocks - max_data; | 792 | *ind_blocks = max_blocks - max_data; |
786 | *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; |
@@ -797,7 +804,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
797 | struct gfs2_inode *ip = GFS2_I(inode); | 804 | struct gfs2_inode *ip = GFS2_I(inode); |
798 | struct gfs2_alloc_parms ap = { .aflags = 0, }; | 805 | struct gfs2_alloc_parms ap = { .aflags = 0, }; |
799 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 806 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
800 | loff_t bytes, max_bytes; | 807 | loff_t bytes, max_bytes, max_blks = UINT_MAX; |
801 | int error; | 808 | int error; |
802 | const loff_t pos = offset; | 809 | const loff_t pos = offset; |
803 | const loff_t count = len; | 810 | const loff_t count = len; |
@@ -819,6 +826,9 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
819 | 826 | ||
820 | gfs2_size_hint(file, offset, len); | 827 | gfs2_size_hint(file, offset, len); |
821 | 828 | ||
829 | gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks); | ||
830 | ap.min_target = data_blocks + ind_blocks; | ||
831 | |||
822 | while (len > 0) { | 832 | while (len > 0) { |
823 | if (len < bytes) | 833 | if (len < bytes) |
824 | bytes = len; | 834 | bytes = len; |
@@ -827,27 +837,41 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
827 | offset += bytes; | 837 | offset += bytes; |
828 | continue; | 838 | continue; |
829 | } | 839 | } |
830 | 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); | ||
831 | if (error) | 855 | if (error) |
832 | return error; | 856 | return error; |
833 | retry: | 857 | /* ap.allowed tells us how many blocks quota will allow |
834 | 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; | ||
835 | 861 | ||
836 | ap.target = data_blocks + ind_blocks; | ||
837 | error = gfs2_inplace_reserve(ip, &ap); | 862 | error = gfs2_inplace_reserve(ip, &ap); |
838 | if (error) { | 863 | if (error) |
839 | if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { | ||
840 | bytes >>= 1; | ||
841 | bytes &= bsize_mask; | ||
842 | if (bytes == 0) | ||
843 | bytes = sdp->sd_sb.sb_bsize; | ||
844 | goto retry; | ||
845 | } | ||
846 | goto out_qunlock; | 864 | goto out_qunlock; |
847 | } | 865 | |
848 | max_bytes = bytes; | 866 | /* check if the selected rgrp limits our max_blks further */ |
849 | calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len, | 867 | if (ap.allowed && ap.allowed < max_blks) |
850 | &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); | ||
851 | 875 | ||
852 | rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + | 876 | rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + |
853 | RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks); | 877 | RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks); |
@@ -931,6 +955,22 @@ out_uninit: | |||
931 | return ret; | 955 | return ret; |
932 | } | 956 | } |
933 | 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 | |||
934 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM | 974 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM |
935 | 975 | ||
936 | /** | 976 | /** |
@@ -1065,9 +1105,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | |||
1065 | 1105 | ||
1066 | const struct file_operations gfs2_file_fops = { | 1106 | const struct file_operations gfs2_file_fops = { |
1067 | .llseek = gfs2_llseek, | 1107 | .llseek = gfs2_llseek, |
1068 | .read = new_sync_read, | ||
1069 | .read_iter = generic_file_read_iter, | 1108 | .read_iter = generic_file_read_iter, |
1070 | .write = new_sync_write, | ||
1071 | .write_iter = gfs2_file_write_iter, | 1109 | .write_iter = gfs2_file_write_iter, |
1072 | .unlocked_ioctl = gfs2_ioctl, | 1110 | .unlocked_ioctl = gfs2_ioctl, |
1073 | .mmap = gfs2_mmap, | 1111 | .mmap = gfs2_mmap, |
@@ -1077,7 +1115,7 @@ const struct file_operations gfs2_file_fops = { | |||
1077 | .lock = gfs2_lock, | 1115 | .lock = gfs2_lock, |
1078 | .flock = gfs2_flock, | 1116 | .flock = gfs2_flock, |
1079 | .splice_read = generic_file_splice_read, | 1117 | .splice_read = generic_file_splice_read, |
1080 | .splice_write = iter_file_splice_write, | 1118 | .splice_write = gfs2_file_splice_write, |
1081 | .setlease = simple_nosetlease, | 1119 | .setlease = simple_nosetlease, |
1082 | .fallocate = gfs2_fallocate, | 1120 | .fallocate = gfs2_fallocate, |
1083 | }; | 1121 | }; |
@@ -1097,9 +1135,7 @@ const struct file_operations gfs2_dir_fops = { | |||
1097 | 1135 | ||
1098 | const struct file_operations gfs2_file_fops_nolock = { | 1136 | const struct file_operations gfs2_file_fops_nolock = { |
1099 | .llseek = gfs2_llseek, | 1137 | .llseek = gfs2_llseek, |
1100 | .read = new_sync_read, | ||
1101 | .read_iter = generic_file_read_iter, | 1138 | .read_iter = generic_file_read_iter, |
1102 | .write = new_sync_write, | ||
1103 | .write_iter = gfs2_file_write_iter, | 1139 | .write_iter = gfs2_file_write_iter, |
1104 | .unlocked_ioctl = gfs2_ioctl, | 1140 | .unlocked_ioctl = gfs2_ioctl, |
1105 | .mmap = gfs2_mmap, | 1141 | .mmap = gfs2_mmap, |
@@ -1107,7 +1143,7 @@ const struct file_operations gfs2_file_fops_nolock = { | |||
1107 | .release = gfs2_release, | 1143 | .release = gfs2_release, |
1108 | .fsync = gfs2_fsync, | 1144 | .fsync = gfs2_fsync, |
1109 | .splice_read = generic_file_splice_read, | 1145 | .splice_read = generic_file_splice_read, |
1110 | .splice_write = iter_file_splice_write, | 1146 | .splice_write = gfs2_file_splice_write, |
1111 | .setlease = generic_setlease, | 1147 | .setlease = generic_setlease, |
1112 | .fallocate = gfs2_fallocate, | 1148 | .fallocate = gfs2_fallocate, |
1113 | }; | 1149 | }; |
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..e3065cb9ab08 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 | ||
@@ -1468,32 +1494,34 @@ int gfs2_quotad(void *data) | |||
1468 | return 0; | 1494 | return 0; |
1469 | } | 1495 | } |
1470 | 1496 | ||
1471 | static int gfs2_quota_get_xstate(struct super_block *sb, | 1497 | static int gfs2_quota_get_state(struct super_block *sb, struct qc_state *state) |
1472 | struct fs_quota_stat *fqs) | ||
1473 | { | 1498 | { |
1474 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1499 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1475 | 1500 | ||
1476 | memset(fqs, 0, sizeof(struct fs_quota_stat)); | 1501 | memset(state, 0, sizeof(*state)); |
1477 | fqs->qs_version = FS_QSTAT_VERSION; | ||
1478 | 1502 | ||
1479 | switch (sdp->sd_args.ar_quota) { | 1503 | switch (sdp->sd_args.ar_quota) { |
1480 | case GFS2_QUOTA_ON: | 1504 | case GFS2_QUOTA_ON: |
1481 | fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD); | 1505 | state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; |
1506 | state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; | ||
1482 | /*FALLTHRU*/ | 1507 | /*FALLTHRU*/ |
1483 | case GFS2_QUOTA_ACCOUNT: | 1508 | case GFS2_QUOTA_ACCOUNT: |
1484 | fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT); | 1509 | state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED | |
1510 | QCI_SYSFILE; | ||
1511 | state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED | | ||
1512 | QCI_SYSFILE; | ||
1485 | break; | 1513 | break; |
1486 | case GFS2_QUOTA_OFF: | 1514 | case GFS2_QUOTA_OFF: |
1487 | break; | 1515 | break; |
1488 | } | 1516 | } |
1489 | |||
1490 | if (sdp->sd_quota_inode) { | 1517 | if (sdp->sd_quota_inode) { |
1491 | fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr; | 1518 | state->s_state[USRQUOTA].ino = |
1492 | fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks; | 1519 | GFS2_I(sdp->sd_quota_inode)->i_no_addr; |
1520 | state->s_state[USRQUOTA].blocks = sdp->sd_quota_inode->i_blocks; | ||
1493 | } | 1521 | } |
1494 | fqs->qs_uquota.qfs_nextents = 1; /* unsupported */ | 1522 | state->s_state[USRQUOTA].nextents = 1; /* unsupported */ |
1495 | fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */ | 1523 | state->s_state[GRPQUOTA] = state->s_state[USRQUOTA]; |
1496 | fqs->qs_incoredqs = list_lru_count(&gfs2_qd_lru); | 1524 | state->s_incoredqs = list_lru_count(&gfs2_qd_lru); |
1497 | return 0; | 1525 | return 0; |
1498 | } | 1526 | } |
1499 | 1527 | ||
@@ -1638,7 +1666,7 @@ out_put: | |||
1638 | 1666 | ||
1639 | const struct quotactl_ops gfs2_quotactl_ops = { | 1667 | const struct quotactl_ops gfs2_quotactl_ops = { |
1640 | .quota_sync = gfs2_quota_sync, | 1668 | .quota_sync = gfs2_quota_sync, |
1641 | .get_xstate = gfs2_quota_get_xstate, | 1669 | .get_state = gfs2_quota_get_state, |
1642 | .get_dqblk = gfs2_get_dqblk, | 1670 | .get_dqblk = gfs2_get_dqblk, |
1643 | .set_dqblk = gfs2_set_dqblk, | 1671 | .set_dqblk = gfs2_set_dqblk, |
1644 | }; | 1672 | }; |
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 | ||