xfs: remove xfs_tosspages
[deliverable/linux.git] / fs / xfs / xfs_vnodeops.c
index c2ddd7a439422ed56494d45bf60a64a00e8b76fd..de3702a57e556c0458b0fa8f60f51342199f42db 100644 (file)
@@ -2118,7 +2118,7 @@ xfs_change_file_space(
        xfs_fsize_t     fsize;
        int             setprealloc;
        xfs_off_t       startoffset;
-       xfs_off_t       llen;
+       xfs_off_t       end;
        xfs_trans_t     *tp;
        struct iattr    iattr;
        int             prealloc_type;
@@ -2139,12 +2139,30 @@ xfs_change_file_space(
                return XFS_ERROR(EINVAL);
        }
 
-       llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len;
+       /*
+        * length of <= 0 for resv/unresv/zero is invalid.  length for
+        * alloc/free is ignored completely and we have no idea what userspace
+        * might have set it to, so set it to zero to allow range
+        * checks to pass.
+        */
+       switch (cmd) {
+       case XFS_IOC_ZERO_RANGE:
+       case XFS_IOC_RESVSP:
+       case XFS_IOC_RESVSP64:
+       case XFS_IOC_UNRESVSP:
+       case XFS_IOC_UNRESVSP64:
+               if (bf->l_len <= 0)
+                       return XFS_ERROR(EINVAL);
+               break;
+       default:
+               bf->l_len = 0;
+               break;
+       }
 
        if (bf->l_start < 0 ||
            bf->l_start > mp->m_super->s_maxbytes ||
-           bf->l_start + llen < 0 ||
-           bf->l_start + llen > mp->m_super->s_maxbytes)
+           bf->l_start + bf->l_len < 0 ||
+           bf->l_start + bf->l_len >= mp->m_super->s_maxbytes)
                return XFS_ERROR(EINVAL);
 
        bf->l_whence = 0;
@@ -2169,7 +2187,9 @@ xfs_change_file_space(
        switch (cmd) {
        case XFS_IOC_ZERO_RANGE:
                prealloc_type |= XFS_BMAPI_CONVERT;
-               xfs_tosspages(ip, startoffset, startoffset + bf->l_len, 0);
+               end = round_down(startoffset + bf->l_len, PAGE_SIZE) - 1;
+               if (startoffset > end)
+                       truncate_pagecache_range(VFS_I(ip), startoffset, end);
                /* FALLTHRU */
        case XFS_IOC_RESVSP:
        case XFS_IOC_RESVSP64:
This page took 0.02714 seconds and 5 git commands to generate.