mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-06 14:31:46 +00:00
fs: introduce write_begin, write_end, and perform_write aops
These are intended to replace prepare_write and commit_write with more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (which prepare_write is unable to do). [mark.fasheh@oracle.com: API design contributions, code review and fixes] [akpm@linux-foundation.org: various fixes] [dmonakhov@sw.ru: new aop block_write_begin fix] Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com> Signed-off-by: Dmitriy Monakhov <dmonakhov@openvz.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
637aff46f9
commit
afddba49d1
11 changed files with 575 additions and 206 deletions
44
fs/libfs.c
44
fs/libfs.c
|
@ -351,6 +351,26 @@ int simple_prepare_write(struct file *file, struct page *page,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int simple_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata)
|
||||
{
|
||||
struct page *page;
|
||||
pgoff_t index;
|
||||
unsigned from;
|
||||
|
||||
index = pos >> PAGE_CACHE_SHIFT;
|
||||
from = pos & (PAGE_CACHE_SIZE - 1);
|
||||
|
||||
page = __grab_cache_page(mapping, index);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
*pagep = page;
|
||||
|
||||
return simple_prepare_write(file, page, from, from+len);
|
||||
}
|
||||
|
||||
int simple_commit_write(struct file *file, struct page *page,
|
||||
unsigned from, unsigned to)
|
||||
{
|
||||
|
@ -369,6 +389,28 @@ int simple_commit_write(struct file *file, struct page *page,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int simple_write_end(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata)
|
||||
{
|
||||
unsigned from = pos & (PAGE_CACHE_SIZE - 1);
|
||||
|
||||
/* zero the stale part of the page if we did a short copy */
|
||||
if (copied < len) {
|
||||
void *kaddr = kmap_atomic(page, KM_USER0);
|
||||
memset(kaddr + from + copied, 0, len - copied);
|
||||
flush_dcache_page(page);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
}
|
||||
|
||||
simple_commit_write(file, page, from, from+copied);
|
||||
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
/*
|
||||
* the inodes created here are not hashed. If you use iunique to generate
|
||||
* unique inode values later for this filesystem, then you must take care
|
||||
|
@ -642,6 +684,8 @@ EXPORT_SYMBOL(dcache_dir_open);
|
|||
EXPORT_SYMBOL(dcache_readdir);
|
||||
EXPORT_SYMBOL(generic_read_dir);
|
||||
EXPORT_SYMBOL(get_sb_pseudo);
|
||||
EXPORT_SYMBOL(simple_write_begin);
|
||||
EXPORT_SYMBOL(simple_write_end);
|
||||
EXPORT_SYMBOL(simple_commit_write);
|
||||
EXPORT_SYMBOL(simple_dir_inode_operations);
|
||||
EXPORT_SYMBOL(simple_dir_operations);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue