summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_dfrag.c3
-rw-r--r--fs/xfs/xfs_fs_subr.c12
-rw-r--r--fs/xfs/xfs_vnodeops.c30
-rw-r--r--fs/xfs/xfs_vnodeops.h2
4 files changed, 26 insertions, 21 deletions
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index b9b8646e62db..b2c63a28afa7 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -315,8 +315,7 @@ xfs_swap_extents(
315 * are safe. We don't really care if non-io related 315 * are safe. We don't really care if non-io related
316 * fields change. 316 * fields change.
317 */ 317 */
318 318 truncate_pagecache_range(VFS_I(ip), 0, -1);
319 xfs_tosspages(ip, 0, -1, FI_REMAPF);
320 319
321 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); 320 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
322 if ((error = xfs_trans_reserve(tp, 0, 321 if ((error = xfs_trans_reserve(tp, 0,
diff --git a/fs/xfs/xfs_fs_subr.c b/fs/xfs/xfs_fs_subr.c
index 652b875a9d4c..d49de3d70456 100644
--- a/fs/xfs/xfs_fs_subr.c
+++ b/fs/xfs/xfs_fs_subr.c
@@ -25,18 +25,6 @@
25 * note: all filemap functions return negative error codes. These 25 * note: all filemap functions return negative error codes. These
26 * need to be inverted before returning to the xfs core functions. 26 * need to be inverted before returning to the xfs core functions.
27 */ 27 */
28void
29xfs_tosspages(
30 xfs_inode_t *ip,
31 xfs_off_t first,
32 xfs_off_t last,
33 int fiopt)
34{
35 /* can't toss partial tail pages, so mask them out */
36 last &= ~(PAGE_SIZE - 1);
37 truncate_inode_pages_range(VFS_I(ip)->i_mapping, first, last - 1);
38}
39
40int 28int
41xfs_flushinval_pages( 29xfs_flushinval_pages(
42 xfs_inode_t *ip, 30 xfs_inode_t *ip,
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index c2ddd7a43942..de3702a57e55 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2118,7 +2118,7 @@ xfs_change_file_space(
2118 xfs_fsize_t fsize; 2118 xfs_fsize_t fsize;
2119 int setprealloc; 2119 int setprealloc;
2120 xfs_off_t startoffset; 2120 xfs_off_t startoffset;
2121 xfs_off_t llen; 2121 xfs_off_t end;
2122 xfs_trans_t *tp; 2122 xfs_trans_t *tp;
2123 struct iattr iattr; 2123 struct iattr iattr;
2124 int prealloc_type; 2124 int prealloc_type;
@@ -2139,12 +2139,30 @@ xfs_change_file_space(
2139 return XFS_ERROR(EINVAL); 2139 return XFS_ERROR(EINVAL);
2140 } 2140 }
2141 2141
2142 llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; 2142 /*
2143 * length of <= 0 for resv/unresv/zero is invalid. length for
2144 * alloc/free is ignored completely and we have no idea what userspace
2145 * might have set it to, so set it to zero to allow range
2146 * checks to pass.
2147 */
2148 switch (cmd) {
2149 case XFS_IOC_ZERO_RANGE:
2150 case XFS_IOC_RESVSP:
2151 case XFS_IOC_RESVSP64:
2152 case XFS_IOC_UNRESVSP:
2153 case XFS_IOC_UNRESVSP64:
2154 if (bf->l_len <= 0)
2155 return XFS_ERROR(EINVAL);
2156 break;
2157 default:
2158 bf->l_len = 0;
2159 break;
2160 }
2143 2161
2144 if (bf->l_start < 0 || 2162 if (bf->l_start < 0 ||
2145 bf->l_start > mp->m_super->s_maxbytes || 2163 bf->l_start > mp->m_super->s_maxbytes ||
2146 bf->l_start + llen < 0 || 2164 bf->l_start + bf->l_len < 0 ||
2147 bf->l_start + llen > mp->m_super->s_maxbytes) 2165 bf->l_start + bf->l_len >= mp->m_super->s_maxbytes)
2148 return XFS_ERROR(EINVAL); 2166 return XFS_ERROR(EINVAL);
2149 2167
2150 bf->l_whence = 0; 2168 bf->l_whence = 0;
@@ -2169,7 +2187,9 @@ xfs_change_file_space(
2169 switch (cmd) { 2187 switch (cmd) {
2170 case XFS_IOC_ZERO_RANGE: 2188 case XFS_IOC_ZERO_RANGE:
2171 prealloc_type |= XFS_BMAPI_CONVERT; 2189 prealloc_type |= XFS_BMAPI_CONVERT;
2172 xfs_tosspages(ip, startoffset, startoffset + bf->l_len, 0); 2190 end = round_down(startoffset + bf->l_len, PAGE_SIZE) - 1;
2191 if (startoffset > end)
2192 truncate_pagecache_range(VFS_I(ip), startoffset, end);
2173 /* FALLTHRU */ 2193 /* FALLTHRU */
2174 case XFS_IOC_RESVSP: 2194 case XFS_IOC_RESVSP:
2175 case XFS_IOC_RESVSP64: 2195 case XFS_IOC_RESVSP64:
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 52fafc416a0c..d48141d6bc3b 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -48,8 +48,6 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
48int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); 48int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags);
49int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, 49int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
50 int flags, struct attrlist_cursor_kern *cursor); 50 int flags, struct attrlist_cursor_kern *cursor);
51void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first,
52 xfs_off_t last, int fiopt);
53int xfs_flushinval_pages(struct xfs_inode *ip, xfs_off_t first, 51int xfs_flushinval_pages(struct xfs_inode *ip, xfs_off_t first,
54 xfs_off_t last, int fiopt); 52 xfs_off_t last, int fiopt);
55int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first, 53int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,