[Top] [All Lists]

[PATCH 0/3] fs: introduce IOC_MOV_DATA ioctl

To: Dave Chinner <david@xxxxxxxxxxxxx>, Theodore Ts'o <tytso@xxxxxxx>
Subject: [PATCH 0/3] fs: introduce IOC_MOV_DATA ioctl
From: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>
Date: Tue, 08 Jul 2014 20:59:32 +0900
Cc: linux-ext4 <linux-ext4@xxxxxxxxxxxxxxx>, linux-fsdevel@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, Lukáš Czerner <lczerner@xxxxxxxxxx>, Brian Foster <bfoster@xxxxxxxxxx>, Christoph Hellwig <hch@xxxxxxxxxxxxx>, Ashish Sangwan <a.sangwan@xxxxxxxxxxx>, xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
Dlp-filter: Pass
Thread-index: Ac+aopve62ajSocMTpGwICvq23LGFw==
For speeding non linear media editing operations, we have already implemeted
FALLOC_FL_COLLAPSE_RANGE (merged in kernel since 3.15) and 
FALLOC_FL_INSERT_RANGE (currently awaiting review).
Both of these fallocate flags are used to remove/insert data within same file.
In continuation of our effort of speeding non linear media editing
(although the use case is not limited to just media editing) we introduce here
an ioctl FS_IOC_MOV_DATA which moves arbitrary (but fs block size aligned
as of now) bytes of data from one file into other file .

The movement takes place by transfering complete extents from donor file to
receiver file and leaves a hole in the donor file at the point from where
the blocks are moved. To eliminate the hole from donor, user can call
COLLAPSE_RANGE after the ioctl is finished if contiguous file space is required.

The main data structure for this ioctl is:
struct mov_data {
       int     donor_fd;               /* fd of donor file */
       int     receiver_fd;            /* fd of receiver file */
       loff_t  donor_offset;           /* offset into donor file */
       loff_t  receiver_offset;        /* offset into receiver file */
       loff_t  length;                 /* data length to be moved */
       loff_t  moved_len;              /* data length actually moved after 
completion */
       int     flags;                  /* Currently unused */

FS_IOC_MOV_DATA will move length bytes of data from donor_fd's donor_offset
to receiver_fd's receiver_offset. The prerequisite is that there must be 
atleast length size hole present @receiver_offset.

For inserting hole within file size at receiver_offset, FALLOC_FL_INSERT_RANGE
can be used. We will shortly post new version of FALLOC_FL_INSERT_RANGE which
enables inserting hole instead of current behavior of allocating unwritten
extents. If the requirement is to create hole at the end of file, truncate(2)
will suffice.

The semantics of this ioctl are:
1) Like collapse range, offsets and length should be file system block size
2) In the receiver file, atleast length size hole should be present at
3) It does not change file size of any of donor or receiver file.
4) It leaves a hole at the place from where blocks are moved out in donor file.
5) Both (donor_offset + length) and (receiver_offset + length) should be within
   size of donor file and receiver file respectively.
   Only unwritten extents resides beyond file size and it does not make sense
   to transfer unwritten extents, leave apart the security issues it may raise.
6) If the range to be transfered from donor file contain any holes, they are
   replicated as it is in receiver file. It mean holes are preserved and
   the length of hole will be added to moved_len signifying that the hole range
   is succesfully transfered.

Currently, flags field is unused but could be used to expand new functionalities
in future.
Some potential enhancements could be:
1) Instead of moving data, one could use it for zero copying between 2 regular
2) Can expand it for a generic VFS interface for defragmenting files.
   Copying data from donor to receiver and than swapping their extents.
   Currently xfs has swap_extent ioctl and ext4 has move_extent ioctl.
   These two calls could additionaly go through the common interface.
3) Or it can be expanded just for swapping extents without copying.

Note: These patchse are created on source included INSERT RANGE patches.
Please Firstly Apply INSERT RANGE patches before applying IOC_MOV_DATA patches.

Namjae Jeon (3):
 fs: Add support IOC_MOV_DATA ioctl
 xfs: Add support IOC_MOV_DATA ioctl
 ext4: Add support IOC_MOV_DATA ioctl
 TODO: Add testcases in xfstests

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 0/3] fs: introduce IOC_MOV_DATA ioctl, Namjae Jeon <=