mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
Merge branch 'iomap-4.9-misc-fixes-1' into for-next
This commit is contained in:
commit
b036b97050
84
fs/iomap.c
84
fs/iomap.c
@ -252,6 +252,88 @@ iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *iter,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iomap_file_buffered_write);
|
||||
|
||||
static struct page *
|
||||
__iomap_read_page(struct inode *inode, loff_t offset)
|
||||
{
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
struct page *page;
|
||||
|
||||
page = read_mapping_page(mapping, offset >> PAGE_SHIFT, NULL);
|
||||
if (IS_ERR(page))
|
||||
return page;
|
||||
if (!PageUptodate(page)) {
|
||||
put_page(page);
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
static loff_t
|
||||
iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
|
||||
struct iomap *iomap)
|
||||
{
|
||||
long status = 0;
|
||||
ssize_t written = 0;
|
||||
|
||||
do {
|
||||
struct page *page, *rpage;
|
||||
unsigned long offset; /* Offset into pagecache page */
|
||||
unsigned long bytes; /* Bytes to write to page */
|
||||
|
||||
offset = (pos & (PAGE_SIZE - 1));
|
||||
bytes = min_t(unsigned long, PAGE_SIZE - offset, length);
|
||||
|
||||
rpage = __iomap_read_page(inode, pos);
|
||||
if (IS_ERR(rpage))
|
||||
return PTR_ERR(rpage);
|
||||
|
||||
status = iomap_write_begin(inode, pos, bytes,
|
||||
AOP_FLAG_NOFS | AOP_FLAG_UNINTERRUPTIBLE,
|
||||
&page, iomap);
|
||||
put_page(rpage);
|
||||
if (unlikely(status))
|
||||
return status;
|
||||
|
||||
WARN_ON_ONCE(!PageUptodate(page));
|
||||
|
||||
status = iomap_write_end(inode, pos, bytes, bytes, page);
|
||||
if (unlikely(status <= 0)) {
|
||||
if (WARN_ON_ONCE(status == 0))
|
||||
return -EIO;
|
||||
return status;
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
|
||||
pos += status;
|
||||
written += status;
|
||||
length -= status;
|
||||
|
||||
balance_dirty_pages_ratelimited(inode->i_mapping);
|
||||
} while (length);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
int
|
||||
iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len,
|
||||
struct iomap_ops *ops)
|
||||
{
|
||||
loff_t ret;
|
||||
|
||||
while (len) {
|
||||
ret = iomap_apply(inode, pos, len, IOMAP_WRITE, ops, NULL,
|
||||
iomap_dirty_actor);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
pos += ret;
|
||||
len -= ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iomap_file_dirty);
|
||||
|
||||
static int iomap_zero(struct inode *inode, loff_t pos, unsigned offset,
|
||||
unsigned bytes, struct iomap *iomap)
|
||||
{
|
||||
@ -430,6 +512,8 @@ static int iomap_to_fiemap(struct fiemap_extent_info *fi,
|
||||
|
||||
if (iomap->flags & IOMAP_F_MERGED)
|
||||
flags |= FIEMAP_EXTENT_MERGED;
|
||||
if (iomap->flags & IOMAP_F_SHARED)
|
||||
flags |= FIEMAP_EXTENT_SHARED;
|
||||
|
||||
return fiemap_fill_next_extent(fi, iomap->offset,
|
||||
iomap->blkno != IOMAP_NULL_BLOCK ? iomap->blkno << 9: 0,
|
||||
|
@ -22,6 +22,7 @@ struct vm_fault;
|
||||
* Flags for iomap mappings:
|
||||
*/
|
||||
#define IOMAP_F_MERGED 0x01 /* contains multiple blocks/extents */
|
||||
#define IOMAP_F_SHARED 0x02 /* block shared with another file */
|
||||
|
||||
/*
|
||||
* Magic value for blkno:
|
||||
@ -64,6 +65,8 @@ struct iomap_ops {
|
||||
|
||||
ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from,
|
||||
struct iomap_ops *ops);
|
||||
int iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len,
|
||||
struct iomap_ops *ops);
|
||||
int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len,
|
||||
bool *did_zero, struct iomap_ops *ops);
|
||||
int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
|
||||
|
Loading…
Reference in New Issue
Block a user