Commit 92e50d2d authored by Al Viro's avatar Al Viro

exofs: don't mess with simple_write_{begin,end}

... and don't zero anything on short copy; just unlock
and return 0 if that has happened on non-uptodate page.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 77469c3f
...@@ -870,46 +870,31 @@ int exofs_write_begin(struct file *file, struct address_space *mapping, ...@@ -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);
if (ret) {
ret = _readpage(page, true); unlock_page(page);
if (ret) { EXOFS_DBGMSG("__readpage failed\n");
/*SetPageError was done by _readpage. Is it ok?*/ }
unlock_page(page);
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, ...@@ -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 (unlikely(ret))
_write_failed(inode, pos + len);
/* TODO: once simple_write_end marks inode dirty remove */ if (!PageUptodate(page)) {
if (i_size != inode->i_size) if (copied < len) {
_write_failed(inode, pos + len);
copied = 0;
goto out;
}
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)
......
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