mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 16:41:25 +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
|
@ -178,15 +178,18 @@ prototypes:
|
|||
locking rules:
|
||||
All except set_page_dirty may block
|
||||
|
||||
BKL PageLocked(page)
|
||||
BKL PageLocked(page) i_sem
|
||||
writepage: no yes, unlocks (see below)
|
||||
readpage: no yes, unlocks
|
||||
sync_page: no maybe
|
||||
writepages: no
|
||||
set_page_dirty no no
|
||||
readpages: no
|
||||
prepare_write: no yes
|
||||
commit_write: no yes
|
||||
prepare_write: no yes yes
|
||||
commit_write: no yes yes
|
||||
write_begin: no locks the page yes
|
||||
write_end: no yes, unlocks yes
|
||||
perform_write: no n/a yes
|
||||
bmap: yes
|
||||
invalidatepage: no yes
|
||||
releasepage: no yes
|
||||
|
|
|
@ -537,6 +537,12 @@ struct address_space_operations {
|
|||
struct list_head *pages, unsigned nr_pages);
|
||||
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
|
||||
int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
|
||||
int (*write_begin)(struct file *, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata);
|
||||
int (*write_end)(struct file *, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata);
|
||||
sector_t (*bmap)(struct address_space *, sector_t);
|
||||
int (*invalidatepage) (struct page *, unsigned long);
|
||||
int (*releasepage) (struct page *, int);
|
||||
|
@ -633,6 +639,45 @@ struct address_space_operations {
|
|||
operations. It should avoid returning an error if possible -
|
||||
errors should have been handled by prepare_write.
|
||||
|
||||
write_begin: This is intended as a replacement for prepare_write. The
|
||||
key differences being that:
|
||||
- it returns a locked page (in *pagep) rather than being
|
||||
given a pre locked page;
|
||||
- it must be able to cope with short writes (where the
|
||||
length passed to write_begin is greater than the number
|
||||
of bytes copied into the page).
|
||||
|
||||
Called by the generic buffered write code to ask the filesystem to
|
||||
prepare to write len bytes at the given offset in the file. The
|
||||
address_space should check that the write will be able to complete,
|
||||
by allocating space if necessary and doing any other internal
|
||||
housekeeping. If the write will update parts of any basic-blocks on
|
||||
storage, then those blocks should be pre-read (if they haven't been
|
||||
read already) so that the updated blocks can be written out properly.
|
||||
|
||||
The filesystem must return the locked pagecache page for the specified
|
||||
offset, in *pagep, for the caller to write into.
|
||||
|
||||
flags is a field for AOP_FLAG_xxx flags, described in
|
||||
include/linux/fs.h.
|
||||
|
||||
A void * may be returned in fsdata, which then gets passed into
|
||||
write_end.
|
||||
|
||||
Returns 0 on success; < 0 on failure (which is the error code), in
|
||||
which case write_end is not called.
|
||||
|
||||
write_end: After a successful write_begin, and data copy, write_end must
|
||||
be called. len is the original len passed to write_begin, and copied
|
||||
is the amount that was able to be copied (copied == len is always true
|
||||
if write_begin was called with the AOP_FLAG_UNINTERRUPTIBLE flag).
|
||||
|
||||
The filesystem must take care of unlocking the page and releasing it
|
||||
refcount, and updating i_size.
|
||||
|
||||
Returns < 0 on failure, otherwise the number of bytes (<= 'copied')
|
||||
that were able to be copied into pagecache.
|
||||
|
||||
bmap: called by the VFS to map a logical block offset within object to
|
||||
physical block number. This method is used by the FIBMAP
|
||||
ioctl and for working with swap-files. To be able to swap to
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue