diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:09:18 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:09:18 -0400 |
| commit | 80dcc31fbe55932ac9204daee5f2ebc0c49b6da3 (patch) | |
| tree | 723802ccd7e96da883352704fe3d2c5e3ba9d2e6 | |
| parent | 78d5dcda92a17f17132671c269ea2c3a17688649 (diff) | |
| parent | 30133177957dca9a3e2a37b720f891d3225a92a1 (diff) | |
Merge tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull GFS2 updates from Bob Peterson:
"Here is a list of patches we've accumulated for GFS2 for the current
upstream merge window.
Most of the patches fix GFS2 quotas, which were not properly enforced.
There's another that adds me as a GFS2 co-maintainer, and a couple
patches that fix a kernel panic doing splice_write on GFS2 as well as
a few correctness patches"
* tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
gfs2: fix quota refresh race in do_glock()
gfs2: incorrect check for debugfs returns
gfs2: allow fallocate to max out quotas/fs efficiently
gfs2: allow quota_check and inplace_reserve to return available blocks
gfs2: perform quota checks against allocation parameters
GFS2: Move gfs2_file_splice_write outside of #ifdef
GFS2: Allocate reservation during splice_write
GFS2: gfs2_set_acl(): Cache "no acl" as well
Add myself (Bob Peterson) as a maintainer of GFS2
| -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; | ||
