aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-08-17 12:10:06 -0400
committerJan Kara <jack@suse.cz>2009-09-14 11:08:14 -0400
commite4dd9de3c66bc7e26c5c7f149a060c5a67cf06a0 (patch)
tree3270180b085c86afe4834fba5567464cd3932eb8
parentd3bccb6f4b886060aa0f58976b92b77d951f5434 (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.h2
-rw-r--r--mm/filemap.c57
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 *);
2204extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); 2204extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
2205int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); 2205int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
2206extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); 2206extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
2207extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long,
2208 loff_t *);
2207extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); 2209extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
2208extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *, 2210extern 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}
2369EXPORT_SYMBOL(generic_file_buffered_write); 2369EXPORT_SYMBOL(generic_file_buffered_write);
2370 2370
2371static 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 */
2390ssize_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}
2488EXPORT_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 */
2471ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, 2505ssize_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}
2493EXPORT_SYMBOL(generic_file_aio_write_nolock); 2526EXPORT_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 */
2495ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 2539ssize_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))) {