Skip to content

Commit

Permalink
exofs: don't mess with simple_write_{begin,end}
Browse files Browse the repository at this point in the history
... and don't zero anything on short copy; just unlock
and return 0 if that has happened on non-uptodate page.

Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed Dec 10, 2016
1 parent 77469c3 commit 92e50d2
Showing 1 changed file with 30 additions and 38 deletions.
68 changes: 30 additions & 38 deletions fs/exofs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -870,46 +870,31 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,

page = *pagep;
if (page == NULL) {
ret = simple_write_begin(file, mapping, pos, len, flags, pagep,
fsdata);
if (ret) {
EXOFS_DBGMSG("simple_write_begin failed\n");
goto out;
page = grab_cache_page_write_begin(mapping, pos >> PAGE_SHIFT,
flags);
if (!page) {
EXOFS_DBGMSG("grab_cache_page_write_begin failed\n");
return -ENOMEM;
}

page = *pagep;
*pagep = page;
}

/* read modify write */
if (!PageUptodate(page) && (len != PAGE_SIZE)) {
loff_t i_size = i_size_read(mapping->host);
pgoff_t end_index = i_size >> PAGE_SHIFT;
size_t rlen;

if (page->index < end_index)
rlen = PAGE_SIZE;
else if (page->index == end_index)
rlen = i_size & ~PAGE_MASK;
else
rlen = 0;

if (!rlen) {
if (page->index > end_index) {
clear_highpage(page);
SetPageUptodate(page);
goto out;
}

ret = _readpage(page, true);
if (ret) {
/*SetPageError was done by _readpage. Is it ok?*/
unlock_page(page);
EXOFS_DBGMSG("__readpage failed\n");
} else {
ret = _readpage(page, true);
if (ret) {
unlock_page(page);
EXOFS_DBGMSG("__readpage failed\n");
}
}
}
out:
if (unlikely(ret))
_write_failed(mapping->host, pos + len);

return ret;
}

Expand All @@ -929,18 +914,25 @@ static int exofs_write_end(struct file *file, struct address_space *mapping,
struct page *page, void *fsdata)
{
struct inode *inode = mapping->host;
/* According to comment in simple_write_end i_mutex is held */
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);
loff_t last_pos = pos + copied;

/* TODO: once simple_write_end marks inode dirty remove */
if (i_size != inode->i_size)
if (!PageUptodate(page)) {
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);
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)
Expand Down

0 comments on commit 92e50d2

Please sign in to comment.