Commit a8324754 authored by Al Viro's avatar Al Viro

Merge ext4 changes in ext4_file_write() into for-next

From ext4.git#dev, needed for switch of ext4 to ->write_iter() ;-/
parents 1456c0a8 f5ccfe1d
...@@ -158,7 +158,6 @@ struct ext4_allocation_request { ...@@ -158,7 +158,6 @@ struct ext4_allocation_request {
#define EXT4_MAP_MAPPED (1 << BH_Mapped) #define EXT4_MAP_MAPPED (1 << BH_Mapped)
#define EXT4_MAP_UNWRITTEN (1 << BH_Unwritten) #define EXT4_MAP_UNWRITTEN (1 << BH_Unwritten)
#define EXT4_MAP_BOUNDARY (1 << BH_Boundary) #define EXT4_MAP_BOUNDARY (1 << BH_Boundary)
#define EXT4_MAP_UNINIT (1 << BH_Uninit)
/* Sometimes (in the bigalloc case, from ext4_da_get_block_prep) the caller of /* Sometimes (in the bigalloc case, from ext4_da_get_block_prep) the caller of
* ext4_map_blocks wants to know whether or not the underlying cluster has * ext4_map_blocks wants to know whether or not the underlying cluster has
* already been accounted for. EXT4_MAP_FROM_CLUSTER conveys to the caller that * already been accounted for. EXT4_MAP_FROM_CLUSTER conveys to the caller that
...@@ -169,7 +168,7 @@ struct ext4_allocation_request { ...@@ -169,7 +168,7 @@ struct ext4_allocation_request {
#define EXT4_MAP_FROM_CLUSTER (1 << BH_AllocFromCluster) #define EXT4_MAP_FROM_CLUSTER (1 << BH_AllocFromCluster)
#define EXT4_MAP_FLAGS (EXT4_MAP_NEW | EXT4_MAP_MAPPED |\ #define EXT4_MAP_FLAGS (EXT4_MAP_NEW | EXT4_MAP_MAPPED |\
EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY |\ EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY |\
EXT4_MAP_UNINIT | EXT4_MAP_FROM_CLUSTER) EXT4_MAP_FROM_CLUSTER)
struct ext4_map_blocks { struct ext4_map_blocks {
ext4_fsblk_t m_pblk; ext4_fsblk_t m_pblk;
...@@ -184,7 +183,7 @@ struct ext4_map_blocks { ...@@ -184,7 +183,7 @@ struct ext4_map_blocks {
#define EXT4_IO_END_UNWRITTEN 0x0001 #define EXT4_IO_END_UNWRITTEN 0x0001
/* /*
* For converting uninitialized extents on a work queue. 'handle' is used for * For converting unwritten extents on a work queue. 'handle' is used for
* buffered writeback. * buffered writeback.
*/ */
typedef struct ext4_io_end { typedef struct ext4_io_end {
...@@ -537,26 +536,26 @@ enum { ...@@ -537,26 +536,26 @@ enum {
/* /*
* Flags used by ext4_map_blocks() * Flags used by ext4_map_blocks()
*/ */
/* Allocate any needed blocks and/or convert an unitialized /* Allocate any needed blocks and/or convert an unwritten
extent to be an initialized ext4 */ extent to be an initialized ext4 */
#define EXT4_GET_BLOCKS_CREATE 0x0001 #define EXT4_GET_BLOCKS_CREATE 0x0001
/* Request the creation of an unitialized extent */ /* Request the creation of an unwritten extent */
#define EXT4_GET_BLOCKS_UNINIT_EXT 0x0002 #define EXT4_GET_BLOCKS_UNWRIT_EXT 0x0002
#define EXT4_GET_BLOCKS_CREATE_UNINIT_EXT (EXT4_GET_BLOCKS_UNINIT_EXT|\ #define EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT (EXT4_GET_BLOCKS_UNWRIT_EXT|\
EXT4_GET_BLOCKS_CREATE) EXT4_GET_BLOCKS_CREATE)
/* Caller is from the delayed allocation writeout path /* Caller is from the delayed allocation writeout path
* finally doing the actual allocation of delayed blocks */ * finally doing the actual allocation of delayed blocks */
#define EXT4_GET_BLOCKS_DELALLOC_RESERVE 0x0004 #define EXT4_GET_BLOCKS_DELALLOC_RESERVE 0x0004
/* caller is from the direct IO path, request to creation of an /* caller is from the direct IO path, request to creation of an
unitialized extents if not allocated, split the uninitialized unwritten extents if not allocated, split the unwritten
extent if blocks has been preallocated already*/ extent if blocks has been preallocated already*/
#define EXT4_GET_BLOCKS_PRE_IO 0x0008 #define EXT4_GET_BLOCKS_PRE_IO 0x0008
#define EXT4_GET_BLOCKS_CONVERT 0x0010 #define EXT4_GET_BLOCKS_CONVERT 0x0010
#define EXT4_GET_BLOCKS_IO_CREATE_EXT (EXT4_GET_BLOCKS_PRE_IO|\ #define EXT4_GET_BLOCKS_IO_CREATE_EXT (EXT4_GET_BLOCKS_PRE_IO|\
EXT4_GET_BLOCKS_CREATE_UNINIT_EXT) EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT)
/* Convert extent to initialized after IO complete */ /* Convert extent to initialized after IO complete */
#define EXT4_GET_BLOCKS_IO_CONVERT_EXT (EXT4_GET_BLOCKS_CONVERT|\ #define EXT4_GET_BLOCKS_IO_CONVERT_EXT (EXT4_GET_BLOCKS_CONVERT|\
EXT4_GET_BLOCKS_CREATE_UNINIT_EXT) EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT)
/* Eventual metadata allocation (due to growing extent tree) /* Eventual metadata allocation (due to growing extent tree)
* should not fail, so try to use reserved blocks for that.*/ * should not fail, so try to use reserved blocks for that.*/
#define EXT4_GET_BLOCKS_METADATA_NOFAIL 0x0020 #define EXT4_GET_BLOCKS_METADATA_NOFAIL 0x0020
...@@ -2783,10 +2782,9 @@ extern int ext4_mmp_csum_verify(struct super_block *sb, ...@@ -2783,10 +2782,9 @@ extern int ext4_mmp_csum_verify(struct super_block *sb,
* See EXT4_MAP_... to see where this is used. * See EXT4_MAP_... to see where this is used.
*/ */
enum ext4_state_bits { enum ext4_state_bits {
BH_Uninit /* blocks are allocated but uninitialized on disk */ BH_AllocFromCluster /* allocated blocks were part of already
= BH_JBDPrivateStart,
BH_AllocFromCluster, /* allocated blocks were part of already
* allocated cluster. */ * allocated cluster. */
= BH_JBDPrivateStart
}; };
/* /*
......
...@@ -137,21 +137,21 @@ struct ext4_ext_path { ...@@ -137,21 +137,21 @@ struct ext4_ext_path {
* EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
* initialized extent. This is 2^15 and not (2^16 - 1), since we use the * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
* MSB of ee_len field in the extent datastructure to signify if this * MSB of ee_len field in the extent datastructure to signify if this
* particular extent is an initialized extent or an uninitialized (i.e. * particular extent is an initialized extent or an unwritten (i.e.
* preallocated). * preallocated).
* EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an * EXT_UNWRITTEN_MAX_LEN is the maximum number of blocks we can have in an
* uninitialized extent. * unwritten extent.
* If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
* uninitialized one. In other words, if MSB of ee_len is set, it is an * unwritten one. In other words, if MSB of ee_len is set, it is an
* uninitialized extent with only one special scenario when ee_len = 0x8000. * unwritten extent with only one special scenario when ee_len = 0x8000.
* In this case we can not have an uninitialized extent of zero length and * In this case we can not have an unwritten extent of zero length and
* thus we make it as a special case of initialized extent with 0x8000 length. * thus we make it as a special case of initialized extent with 0x8000 length.
* This way we get better extent-to-group alignment for initialized extents. * This way we get better extent-to-group alignment for initialized extents.
* Hence, the maximum number of blocks we can have in an *initialized* * Hence, the maximum number of blocks we can have in an *initialized*
* extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767). * extent is 2^15 (32768) and in an *unwritten* extent is 2^15-1 (32767).
*/ */
#define EXT_INIT_MAX_LEN (1UL << 15) #define EXT_INIT_MAX_LEN (1UL << 15)
#define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1) #define EXT_UNWRITTEN_MAX_LEN (EXT_INIT_MAX_LEN - 1)
#define EXT_FIRST_EXTENT(__hdr__) \ #define EXT_FIRST_EXTENT(__hdr__) \
...@@ -187,14 +187,14 @@ static inline unsigned short ext_depth(struct inode *inode) ...@@ -187,14 +187,14 @@ static inline unsigned short ext_depth(struct inode *inode)
return le16_to_cpu(ext_inode_hdr(inode)->eh_depth); return le16_to_cpu(ext_inode_hdr(inode)->eh_depth);
} }
static inline void ext4_ext_mark_uninitialized(struct ext4_extent *ext) static inline void ext4_ext_mark_unwritten(struct ext4_extent *ext)
{ {
/* We can not have an uninitialized extent of zero length! */ /* We can not have an unwritten extent of zero length! */
BUG_ON((le16_to_cpu(ext->ee_len) & ~EXT_INIT_MAX_LEN) == 0); BUG_ON((le16_to_cpu(ext->ee_len) & ~EXT_INIT_MAX_LEN) == 0);
ext->ee_len |= cpu_to_le16(EXT_INIT_MAX_LEN); ext->ee_len |= cpu_to_le16(EXT_INIT_MAX_LEN);
} }
static inline int ext4_ext_is_uninitialized(struct ext4_extent *ext) static inline int ext4_ext_is_unwritten(struct ext4_extent *ext)
{ {
/* Extent with ee_len of 0x8000 is treated as an initialized extent */ /* Extent with ee_len of 0x8000 is treated as an initialized extent */
return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN); return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
......
This diff is collapsed.
...@@ -433,7 +433,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode, ...@@ -433,7 +433,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
ee_start = ext4_ext_pblock(ex); ee_start = ext4_ext_pblock(ex);
ee_len = ext4_ext_get_actual_len(ex); ee_len = ext4_ext_get_actual_len(ex);
ee_status = ext4_ext_is_uninitialized(ex) ? 1 : 0; ee_status = ext4_ext_is_unwritten(ex) ? 1 : 0;
es_status = ext4_es_is_unwritten(es) ? 1 : 0; es_status = ext4_es_is_unwritten(es) ? 1 : 0;
/* /*
......
...@@ -92,58 +92,91 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, ...@@ -92,58 +92,91 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov,
} }
static ssize_t static ssize_t
ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov, ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos) unsigned long nr_segs, loff_t pos)
{ {
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host; struct inode *inode = file_inode(iocb->ki_filp);
struct mutex *aio_mutex = NULL;
struct blk_plug plug; struct blk_plug plug;
int unaligned_aio = 0; int o_direct = file->f_flags & O_DIRECT;
ssize_t ret;
int overwrite = 0; int overwrite = 0;
size_t length = iov_length(iov, nr_segs); size_t length = iov_length(iov, nr_segs);
ssize_t ret;
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && BUG_ON(iocb->ki_pos != pos);
!is_sync_kiocb(iocb))
unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos);
/* Unaligned direct AIO must be serialized; see comment above */ /*
if (unaligned_aio) { * Unaligned direct AIO must be serialized; see comment above
mutex_lock(ext4_aio_mutex(inode)); * In the case of O_APPEND, assume that we must always serialize
*/
if (o_direct &&
ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
!is_sync_kiocb(iocb) &&
(file->f_flags & O_APPEND ||
ext4_unaligned_aio(inode, iov, nr_segs, pos))) {
aio_mutex = ext4_aio_mutex(inode);
mutex_lock(aio_mutex);
ext4_unwritten_wait(inode); ext4_unwritten_wait(inode);
} }
BUG_ON(iocb->ki_pos != pos);
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
blk_start_plug(&plug); if (file->f_flags & O_APPEND)
iocb->ki_pos = pos = i_size_read(inode);
/*
* If we have encountered a bitmap-format file, the size limit
* is smaller than s_maxbytes, which is for extent-mapped files.
*/
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
iocb->private = &overwrite; if ((pos > sbi->s_bitmap_maxbytes) ||
(pos == sbi->s_bitmap_maxbytes && length > 0)) {
mutex_unlock(&inode->i_mutex);
ret = -EFBIG;
goto errout;
}
/* check whether we do a DIO overwrite or not */ if (pos + length > sbi->s_bitmap_maxbytes) {
if (ext4_should_dioread_nolock(inode) && !unaligned_aio && nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
!file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { sbi->s_bitmap_maxbytes - pos);
struct ext4_map_blocks map; }
unsigned int blkbits = inode->i_blkbits; }
int err, len;
map.m_lblk = pos >> blkbits; if (o_direct) {
map.m_len = (EXT4_BLOCK_ALIGN(pos + length, blkbits) >> blkbits) blk_start_plug(&plug);
- map.m_lblk;
len = map.m_len;
err = ext4_map_blocks(NULL, inode, &map, 0); iocb->private = &overwrite;
/*
* 'err==len' means that all of blocks has been preallocated no /* check whether we do a DIO overwrite or not */
* matter they are initialized or not. For excluding if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
* uninitialized extents, we need to check m_flags. There are !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
* two conditions that indicate for initialized extents. struct ext4_map_blocks map;
* 1) If we hit extent cache, EXT4_MAP_MAPPED flag is returned; unsigned int blkbits = inode->i_blkbits;
* 2) If we do a real lookup, non-flags are returned. int err, len;
* So we should check these two conditions.
*/ map.m_lblk = pos >> blkbits;
if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) map.m_len = (EXT4_BLOCK_ALIGN(pos + length, blkbits) >> blkbits)
overwrite = 1; - map.m_lblk;
len = map.m_len;
err = ext4_map_blocks(NULL, inode, &map, 0);
/*
* 'err==len' means that all of blocks has
* been preallocated no matter they are
* initialized or not. For excluding
* unwritten extents, we need to check
* m_flags. There are two conditions that
* indicate for initialized extents. 1) If we
* hit extent cache, EXT4_MAP_MAPPED flag is
* returned; 2) If we do a real lookup,
* non-flags are returned. So we should check
* these two conditions.
*/
if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
overwrite = 1;
}
} }
ret = __generic_file_aio_write(iocb, iov, nr_segs); ret = __generic_file_aio_write(iocb, iov, nr_segs);
...@@ -156,45 +189,12 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -156,45 +189,12 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
if (err < 0) if (err < 0)
ret = err; ret = err;
} }
blk_finish_plug(&plug); if (o_direct)
blk_finish_plug(&plug);
if (unaligned_aio)
mutex_unlock(ext4_aio_mutex(inode));
return ret;
}
static ssize_t
ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct inode *inode = file_inode(iocb->ki_filp);
ssize_t ret;
/*
* If we have encountered a bitmap-format file, the size limit
* is smaller than s_maxbytes, which is for extent-mapped files.
*/
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
size_t length = iov_length(iov, nr_segs);
if ((pos > sbi->s_bitmap_maxbytes ||
(pos == sbi->s_bitmap_maxbytes && length > 0)))
return -EFBIG;
if (pos + length > sbi->s_bitmap_maxbytes) {
nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
sbi->s_bitmap_maxbytes - pos);
}
}
if (unlikely(iocb->ki_filp->f_flags & O_DIRECT))
ret = ext4_file_dio_write(iocb, iov, nr_segs, pos);
else
ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
errout:
if (aio_mutex)
mutex_unlock(aio_mutex);
return ret; return ret;
} }
......
...@@ -489,8 +489,8 @@ static void ext4_map_blocks_es_recheck(handle_t *handle, ...@@ -489,8 +489,8 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
* Otherwise, call with ext4_ind_map_blocks() to handle indirect mapping * Otherwise, call with ext4_ind_map_blocks() to handle indirect mapping
* based files * based files
* *
* On success, it returns the number of blocks being mapped or allocate. * On success, it returns the number of blocks being mapped or allocated.
* if create==0 and the blocks are pre-allocated and uninitialized block, * if create==0 and the blocks are pre-allocated and unwritten block,
* the result buffer head is unmapped. If the create ==1, it will make sure * the result buffer head is unmapped. If the create ==1, it will make sure
* the buffer head is mapped. * the buffer head is mapped.
* *
...@@ -622,7 +622,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, ...@@ -622,7 +622,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
map->m_flags &= ~EXT4_MAP_FLAGS; map->m_flags &= ~EXT4_MAP_FLAGS;
/* /*
* New blocks allocate and/or writing to uninitialized extent * New blocks allocate and/or writing to unwritten extent
* will possibly result in updating i_data, so we take * will possibly result in updating i_data, so we take
* the write lock of i_data_sem, and call get_blocks() * the write lock of i_data_sem, and call get_blocks()
* with create == 1 flag. * with create == 1 flag.
...@@ -2032,7 +2032,7 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd, ...@@ -2032,7 +2032,7 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd,
* Scan buffers corresponding to changed extent (we expect corresponding pages * Scan buffers corresponding to changed extent (we expect corresponding pages
* to be already locked) and update buffer state according to new extent state. * to be already locked) and update buffer state according to new extent state.
* We map delalloc buffers to their physical location, clear unwritten bits, * We map delalloc buffers to their physical location, clear unwritten bits,
* and mark buffers as uninit when we perform writes to uninitialized extents * and mark buffers as uninit when we perform writes to unwritten extents
* and do extent conversion after IO is finished. If the last page is not fully * and do extent conversion after IO is finished. If the last page is not fully
* mapped, we update @map to the next extent in the last page that needs * mapped, we update @map to the next extent in the last page that needs
* mapping. Otherwise we submit the page for IO. * mapping. Otherwise we submit the page for IO.
...@@ -2126,12 +2126,12 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd) ...@@ -2126,12 +2126,12 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
struct inode *inode = mpd->inode; struct inode *inode = mpd->inode;
struct ext4_map_blocks *map = &mpd->map; struct ext4_map_blocks *map = &mpd->map;
int get_blocks_flags; int get_blocks_flags;
int err; int err, dioread_nolock;
trace_ext4_da_write_pages_extent(inode, map); trace_ext4_da_write_pages_extent(inode, map);
/* /*
* Call ext4_map_blocks() to allocate any delayed allocation blocks, or * Call ext4_map_blocks() to allocate any delayed allocation blocks, or
* to convert an uninitialized extent to be initialized (in the case * to convert an unwritten extent to be initialized (in the case
* where we have written into one or more preallocated blocks). It is * where we have written into one or more preallocated blocks). It is
* possible that we're going to need more metadata blocks than * possible that we're going to need more metadata blocks than
* previously reserved. However we must not fail because we're in * previously reserved. However we must not fail because we're in
...@@ -2148,7 +2148,8 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd) ...@@ -2148,7 +2148,8 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
*/ */
get_blocks_flags = EXT4_GET_BLOCKS_CREATE | get_blocks_flags = EXT4_GET_BLOCKS_CREATE |
EXT4_GET_BLOCKS_METADATA_NOFAIL; EXT4_GET_BLOCKS_METADATA_NOFAIL;
if (ext4_should_dioread_nolock(inode)) dioread_nolock = ext4_should_dioread_nolock(inode);
if (dioread_nolock)
get_blocks_flags |= EXT4_GET_BLOCKS_IO_CREATE_EXT; get_blocks_flags |= EXT4_GET_BLOCKS_IO_CREATE_EXT;
if (map->m_flags & (1 << BH_Delay)) if (map->m_flags & (1 << BH_Delay))
get_blocks_flags |= EXT4_GET_BLOCKS_DELALLOC_RESERVE; get_blocks_flags |= EXT4_GET_BLOCKS_DELALLOC_RESERVE;
...@@ -2156,7 +2157,7 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd) ...@@ -2156,7 +2157,7 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
err = ext4_map_blocks(handle, inode, map, get_blocks_flags); err = ext4_map_blocks(handle, inode, map, get_blocks_flags);
if (err < 0) if (err < 0)
return err; return err;
if (map->m_flags & EXT4_MAP_UNINIT) { if (dioread_nolock && (map->m_flags & EXT4_MAP_UNWRITTEN)) {
if (!mpd->io_submit.io_end->handle && if (!mpd->io_submit.io_end->handle &&
ext4_handle_valid(handle)) { ext4_handle_valid(handle)) {
mpd->io_submit.io_end->handle = handle->h_rsv_handle; mpd->io_submit.io_end->handle = handle->h_rsv_handle;
...@@ -3070,9 +3071,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, ...@@ -3070,9 +3071,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
* preallocated extents, and those write extend the file, no need to * preallocated extents, and those write extend the file, no need to
* fall back to buffered IO. * fall back to buffered IO.
* *
* For holes, we fallocate those blocks, mark them as uninitialized * For holes, we fallocate those blocks, mark them as unwritten
* If those blocks were preallocated, we mark sure they are split, but * If those blocks were preallocated, we mark sure they are split, but
* still keep the range to write as uninitialized. * still keep the range to write as unwritten.
* *
* The unwritten extents will be converted to written when DIO is completed. * The unwritten extents will be converted to written when DIO is completed.
* For async direct IO, since the IO may still pending when return, we * For async direct IO, since the IO may still pending when return, we
...@@ -3123,12 +3124,12 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, ...@@ -3123,12 +3124,12 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
* We could direct write to holes and fallocate. * We could direct write to holes and fallocate.
* *
* Allocated blocks to fill the hole are marked as * Allocated blocks to fill the hole are marked as
* uninitialized to prevent parallel buffered read to expose * unwritten to prevent parallel buffered read to expose
* the stale data before DIO complete the data IO. * the stale data before DIO complete the data IO.
* *
* As to previously fallocated extents, ext4 get_block will * As to previously fallocated extents, ext4 get_block will
* just simply mark the buffer mapped but still keep the * just simply mark the buffer mapped but still keep the
* extents uninitialized. * extents unwritten.
* *
* For non AIO case, we will convert those unwritten extents * For non AIO case, we will convert those unwritten extents
* to written after return back from blockdev_direct_IO. * to written after return back from blockdev_direct_IO.
......
...@@ -57,8 +57,8 @@ get_ext_path(struct inode *inode, ext4_lblk_t lblock, ...@@ -57,8 +57,8 @@ get_ext_path(struct inode *inode, ext4_lblk_t lblock,
static void static void
copy_extent_status(struct ext4_extent *src, struct ext4_extent *dest) copy_extent_status(struct ext4_extent *src, struct ext4_extent *dest)
{ {
if (ext4_ext_is_uninitialized(src)) if (ext4_ext_is_unwritten(src))
ext4_ext_mark_uninitialized(dest); ext4_ext_mark_unwritten(dest);
else else
dest->ee_len = cpu_to_le16(ext4_ext_get_actual_len(dest)); dest->ee_len = cpu_to_le16(ext4_ext_get_actual_len(dest));
} }
...@@ -593,14 +593,14 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext, ...@@ -593,14 +593,14 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
* @inode: inode in question * @inode: inode in question
* @from: block offset of inode * @from: block offset of inode
* @count: block count to be checked * @count: block count to be checked
* @uninit: extents expected to be uninitialized * @unwritten: extents expected to be unwritten
* @err: pointer to save error value * @err: pointer to save error value
* *
* Return 1 if all extents in range has expected type, and zero otherwise. * Return 1 if all extents in range has expected type, and zero otherwise.
*/ */
static int static int
mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count, mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
int uninit, int *err) int unwritten, int *err)
{ {
struct ext4_ext_path *path = NULL; struct ext4_ext_path *path = NULL;
struct ext4_extent *ext; struct ext4_extent *ext;
...@@ -611,7 +611,7 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count, ...@@ -611,7 +611,7 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
if (*err) if (*err)
goto out; goto out;
ext = path[ext_depth(inode)].p_ext; ext = path[ext_depth(inode)].p_ext;
if (uninit != ext4_ext_is_uninitialized(ext)) if (unwritten != ext4_ext_is_unwritten(ext))
goto out; goto out;
from += ext4_ext_get_actual_len(ext); from += ext4_ext_get_actual_len(ext);
ext4_ext_drop_refs(path); ext4_ext_drop_refs(path);
...@@ -894,7 +894,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to) ...@@ -894,7 +894,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to)
* @orig_page_offset: page index on original file * @orig_page_offset: page index on original file
* @data_offset_in_page: block index where data swapping starts * @data_offset_in_page: block index where data swapping starts
* @block_len_in_page: the number of blocks to be swapped * @block_len_in_page: the number of blocks to be swapped
* @uninit: orig extent is uninitialized or not * @unwritten: orig extent is unwritten or not
* @err: pointer to save return value * @err: pointer to save return value
* *
* Save the data in original inode blocks and replace original inode extents * Save the data in original inode blocks and replace original inode extents
...@@ -905,7 +905,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to) ...@@ -905,7 +905,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to)
static int static int
move_extent_per_page(struct file *o_filp, struct inode *donor_inode, move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
pgoff_t orig_page_offset, int data_offset_in_page, pgoff_t orig_page_offset, int data_offset_in_page,
int block_len_in_page, int uninit, int *err) int block_len_in_page, int unwritten, int *err)
{ {
struct inode *orig_inode = file_inode(o_filp); struct inode *orig_inode = file_inode(o_filp);
struct page *pagep[2] = {NULL, NULL}; struct page *pagep[2] = {NULL, NULL};
...@@ -962,27 +962,27 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -962,27 +962,27 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
if (unlikely(*err < 0)) if (unlikely(*err < 0))
goto stop_journal; goto stop_journal;
/* /*
* If orig extent was uninitialized it can become initialized * If orig extent was unwritten it can become initialized
* at any time after i_data_sem was dropped, in order to * at any time after i_data_sem was dropped, in order to
* serialize with delalloc we have recheck extent while we * serialize with delalloc we have recheck extent while we
* hold page's lock, if it is still the case data copy is not * hold page's lock, if it is still the case data copy is not
* necessary, just swap data blocks between orig and donor. * necessary, just swap data blocks between orig and donor.
*/ */
if (uninit) { if (unwritten) {
ext4_double_down_write_data_sem(orig_inode, donor_inode); ext4_double_down_write_data_sem(orig_inode, donor_inode);
/* If any of extents in range became initialized we have to /* If any of extents in range became initialized we have to
* fallback to data copying */ * fallback to data copying */
uninit = mext_check_coverage(orig_inode, orig_blk_offset, unwritten = mext_check_coverage(orig_inode, orig_blk_offset,
block_len_in_page, 1, err); block_len_in_page, 1, err);
if (*err) if (*err)
goto drop_data_sem; goto drop_data_sem;
uninit &= mext_check_coverage(donor_inode, orig_blk_offset, unwritten &= mext_check_coverage(donor_inode, orig_blk_offset,
block_len_in_page, 1, err); block_len_in_page, 1, err);
if (*err) if (*err)
goto drop_data_sem; goto drop_data_sem;
if (!uninit) { if (!unwritten) {
ext4_double_up_write_data_sem(orig_inode, donor_inode); ext4_double_up_write_data_sem(orig_inode, donor_inode);
goto data_copy; goto data_copy;
} }
...@@ -1259,7 +1259,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, ...@@ -1259,7 +1259,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
int data_offset_in_page; int data_offset_in_page;
int block_len_in_page; int block_len_in_page;
int uninit; int unwritten;
if (orig_inode->i_sb != donor_inode->i_sb) { if (orig_inode->i_sb != donor_inode->i_sb) {
ext4_debug("ext4 move extent: The argument files " ext4_debug("ext4 move extent: The argument files "
...@@ -1391,8 +1391,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, ...@@ -1391,8 +1391,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
!last_extent) !last_extent)
continue; continue;
/* Is original extent is uninitialized */ /* Is original extent is unwritten */
uninit = ext4_ext_is_uninitialized(ext_prev); unwritten = ext4_ext_is_unwritten(ext_prev);
data_offset_in_page = seq_start % blocks_per_page; data_offset_in_page = seq_start % blocks_per_page;
...@@ -1432,8 +1432,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, ...@@ -1432,8 +1432,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
o_filp, donor_inode, o_filp, donor_inode,
orig_page_offset, orig_page_offset,
data_offset_in_page, data_offset_in_page,
block_len_in_page, uninit, block_len_in_page,
&ret); unwritten, &ret);
/* Count how many blocks we have exchanged */ /* Count how many blocks we have exchanged */
*moved_len += block_len_in_page; *moved_len += block_len_in_page;
......
...@@ -3337,7 +3337,7 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb) ...@@ -3337,7 +3337,7 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
* By default we reserve 2% or 4096 clusters, whichever is smaller. * By default we reserve 2% or 4096 clusters, whichever is smaller.
* This should cover the situations where we can not afford to run * This should cover the situations where we can not afford to run
* out of space like for example punch hole, or converting * out of space like for example punch hole, or converting
* uninitialized extents in delalloc path. In most cases such * unwritten extents in delalloc path. In most cases such
* allocation would require 1, or 2 blocks, higher numbers are * allocation would require 1, or 2 blocks, higher numbers are
* very rare. * very rare.
*/ */
......
...@@ -36,7 +36,7 @@ struct extent_status; ...@@ -36,7 +36,7 @@ struct extent_status;
#define show_map_flags(flags) __print_flags(flags, "|", \ #define show_map_flags(flags) __print_flags(flags, "|", \
{ EXT4_GET_BLOCKS_CREATE, "CREATE" }, \ { EXT4_GET_BLOCKS_CREATE, "CREATE" }, \
{ EXT4_GET_BLOCKS_UNINIT_EXT, "UNINIT" }, \ { EXT4_GET_BLOCKS_UNWRIT_EXT, "UNWRIT" }, \
{ EXT4_GET_BLOCKS_DELALLOC_RESERVE, "DELALLOC" }, \ { EXT4_GET_BLOCKS_DELALLOC_RESERVE, "DELALLOC" }, \
{ EXT4_GET_BLOCKS_PRE_IO, "PRE_IO" }, \ { EXT4_GET_BLOCKS_PRE_IO, "PRE_IO" }, \
{ EXT4_GET_BLOCKS_CONVERT, "CONVERT" }, \ { EXT4_GET_BLOCKS_CONVERT, "CONVERT" }, \
...@@ -51,7 +51,6 @@ struct extent_status; ...@@ -51,7 +51,6 @@ struct extent_status;
{ EXT4_MAP_MAPPED, "M" }, \ { EXT4_MAP_MAPPED, "M" }, \
{ EXT4_MAP_UNWRITTEN, "U" }, \ { EXT4_MAP_UNWRITTEN, "U" }, \
{ EXT4_MAP_BOUNDARY, "B" }, \ { EXT4_MAP_BOUNDARY, "B" }, \
{ EXT4_MAP_UNINIT, "u" }, \
{ EXT4_MAP_FROM_CLUSTER, "C" }) { EXT4_MAP_FROM_CLUSTER, "C" })
#define show_free_flags(flags) __print_flags(flags, "|", \ #define show_free_flags(flags) __print_flags(flags, "|", \
...@@ -1497,7 +1496,7 @@ DEFINE_EVENT(ext4__truncate, ext4_truncate_exit, ...@@ -1497,7 +1496,7 @@ DEFINE_EVENT(ext4__truncate, ext4_truncate_exit,
TP_ARGS(inode) TP_ARGS(inode)
); );
/* 'ux' is the uninitialized extent. */ /* 'ux' is the unwritten extent. */
TRACE_EVENT(ext4_ext_convert_to_initialized_enter, TRACE_EVENT(ext4_ext_convert_to_initialized_enter,
TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, TP_PROTO(struct inode *inode, struct ext4_map_blocks *map,
struct ext4_extent *ux), struct ext4_extent *ux),
...@@ -1533,7 +1532,7 @@ TRACE_EVENT(ext4_ext_convert_to_initialized_enter, ...@@ -1533,7 +1532,7 @@ TRACE_EVENT(ext4_ext_convert_to_initialized_enter,
); );
/* /*
* 'ux' is the uninitialized extent. * 'ux' is the unwritten extent.
* 'ix' is the initialized extent to which blocks are transferred. * 'ix' is the initialized extent to which blocks are transferred.
*/ */
TRACE_EVENT(ext4_ext_convert_to_initialized_fastpath, TRACE_EVENT(ext4_ext_convert_to_initialized_fastpath,
...@@ -1811,7 +1810,7 @@ DEFINE_EVENT(ext4__trim, ext4_trim_all_free, ...@@ -1811,7 +1810,7 @@ DEFINE_EVENT(ext4__trim, ext4_trim_all_free,
TP_ARGS(sb, group, start, len) TP_ARGS(sb, group, start, len)
); );
TRACE_EVENT(ext4_ext_handle_uninitialized_extents, TRACE_EVENT(ext4_ext_handle_unwritten_extents,
TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, int flags, TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, int flags,
unsigned int allocated, ext4_fsblk_t newblock), unsigned int allocated, ext4_fsblk_t newblock),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment