xfs
[Top] [All Lists]

[PATCH 2/2] xfs: add FALLOC_FL_ZERO_RANGE to fallocate

To: linux-kernel@xxxxxxxxxxxxxxx
Subject: [PATCH 2/2] xfs: add FALLOC_FL_ZERO_RANGE to fallocate
From: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Date: Tue, 12 Jun 2012 17:36:04 +0200
Cc: xfs@xxxxxxxxxxx, linux-fsdevel@xxxxxxxxxxxxxxx, Dave Chinner <dchinner@xxxxxxxxxx>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=bQ59oM9ElwpNimHrxPyjrpAvzBQ4SP0UMW6RSo28tXY=; b=bZGmRx3AmJDD0XKmn+GhOlxpta82K0wUB2Ygu3zh4JlHTnClJyIC/SgRSVglxZImt3 RV7j54zTdpOV3SQ53MKRgxxm5N31gD61Nx7FAY1vdEYElHogJXZPhaFYgpAAyv/DIe2J 091NpTYrC8u2yBslKCLQzKMwrm6qrv+qTgwPmmxOHV3dLU7BS+zBhrvEclctxFHJKe4M 2GeBLYIf4ih28QX9beKMmDDMzb7x9rxk/SLAdLBbkc4pVKC+/EYBoXH4JIQZVdr9iW/q f5b/mgIwcnaPiGVAnDvbo7eH8TQuWMigdGiwBzi2aMzL47bWqufiW6J1Sl0skQeCSUg8 MuRw==
In-reply-to: <1339515364-17374-1-git-send-email-pbonzini@xxxxxxxxxx>
References: <1339515364-17374-1-git-send-email-pbonzini@xxxxxxxxxx>
Sender: Paolo Bonzini <paolo.bonzini@xxxxxxxxx>
This is implemented in the same way as the other fallocate modes.  All of
them map to XFS ioctls that are implemented by xfs_change_file_space.

However, we need to cap the length to the inode size if the user requested
FALLOC_FL_KEEP_SIZE.

Cc: Dave Chinner <dchinner@xxxxxxxxxx>
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 fs/xfs/xfs_file.c |   36 ++++++++++++++++++++++++------------
 1 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 9f7ec15..c811cf9 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -818,33 +818,45 @@ xfs_file_fallocate(
        loff_t          new_size = 0;
        xfs_flock64_t   bf;
        xfs_inode_t     *ip = XFS_I(inode);
-       int             cmd = XFS_IOC_RESVSP;
+       int             cmd;
        int             attr_flags = XFS_ATTR_NOLOCK;
 
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+                    FALLOC_FL_ZERO_RANGE))
                return -EOPNOTSUPP;
 
+       BUG_ON((mode & FALLOC_FL_PUNCH_HOLE) && (mode & FALLOC_FL_ZERO_RANGE));
+
        bf.l_whence = 0;
        bf.l_start = offset;
        bf.l_len = len;
 
        xfs_ilock(ip, XFS_IOLOCK_EXCL);
 
-       if (mode & FALLOC_FL_PUNCH_HOLE)
-               cmd = XFS_IOC_UNRESVSP;
-
-       /* check the new inode size is valid before allocating */
-       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
-           offset + len > i_size_read(inode)) {
-               new_size = offset + len;
-               error = inode_newsize_ok(inode, new_size);
-               if (error)
-                       goto out_unlock;
+       if (offset + len > i_size_read(inode)) {
+               if (mode & FALLOC_FL_KEEP_SIZE) {
+                       if (offset > i_size_read(inode))
+                               goto out_unlock;
+                       len = i_size_read(inode) - offset;
+               } else {
+                       /* check validity of new inode size before allocating */
+                       new_size = offset + len;
+                       error = inode_newsize_ok(inode, new_size);
+                       if (error)
+                               goto out_unlock;
+               }
        }
 
        if (file->f_flags & O_DSYNC)
                attr_flags |= XFS_ATTR_SYNC;
 
+       if (mode & FALLOC_FL_PUNCH_HOLE)
+               cmd = XFS_IOC_UNRESVSP;
+       else if (mode & FALLOC_FL_ZERO_RANGE)
+               cmd = XFS_IOC_ZERO_RANGE;
+       else
+               cmd = XFS_IOC_RESVSP;
+
        error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags);
        if (error)
                goto out_unlock;
-- 
1.7.1

<Prev in Thread] Current Thread [Next in Thread>