Commit f2b6a16e authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

fs: affs convert to new aops

Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b4585729
...@@ -395,25 +395,33 @@ static int affs_writepage(struct page *page, struct writeback_control *wbc) ...@@ -395,25 +395,33 @@ static int affs_writepage(struct page *page, struct writeback_control *wbc)
{ {
return block_write_full_page(page, affs_get_block, wbc); return block_write_full_page(page, affs_get_block, wbc);
} }
static int affs_readpage(struct file *file, struct page *page) static int affs_readpage(struct file *file, struct page *page)
{ {
return block_read_full_page(page, affs_get_block); return block_read_full_page(page, affs_get_block);
} }
static int affs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
static int affs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{ {
return cont_prepare_write(page, from, to, affs_get_block, *pagep = NULL;
&AFFS_I(page->mapping->host)->mmu_private); return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
affs_get_block,
&AFFS_I(mapping->host)->mmu_private);
} }
static sector_t _affs_bmap(struct address_space *mapping, sector_t block) static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
{ {
return generic_block_bmap(mapping,block,affs_get_block); return generic_block_bmap(mapping,block,affs_get_block);
} }
const struct address_space_operations affs_aops = { const struct address_space_operations affs_aops = {
.readpage = affs_readpage, .readpage = affs_readpage,
.writepage = affs_writepage, .writepage = affs_writepage,
.sync_page = block_sync_page, .sync_page = block_sync_page,
.prepare_write = affs_prepare_write, .write_begin = affs_write_begin,
.commit_write = generic_commit_write, .write_end = generic_write_end,
.bmap = _affs_bmap .bmap = _affs_bmap
}; };
...@@ -603,54 +611,65 @@ affs_readpage_ofs(struct file *file, struct page *page) ...@@ -603,54 +611,65 @@ affs_readpage_ofs(struct file *file, struct page *page)
return err; return err;
} }
static int affs_prepare_write_ofs(struct file *file, struct page *page, unsigned from, unsigned to) static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = mapping->host;
u32 size, offset; struct page *page;
u32 tmp; pgoff_t index;
int err = 0; int err = 0;
pr_debug("AFFS: prepare_write(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to); pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
offset = page->index << PAGE_CACHE_SHIFT; if (pos > AFFS_I(inode)->mmu_private) {
if (offset + from > AFFS_I(inode)->mmu_private) { /* XXX: this probably leaves a too-big i_size in case of
err = affs_extent_file_ofs(inode, offset + from); * failure. Should really be updating i_size at write_end time
*/
err = affs_extent_file_ofs(inode, pos);
if (err) if (err)
return err; return err;
} }
size = inode->i_size;
index = pos >> PAGE_CACHE_SHIFT;
page = __grab_cache_page(mapping, index);
if (!page)
return -ENOMEM;
*pagep = page;
if (PageUptodate(page)) if (PageUptodate(page))
return 0; return 0;
if (from) { /* XXX: inefficient but safe in the face of short writes */
err = affs_do_readpage_ofs(file, page, 0, from); err = affs_do_readpage_ofs(file, page, 0, PAGE_CACHE_SIZE);
if (err) if (err) {
return err; unlock_page(page);
} page_cache_release(page);
if (to < PAGE_CACHE_SIZE) {
zero_user_page(page, to, PAGE_CACHE_SIZE - to, KM_USER0);
if (size > offset + to) {
if (size < offset + PAGE_CACHE_SIZE)
tmp = size & ~PAGE_CACHE_MASK;
else
tmp = PAGE_CACHE_SIZE;
err = affs_do_readpage_ofs(file, page, to, tmp);
}
} }
return err; return err;
} }
static int affs_commit_write_ofs(struct file *file, struct page *page, unsigned from, unsigned to) static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = mapping->host;
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct buffer_head *bh, *prev_bh; struct buffer_head *bh, *prev_bh;
char *data; char *data;
u32 bidx, boff, bsize; u32 bidx, boff, bsize;
unsigned from, to;
u32 tmp; u32 tmp;
int written; int written;
pr_debug("AFFS: commit_write(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to); from = pos & (PAGE_CACHE_SIZE - 1);
to = pos + len;
/*
* XXX: not sure if this can handle short copies (len < copied), but
* we don't have to, because the page should always be uptodate here,
* due to write_begin.
*/
pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
bsize = AFFS_SB(sb)->s_data_blksize; bsize = AFFS_SB(sb)->s_data_blksize;
data = page_address(page); data = page_address(page);
...@@ -748,6 +767,9 @@ done: ...@@ -748,6 +767,9 @@ done:
if (tmp > inode->i_size) if (tmp > inode->i_size)
inode->i_size = AFFS_I(inode)->mmu_private = tmp; inode->i_size = AFFS_I(inode)->mmu_private = tmp;
unlock_page(page);
page_cache_release(page);
return written; return written;
out: out:
...@@ -761,8 +783,8 @@ const struct address_space_operations affs_aops_ofs = { ...@@ -761,8 +783,8 @@ const struct address_space_operations affs_aops_ofs = {
.readpage = affs_readpage_ofs, .readpage = affs_readpage_ofs,
//.writepage = affs_writepage_ofs, //.writepage = affs_writepage_ofs,
//.sync_page = affs_sync_page_ofs, //.sync_page = affs_sync_page_ofs,
.prepare_write = affs_prepare_write_ofs, .write_begin = affs_write_begin_ofs,
.commit_write = affs_commit_write_ofs .write_end = affs_write_end_ofs
}; };
/* Free any preallocated blocks. */ /* Free any preallocated blocks. */
...@@ -805,18 +827,13 @@ affs_truncate(struct inode *inode) ...@@ -805,18 +827,13 @@ affs_truncate(struct inode *inode)
if (inode->i_size > AFFS_I(inode)->mmu_private) { if (inode->i_size > AFFS_I(inode)->mmu_private) {
struct address_space *mapping = inode->i_mapping; struct address_space *mapping = inode->i_mapping;
struct page *page; struct page *page;
u32 size = inode->i_size - 1; void *fsdata;
u32 size = inode->i_size;
int res; int res;
page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT); res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
if (!page)
return;
size = (size & (PAGE_CACHE_SIZE - 1)) + 1;
res = mapping->a_ops->prepare_write(NULL, page, size, size);
if (!res) if (!res)
res = mapping->a_ops->commit_write(NULL, page, size, size); res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
unlock_page(page);
page_cache_release(page);
mark_inode_dirty(inode); mark_inode_dirty(inode);
return; return;
} else if (inode->i_size == AFFS_I(inode)->mmu_private) } else if (inode->i_size == AFFS_I(inode)->mmu_private)
......
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