aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c168
1 files changed, 121 insertions, 47 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 2a5c637344b4..d95f565a390e 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -47,6 +47,7 @@
47#include "xfs_filestream.h" 47#include "xfs_filestream.h"
48#include "xfs_vnodeops.h" 48#include "xfs_vnodeops.h"
49#include "xfs_trace.h" 49#include "xfs_trace.h"
50#include "xfs_icache.h"
50 51
51/* 52/*
52 * The maximum pathlen is 1024 bytes. Since the minimum file system 53 * The maximum pathlen is 1024 bytes. Since the minimum file system
@@ -79,7 +80,7 @@ xfs_readlink_bmap(
79 d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); 80 d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
80 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); 81 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
81 82
82 bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0); 83 bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0, NULL);
83 if (!bp) 84 if (!bp)
84 return XFS_ERROR(ENOMEM); 85 return XFS_ERROR(ENOMEM);
85 error = bp->b_error; 86 error = bp->b_error;
@@ -150,7 +151,7 @@ xfs_readlink(
150 * when the link count isn't zero and by xfs_dm_punch_hole() when 151 * when the link count isn't zero and by xfs_dm_punch_hole() when
151 * punching a hole to EOF. 152 * punching a hole to EOF.
152 */ 153 */
153STATIC int 154int
154xfs_free_eofblocks( 155xfs_free_eofblocks(
155 xfs_mount_t *mp, 156 xfs_mount_t *mp,
156 xfs_inode_t *ip, 157 xfs_inode_t *ip,
@@ -199,7 +200,7 @@ xfs_free_eofblocks(
199 if (need_iolock) { 200 if (need_iolock) {
200 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { 201 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
201 xfs_trans_cancel(tp, 0); 202 xfs_trans_cancel(tp, 0);
202 return 0; 203 return EAGAIN;
203 } 204 }
204 } 205 }
205 206
@@ -237,6 +238,8 @@ xfs_free_eofblocks(
237 } else { 238 } else {
238 error = xfs_trans_commit(tp, 239 error = xfs_trans_commit(tp,
239 XFS_TRANS_RELEASE_LOG_RES); 240 XFS_TRANS_RELEASE_LOG_RES);
241 if (!error)
242 xfs_inode_clear_eofblocks_tag(ip);
240 } 243 }
241 244
242 xfs_iunlock(ip, XFS_ILOCK_EXCL); 245 xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -425,19 +428,18 @@ xfs_release(
425 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); 428 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
426 if (truncated) { 429 if (truncated) {
427 xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); 430 xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE);
428 if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) 431 if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) {
429 xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE); 432 error = -filemap_flush(VFS_I(ip)->i_mapping);
433 if (error)
434 return error;
435 }
430 } 436 }
431 } 437 }
432 438
433 if (ip->i_d.di_nlink == 0) 439 if (ip->i_d.di_nlink == 0)
434 return 0; 440 return 0;
435 441
436 if ((S_ISREG(ip->i_d.di_mode) && 442 if (xfs_can_free_eofblocks(ip, false)) {
437 (VFS_I(ip)->i_size > 0 ||
438 (VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) &&
439 (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
440 (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
441 443
442 /* 444 /*
443 * If we can't get the iolock just skip truncating the blocks 445 * If we can't get the iolock just skip truncating the blocks
@@ -464,7 +466,7 @@ xfs_release(
464 return 0; 466 return 0;
465 467
466 error = xfs_free_eofblocks(mp, ip, true); 468 error = xfs_free_eofblocks(mp, ip, true);
467 if (error) 469 if (error && error != EAGAIN)
468 return error; 470 return error;
469 471
470 /* delalloc blocks after truncation means it really is dirty */ 472 /* delalloc blocks after truncation means it really is dirty */
@@ -513,13 +515,12 @@ xfs_inactive(
513 goto out; 515 goto out;
514 516
515 if (ip->i_d.di_nlink != 0) { 517 if (ip->i_d.di_nlink != 0) {
516 if ((S_ISREG(ip->i_d.di_mode) && 518 /*
517 (VFS_I(ip)->i_size > 0 || 519 * force is true because we are evicting an inode from the
518 (VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) && 520 * cache. Post-eof blocks must be freed, lest we end up with
519 (ip->i_df.if_flags & XFS_IFEXTENTS) && 521 * broken free space accounting.
520 (!(ip->i_d.di_flags & 522 */
521 (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || 523 if (xfs_can_free_eofblocks(ip, true)) {
522 ip->i_delayed_blks != 0))) {
523 error = xfs_free_eofblocks(mp, ip, false); 524 error = xfs_free_eofblocks(mp, ip, false);
524 if (error) 525 if (error)
525 return VN_INACTIVE_CACHE; 526 return VN_INACTIVE_CACHE;
@@ -777,7 +778,7 @@ xfs_create(
777 XFS_TRANS_PERM_LOG_RES, log_count); 778 XFS_TRANS_PERM_LOG_RES, log_count);
778 if (error == ENOSPC) { 779 if (error == ENOSPC) {
779 /* flush outstanding delalloc blocks and retry */ 780 /* flush outstanding delalloc blocks and retry */
780 xfs_flush_inodes(dp); 781 xfs_flush_inodes(mp);
781 error = xfs_trans_reserve(tp, resblks, log_res, 0, 782 error = xfs_trans_reserve(tp, resblks, log_res, 0,
782 XFS_TRANS_PERM_LOG_RES, log_count); 783 XFS_TRANS_PERM_LOG_RES, log_count);
783 } 784 }
@@ -1957,12 +1958,11 @@ xfs_free_file_space(
1957 1958
1958 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); 1959 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
1959 ioffset = offset & ~(rounding - 1); 1960 ioffset = offset & ~(rounding - 1);
1960 1961 error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
1961 if (VN_CACHED(VFS_I(ip)) != 0) { 1962 ioffset, -1);
1962 error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); 1963 if (error)
1963 if (error) 1964 goto out_unlock_iolock;
1964 goto out_unlock_iolock; 1965 truncate_pagecache_range(VFS_I(ip), ioffset, -1);
1965 }
1966 1966
1967 /* 1967 /*
1968 * Need to zero the stuff we're not freeing, on disk. 1968 * Need to zero the stuff we're not freeing, on disk.
@@ -2095,6 +2095,73 @@ xfs_free_file_space(
2095 return error; 2095 return error;
2096} 2096}
2097 2097
2098
2099STATIC int
2100xfs_zero_file_space(
2101 struct xfs_inode *ip,
2102 xfs_off_t offset,
2103 xfs_off_t len,
2104 int attr_flags)
2105{
2106 struct xfs_mount *mp = ip->i_mount;
2107 uint granularity;
2108 xfs_off_t start_boundary;
2109 xfs_off_t end_boundary;
2110 int error;
2111
2112 granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
2113
2114 /*
2115 * Round the range of extents we are going to convert inwards. If the
2116 * offset is aligned, then it doesn't get changed so we zero from the
2117 * start of the block offset points to.
2118 */
2119 start_boundary = round_up(offset, granularity);
2120 end_boundary = round_down(offset + len, granularity);
2121
2122 ASSERT(start_boundary >= offset);
2123 ASSERT(end_boundary <= offset + len);
2124
2125 if (!(attr_flags & XFS_ATTR_NOLOCK))
2126 xfs_ilock(ip, XFS_IOLOCK_EXCL);
2127
2128 if (start_boundary < end_boundary - 1) {
2129 /* punch out the page cache over the conversion range */
2130 truncate_pagecache_range(VFS_I(ip), start_boundary,
2131 end_boundary - 1);
2132 /* convert the blocks */
2133 error = xfs_alloc_file_space(ip, start_boundary,
2134 end_boundary - start_boundary - 1,
2135 XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT,
2136 attr_flags);
2137 if (error)
2138 goto out_unlock;
2139
2140 /* We've handled the interior of the range, now for the edges */
2141 if (start_boundary != offset)
2142 error = xfs_iozero(ip, offset, start_boundary - offset);
2143 if (error)
2144 goto out_unlock;
2145
2146 if (end_boundary != offset + len)
2147 error = xfs_iozero(ip, end_boundary,
2148 offset + len - end_boundary);
2149
2150 } else {
2151 /*
2152 * It's either a sub-granularity range or the range spanned lies
2153 * partially across two adjacent blocks.
2154 */
2155 error = xfs_iozero(ip, offset, len);
2156 }
2157
2158out_unlock:
2159 if (!(attr_flags & XFS_ATTR_NOLOCK))
2160 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
2161 return error;
2162
2163}
2164
2098/* 2165/*
2099 * xfs_change_file_space() 2166 * xfs_change_file_space()
2100 * This routine allocates or frees disk space for the given file. 2167 * This routine allocates or frees disk space for the given file.
@@ -2120,10 +2187,8 @@ xfs_change_file_space(
2120 xfs_fsize_t fsize; 2187 xfs_fsize_t fsize;
2121 int setprealloc; 2188 int setprealloc;
2122 xfs_off_t startoffset; 2189 xfs_off_t startoffset;
2123 xfs_off_t llen;
2124 xfs_trans_t *tp; 2190 xfs_trans_t *tp;
2125 struct iattr iattr; 2191 struct iattr iattr;
2126 int prealloc_type;
2127 2192
2128 if (!S_ISREG(ip->i_d.di_mode)) 2193 if (!S_ISREG(ip->i_d.di_mode))
2129 return XFS_ERROR(EINVAL); 2194 return XFS_ERROR(EINVAL);
@@ -2141,12 +2206,30 @@ xfs_change_file_space(
2141 return XFS_ERROR(EINVAL); 2206 return XFS_ERROR(EINVAL);
2142 } 2207 }
2143 2208
2144 llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; 2209 /*
2210 * length of <= 0 for resv/unresv/zero is invalid. length for
2211 * alloc/free is ignored completely and we have no idea what userspace
2212 * might have set it to, so set it to zero to allow range
2213 * checks to pass.
2214 */
2215 switch (cmd) {
2216 case XFS_IOC_ZERO_RANGE:
2217 case XFS_IOC_RESVSP:
2218 case XFS_IOC_RESVSP64:
2219 case XFS_IOC_UNRESVSP:
2220 case XFS_IOC_UNRESVSP64:
2221 if (bf->l_len <= 0)
2222 return XFS_ERROR(EINVAL);
2223 break;
2224 default:
2225 bf->l_len = 0;
2226 break;
2227 }
2145 2228
2146 if (bf->l_start < 0 || 2229 if (bf->l_start < 0 ||
2147 bf->l_start > mp->m_super->s_maxbytes || 2230 bf->l_start > mp->m_super->s_maxbytes ||
2148 bf->l_start + llen < 0 || 2231 bf->l_start + bf->l_len < 0 ||
2149 bf->l_start + llen > mp->m_super->s_maxbytes) 2232 bf->l_start + bf->l_len >= mp->m_super->s_maxbytes)
2150 return XFS_ERROR(EINVAL); 2233 return XFS_ERROR(EINVAL);
2151 2234
2152 bf->l_whence = 0; 2235 bf->l_whence = 0;
@@ -2154,29 +2237,20 @@ xfs_change_file_space(
2154 startoffset = bf->l_start; 2237 startoffset = bf->l_start;
2155 fsize = XFS_ISIZE(ip); 2238 fsize = XFS_ISIZE(ip);
2156 2239
2157 /*
2158 * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve
2159 * file space.
2160 * These calls do NOT zero the data space allocated to the file,
2161 * nor do they change the file size.
2162 *
2163 * XFS_IOC_ALLOCSP and XFS_IOC_FREESP will allocate and free file
2164 * space.
2165 * These calls cause the new file data to be zeroed and the file
2166 * size to be changed.
2167 */
2168 setprealloc = clrprealloc = 0; 2240 setprealloc = clrprealloc = 0;
2169 prealloc_type = XFS_BMAPI_PREALLOC;
2170
2171 switch (cmd) { 2241 switch (cmd) {
2172 case XFS_IOC_ZERO_RANGE: 2242 case XFS_IOC_ZERO_RANGE:
2173 prealloc_type |= XFS_BMAPI_CONVERT; 2243 error = xfs_zero_file_space(ip, startoffset, bf->l_len,
2174 xfs_tosspages(ip, startoffset, startoffset + bf->l_len, 0); 2244 attr_flags);
2175 /* FALLTHRU */ 2245 if (error)
2246 return error;
2247 setprealloc = 1;
2248 break;
2249
2176 case XFS_IOC_RESVSP: 2250 case XFS_IOC_RESVSP:
2177 case XFS_IOC_RESVSP64: 2251 case XFS_IOC_RESVSP64:
2178 error = xfs_alloc_file_space(ip, startoffset, bf->l_len, 2252 error = xfs_alloc_file_space(ip, startoffset, bf->l_len,
2179 prealloc_type, attr_flags); 2253 XFS_BMAPI_PREALLOC, attr_flags);
2180 if (error) 2254 if (error)
2181 return error; 2255 return error;
2182 setprealloc = 1; 2256 setprealloc = 1;