Merge branch 'work.write_end' into for-linus
This commit is contained in:
commit
4da00fd1b9
@ -309,18 +309,10 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
|
|||||||
|
|
||||||
p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
|
p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
|
||||||
|
|
||||||
if (unlikely(copied < len)) {
|
if (unlikely(copied < len && !PageUptodate(page))) {
|
||||||
/*
|
copied = 0;
|
||||||
* zero out the rest of the area
|
goto out;
|
||||||
*/
|
|
||||||
unsigned from = pos & (PAGE_SIZE - 1);
|
|
||||||
|
|
||||||
zero_user(page, from + copied, len - copied);
|
|
||||||
flush_dcache_page(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PageUptodate(page))
|
|
||||||
SetPageUptodate(page);
|
|
||||||
/*
|
/*
|
||||||
* No need to use i_size_read() here, the i_size
|
* No need to use i_size_read() here, the i_size
|
||||||
* cannot change under us because we hold the i_mutex.
|
* cannot change under us because we hold the i_mutex.
|
||||||
@ -330,6 +322,7 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
|
|||||||
i_size_write(inode, last_pos);
|
i_size_write(inode, last_pos);
|
||||||
}
|
}
|
||||||
set_page_dirty(page);
|
set_page_dirty(page);
|
||||||
|
out:
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
put_page(page);
|
put_page(page);
|
||||||
|
|
||||||
|
@ -1276,25 +1276,27 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
|
|||||||
struct page *page, void *fsdata)
|
struct page *page, void *fsdata)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
unsigned from = pos & (PAGE_SIZE - 1);
|
|
||||||
int check_cap = 0;
|
int check_cap = 0;
|
||||||
|
|
||||||
dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
|
dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
|
||||||
inode, page, (int)pos, (int)copied, (int)len);
|
inode, page, (int)pos, (int)copied, (int)len);
|
||||||
|
|
||||||
/* zero the stale part of the page if we did a short copy */
|
/* zero the stale part of the page if we did a short copy */
|
||||||
if (copied < len)
|
if (!PageUptodate(page)) {
|
||||||
zero_user_segment(page, from+copied, len);
|
if (copied < len) {
|
||||||
|
copied = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
SetPageUptodate(page);
|
||||||
|
}
|
||||||
|
|
||||||
/* did file size increase? */
|
/* did file size increase? */
|
||||||
if (pos+copied > i_size_read(inode))
|
if (pos+copied > i_size_read(inode))
|
||||||
check_cap = ceph_inode_set_size(inode, pos+copied);
|
check_cap = ceph_inode_set_size(inode, pos+copied);
|
||||||
|
|
||||||
if (!PageUptodate(page))
|
|
||||||
SetPageUptodate(page);
|
|
||||||
|
|
||||||
set_page_dirty(page);
|
set_page_dirty(page);
|
||||||
|
|
||||||
|
out:
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
put_page(page);
|
put_page(page);
|
||||||
|
|
||||||
|
@ -870,46 +870,31 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
|
|||||||
|
|
||||||
page = *pagep;
|
page = *pagep;
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
ret = simple_write_begin(file, mapping, pos, len, flags, pagep,
|
page = grab_cache_page_write_begin(mapping, pos >> PAGE_SHIFT,
|
||||||
fsdata);
|
flags);
|
||||||
if (ret) {
|
if (!page) {
|
||||||
EXOFS_DBGMSG("simple_write_begin failed\n");
|
EXOFS_DBGMSG("grab_cache_page_write_begin failed\n");
|
||||||
goto out;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
*pagep = page;
|
||||||
page = *pagep;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read modify write */
|
/* read modify write */
|
||||||
if (!PageUptodate(page) && (len != PAGE_SIZE)) {
|
if (!PageUptodate(page) && (len != PAGE_SIZE)) {
|
||||||
loff_t i_size = i_size_read(mapping->host);
|
loff_t i_size = i_size_read(mapping->host);
|
||||||
pgoff_t end_index = i_size >> PAGE_SHIFT;
|
pgoff_t end_index = i_size >> PAGE_SHIFT;
|
||||||
size_t rlen;
|
|
||||||
|
|
||||||
if (page->index < end_index)
|
if (page->index > end_index) {
|
||||||
rlen = PAGE_SIZE;
|
|
||||||
else if (page->index == end_index)
|
|
||||||
rlen = i_size & ~PAGE_MASK;
|
|
||||||
else
|
|
||||||
rlen = 0;
|
|
||||||
|
|
||||||
if (!rlen) {
|
|
||||||
clear_highpage(page);
|
clear_highpage(page);
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
goto out;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
ret = _readpage(page, true);
|
ret = _readpage(page, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/*SetPageError was done by _readpage. Is it ok?*/
|
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
EXOFS_DBGMSG("__readpage failed\n");
|
EXOFS_DBGMSG("__readpage failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
}
|
||||||
if (unlikely(ret))
|
|
||||||
_write_failed(mapping->host, pos + len);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,18 +914,25 @@ static int exofs_write_end(struct file *file, struct address_space *mapping,
|
|||||||
struct page *page, void *fsdata)
|
struct page *page, void *fsdata)
|
||||||
{
|
{
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
/* According to comment in simple_write_end i_mutex is held */
|
loff_t last_pos = pos + copied;
|
||||||
loff_t i_size = inode->i_size;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata);
|
if (!PageUptodate(page)) {
|
||||||
if (unlikely(ret))
|
if (copied < len) {
|
||||||
_write_failed(inode, pos + len);
|
_write_failed(inode, pos + len);
|
||||||
|
copied = 0;
|
||||||
/* TODO: once simple_write_end marks inode dirty remove */
|
goto out;
|
||||||
if (i_size != inode->i_size)
|
}
|
||||||
|
SetPageUptodate(page);
|
||||||
|
}
|
||||||
|
if (last_pos > inode->i_size) {
|
||||||
|
i_size_write(inode, last_pos);
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
return ret;
|
}
|
||||||
|
set_page_dirty(page);
|
||||||
|
out:
|
||||||
|
unlock_page(page);
|
||||||
|
put_page(page);
|
||||||
|
return copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exofs_releasepage(struct page *page, gfp_t gfp)
|
static int exofs_releasepage(struct page *page, gfp_t gfp)
|
||||||
|
@ -839,12 +839,10 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
|
|||||||
BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
|
BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
|
||||||
kaddr = kmap_atomic(page);
|
kaddr = kmap_atomic(page);
|
||||||
memcpy(buf + pos, kaddr + pos, copied);
|
memcpy(buf + pos, kaddr + pos, copied);
|
||||||
memset(kaddr + pos + copied, 0, len - copied);
|
|
||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
kunmap_atomic(kaddr);
|
kunmap_atomic(kaddr);
|
||||||
|
|
||||||
if (!PageUptodate(page))
|
WARN_ON(!PageUptodate(page));
|
||||||
SetPageUptodate(page);
|
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
put_page(page);
|
put_page(page);
|
||||||
|
|
||||||
|
@ -465,6 +465,8 @@ EXPORT_SYMBOL(simple_write_begin);
|
|||||||
* is not called, so a filesystem that actually does store data in .write_inode
|
* is not called, so a filesystem that actually does store data in .write_inode
|
||||||
* should extend on what's done here with a call to mark_inode_dirty() in the
|
* should extend on what's done here with a call to mark_inode_dirty() in the
|
||||||
* case that i_size has changed.
|
* case that i_size has changed.
|
||||||
|
*
|
||||||
|
* Use *ONLY* with simple_readpage()
|
||||||
*/
|
*/
|
||||||
int simple_write_end(struct file *file, struct address_space *mapping,
|
int simple_write_end(struct file *file, struct address_space *mapping,
|
||||||
loff_t pos, unsigned len, unsigned copied,
|
loff_t pos, unsigned len, unsigned copied,
|
||||||
@ -474,14 +476,14 @@ int simple_write_end(struct file *file, struct address_space *mapping,
|
|||||||
loff_t last_pos = pos + copied;
|
loff_t last_pos = pos + copied;
|
||||||
|
|
||||||
/* zero the stale part of the page if we did a short copy */
|
/* zero the stale part of the page if we did a short copy */
|
||||||
|
if (!PageUptodate(page)) {
|
||||||
if (copied < len) {
|
if (copied < len) {
|
||||||
unsigned from = pos & (PAGE_SIZE - 1);
|
unsigned from = pos & (PAGE_SIZE - 1);
|
||||||
|
|
||||||
zero_user(page, from + copied, len - copied);
|
zero_user(page, from + copied, len - copied);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PageUptodate(page))
|
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* No need to use i_size_read() here, the i_size
|
* No need to use i_size_read() here, the i_size
|
||||||
* cannot change under us because we hold the i_mutex.
|
* cannot change under us because we hold the i_mutex.
|
||||||
|
@ -374,7 +374,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
|
|||||||
*/
|
*/
|
||||||
if (!PageUptodate(page)) {
|
if (!PageUptodate(page)) {
|
||||||
unsigned pglen = nfs_page_length(page);
|
unsigned pglen = nfs_page_length(page);
|
||||||
unsigned end = offset + len;
|
unsigned end = offset + copied;
|
||||||
|
|
||||||
if (pglen == 0) {
|
if (pglen == 0) {
|
||||||
zero_user_segments(page, 0, offset,
|
zero_user_segments(page, 0, offset,
|
||||||
|
Loading…
Reference in New Issue
Block a user