diff options
author | Jan Kara <jack@suse.cz> | 2009-08-17 12:10:06 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2009-09-14 11:08:14 -0400 |
commit | e4dd9de3c66bc7e26c5c7f149a060c5a67cf06a0 (patch) | |
tree | 3270180b085c86afe4834fba5567464cd3932eb8 | |
parent | d3bccb6f4b886060aa0f58976b92b77d951f5434 (diff) |
vfs: Export __generic_file_aio_write() and add some comments
Rename __generic_file_aio_write_nolock() to __generic_file_aio_write(), add
comments to write helpers explaining how they should be used and export
__generic_file_aio_write() since it will be used by some filesystems.
CC: ocfs2-devel@oss.oracle.com
CC: Joel Becker <joel.becker@oracle.com>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | include/linux/fs.h | 2 | ||||
-rw-r--r-- | mm/filemap.c | 57 |
2 files changed, 52 insertions, 7 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index beb0e2774b2e..ea099d3a18d9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2204,6 +2204,8 @@ extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); | |||
2204 | extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); | 2204 | extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); |
2205 | int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); | 2205 | int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); |
2206 | extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); | 2206 | extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); |
2207 | extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, | ||
2208 | loff_t *); | ||
2207 | extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); | 2209 | extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); |
2208 | extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *, | 2210 | extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *, |
2209 | unsigned long, loff_t); | 2211 | unsigned long, loff_t); |
diff --git a/mm/filemap.c b/mm/filemap.c index 65b2e50efcd0..554a396d85e2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -2368,9 +2368,27 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2368 | } | 2368 | } |
2369 | EXPORT_SYMBOL(generic_file_buffered_write); | 2369 | EXPORT_SYMBOL(generic_file_buffered_write); |
2370 | 2370 | ||
2371 | static ssize_t | 2371 | /** |
2372 | __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, | 2372 | * __generic_file_aio_write - write data to a file |
2373 | unsigned long nr_segs, loff_t *ppos) | 2373 | * @iocb: IO state structure (file, offset, etc.) |
2374 | * @iov: vector with data to write | ||
2375 | * @nr_segs: number of segments in the vector | ||
2376 | * @ppos: position where to write | ||
2377 | * | ||
2378 | * This function does all the work needed for actually writing data to a | ||
2379 | * file. It does all basic checks, removes SUID from the file, updates | ||
2380 | * modification times and calls proper subroutines depending on whether we | ||
2381 | * do direct IO or a standard buffered write. | ||
2382 | * | ||
2383 | * It expects i_mutex to be grabbed unless we work on a block device or similar | ||
2384 | * object which does not need locking at all. | ||
2385 | * | ||
2386 | * This function does *not* take care of syncing data in case of O_SYNC write. | ||
2387 | * A caller has to handle it. This is mainly due to the fact that we want to | ||
2388 | * avoid syncing under i_mutex. | ||
2389 | */ | ||
2390 | ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||
2391 | unsigned long nr_segs, loff_t *ppos) | ||
2374 | { | 2392 | { |
2375 | struct file *file = iocb->ki_filp; | 2393 | struct file *file = iocb->ki_filp; |
2376 | struct address_space * mapping = file->f_mapping; | 2394 | struct address_space * mapping = file->f_mapping; |
@@ -2467,7 +2485,23 @@ out: | |||
2467 | current->backing_dev_info = NULL; | 2485 | current->backing_dev_info = NULL; |
2468 | return written ? written : err; | 2486 | return written ? written : err; |
2469 | } | 2487 | } |
2488 | EXPORT_SYMBOL(__generic_file_aio_write); | ||
2489 | |||
2470 | 2490 | ||
2491 | /** | ||
2492 | * generic_file_aio_write_nolock - write data, usually to a device | ||
2493 | * @iocb: IO state structure | ||
2494 | * @iov: vector with data to write | ||
2495 | * @nr_segs: number of segments in the vector | ||
2496 | * @pos: position in file where to write | ||
2497 | * | ||
2498 | * This is a wrapper around __generic_file_aio_write() which takes care of | ||
2499 | * syncing the file in case of O_SYNC file. It does not take i_mutex for the | ||
2500 | * write itself but may do so during syncing. It is meant for users like block | ||
2501 | * devices which do not need i_mutex during write. If your filesystem needs to | ||
2502 | * do a write but already holds i_mutex, use __generic_file_aio_write() | ||
2503 | * directly and then sync the file like generic_file_aio_write(). | ||
2504 | */ | ||
2471 | ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, | 2505 | ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, |
2472 | const struct iovec *iov, unsigned long nr_segs, loff_t pos) | 2506 | const struct iovec *iov, unsigned long nr_segs, loff_t pos) |
2473 | { | 2507 | { |
@@ -2478,8 +2512,7 @@ ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, | |||
2478 | 2512 | ||
2479 | BUG_ON(iocb->ki_pos != pos); | 2513 | BUG_ON(iocb->ki_pos != pos); |
2480 | 2514 | ||
2481 | ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, | 2515 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
2482 | &iocb->ki_pos); | ||
2483 | 2516 | ||
2484 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2517 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
2485 | ssize_t err; | 2518 | ssize_t err; |
@@ -2492,6 +2525,17 @@ ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, | |||
2492 | } | 2525 | } |
2493 | EXPORT_SYMBOL(generic_file_aio_write_nolock); | 2526 | EXPORT_SYMBOL(generic_file_aio_write_nolock); |
2494 | 2527 | ||
2528 | /** | ||
2529 | * generic_file_aio_write - write data to a file | ||
2530 | * @iocb: IO state structure | ||
2531 | * @iov: vector with data to write | ||
2532 | * @nr_segs: number of segments in the vector | ||
2533 | * @pos: position in file where to write | ||
2534 | * | ||
2535 | * This is a wrapper around __generic_file_aio_write() to be used by most | ||
2536 | * filesystems. It takes care of syncing the file in case of O_SYNC file | ||
2537 | * and acquires i_mutex as needed. | ||
2538 | */ | ||
2495 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2539 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
2496 | unsigned long nr_segs, loff_t pos) | 2540 | unsigned long nr_segs, loff_t pos) |
2497 | { | 2541 | { |
@@ -2503,8 +2547,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2503 | BUG_ON(iocb->ki_pos != pos); | 2547 | BUG_ON(iocb->ki_pos != pos); |
2504 | 2548 | ||
2505 | mutex_lock(&inode->i_mutex); | 2549 | mutex_lock(&inode->i_mutex); |
2506 | ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, | 2550 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
2507 | &iocb->ki_pos); | ||
2508 | mutex_unlock(&inode->i_mutex); | 2551 | mutex_unlock(&inode->i_mutex); |
2509 | 2552 | ||
2510 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2553 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |