diff options
author | Badari Pulavarty <pbadari@us.ibm.com> | 2006-10-01 02:28:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-01 03:39:28 -0400 |
commit | 543ade1fc901db4c3dbe9fb27241fb977f1f3eea (patch) | |
tree | cdd1a1f67a718adf71e92fe08e4b3d33bf3dbadc /mm | |
parent | ee0b3e671baff681d69fbf0db33b47603c0a8280 (diff) |
[PATCH] Streamline generic_file_* interfaces and filemap cleanups
This patch cleans up generic_file_*_read/write() interfaces. Christoph
Hellwig gave me the idea for this clean ups.
In a nutshell, all filesystems should set .aio_read/.aio_write methods and use
do_sync_read/ do_sync_write() as their .read/.write methods. This allows us
to cleanup all variants of generic_file_* routines.
Final available interfaces:
generic_file_aio_read() - read handler
generic_file_aio_write() - write handler
generic_file_aio_write_nolock() - no lock write handler
__generic_file_aio_write_nolock() - internal worker routine
Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 87 |
1 files changed, 4 insertions, 83 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 48497094ae83..ec469235985d 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1149,13 +1149,14 @@ success: | |||
1149 | * that can use the page cache directly. | 1149 | * that can use the page cache directly. |
1150 | */ | 1150 | */ |
1151 | ssize_t | 1151 | ssize_t |
1152 | __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | 1152 | generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, |
1153 | unsigned long nr_segs, loff_t *ppos) | 1153 | unsigned long nr_segs, loff_t pos) |
1154 | { | 1154 | { |
1155 | struct file *filp = iocb->ki_filp; | 1155 | struct file *filp = iocb->ki_filp; |
1156 | ssize_t retval; | 1156 | ssize_t retval; |
1157 | unsigned long seg; | 1157 | unsigned long seg; |
1158 | size_t count; | 1158 | size_t count; |
1159 | loff_t *ppos = &iocb->ki_pos; | ||
1159 | 1160 | ||
1160 | count = 0; | 1161 | count = 0; |
1161 | for (seg = 0; seg < nr_segs; seg++) { | 1162 | for (seg = 0; seg < nr_segs; seg++) { |
@@ -1179,7 +1180,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1179 | 1180 | ||
1180 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ | 1181 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ |
1181 | if (filp->f_flags & O_DIRECT) { | 1182 | if (filp->f_flags & O_DIRECT) { |
1182 | loff_t pos = *ppos, size; | 1183 | loff_t size; |
1183 | struct address_space *mapping; | 1184 | struct address_space *mapping; |
1184 | struct inode *inode; | 1185 | struct inode *inode; |
1185 | 1186 | ||
@@ -1223,32 +1224,8 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1223 | out: | 1224 | out: |
1224 | return retval; | 1225 | return retval; |
1225 | } | 1226 | } |
1226 | EXPORT_SYMBOL(__generic_file_aio_read); | ||
1227 | |||
1228 | ssize_t | ||
1229 | generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | ||
1230 | unsigned long nr_segs, loff_t pos) | ||
1231 | { | ||
1232 | BUG_ON(iocb->ki_pos != pos); | ||
1233 | return __generic_file_aio_read(iocb, iov, nr_segs, &iocb->ki_pos); | ||
1234 | } | ||
1235 | EXPORT_SYMBOL(generic_file_aio_read); | 1227 | EXPORT_SYMBOL(generic_file_aio_read); |
1236 | 1228 | ||
1237 | ssize_t | ||
1238 | generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | ||
1239 | { | ||
1240 | struct iovec local_iov = { .iov_base = buf, .iov_len = count }; | ||
1241 | struct kiocb kiocb; | ||
1242 | ssize_t ret; | ||
1243 | |||
1244 | init_sync_kiocb(&kiocb, filp); | ||
1245 | ret = __generic_file_aio_read(&kiocb, &local_iov, 1, ppos); | ||
1246 | if (-EIOCBQUEUED == ret) | ||
1247 | ret = wait_on_sync_kiocb(&kiocb); | ||
1248 | return ret; | ||
1249 | } | ||
1250 | EXPORT_SYMBOL(generic_file_read); | ||
1251 | |||
1252 | int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) | 1229 | int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) |
1253 | { | 1230 | { |
1254 | ssize_t written; | 1231 | ssize_t written; |
@@ -2339,38 +2316,6 @@ ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, | |||
2339 | } | 2316 | } |
2340 | EXPORT_SYMBOL(generic_file_aio_write_nolock); | 2317 | EXPORT_SYMBOL(generic_file_aio_write_nolock); |
2341 | 2318 | ||
2342 | static ssize_t | ||
2343 | __generic_file_write_nolock(struct file *file, const struct iovec *iov, | ||
2344 | unsigned long nr_segs, loff_t *ppos) | ||
2345 | { | ||
2346 | struct kiocb kiocb; | ||
2347 | ssize_t ret; | ||
2348 | |||
2349 | init_sync_kiocb(&kiocb, file); | ||
2350 | kiocb.ki_pos = *ppos; | ||
2351 | ret = __generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos); | ||
2352 | if (-EIOCBQUEUED == ret) | ||
2353 | ret = wait_on_sync_kiocb(&kiocb); | ||
2354 | return ret; | ||
2355 | } | ||
2356 | |||
2357 | ssize_t | ||
2358 | generic_file_write_nolock(struct file *file, const struct iovec *iov, | ||
2359 | unsigned long nr_segs, loff_t *ppos) | ||
2360 | { | ||
2361 | struct kiocb kiocb; | ||
2362 | ssize_t ret; | ||
2363 | |||
2364 | init_sync_kiocb(&kiocb, file); | ||
2365 | kiocb.ki_pos = *ppos; | ||
2366 | ret = generic_file_aio_write_nolock(&kiocb, iov, nr_segs, *ppos); | ||
2367 | if (-EIOCBQUEUED == ret) | ||
2368 | ret = wait_on_sync_kiocb(&kiocb); | ||
2369 | *ppos = kiocb.ki_pos; | ||
2370 | return ret; | ||
2371 | } | ||
2372 | EXPORT_SYMBOL(generic_file_write_nolock); | ||
2373 | |||
2374 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2319 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
2375 | unsigned long nr_segs, loff_t pos) | 2320 | unsigned long nr_segs, loff_t pos) |
2376 | { | 2321 | { |
@@ -2397,30 +2342,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2397 | } | 2342 | } |
2398 | EXPORT_SYMBOL(generic_file_aio_write); | 2343 | EXPORT_SYMBOL(generic_file_aio_write); |
2399 | 2344 | ||
2400 | ssize_t generic_file_write(struct file *file, const char __user *buf, | ||
2401 | size_t count, loff_t *ppos) | ||
2402 | { | ||
2403 | struct address_space *mapping = file->f_mapping; | ||
2404 | struct inode *inode = mapping->host; | ||
2405 | ssize_t ret; | ||
2406 | struct iovec local_iov = { .iov_base = (void __user *)buf, | ||
2407 | .iov_len = count }; | ||
2408 | |||
2409 | mutex_lock(&inode->i_mutex); | ||
2410 | ret = __generic_file_write_nolock(file, &local_iov, 1, ppos); | ||
2411 | mutex_unlock(&inode->i_mutex); | ||
2412 | |||
2413 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
2414 | ssize_t err; | ||
2415 | |||
2416 | err = sync_page_range(inode, mapping, *ppos - ret, ret); | ||
2417 | if (err < 0) | ||
2418 | ret = err; | ||
2419 | } | ||
2420 | return ret; | ||
2421 | } | ||
2422 | EXPORT_SYMBOL(generic_file_write); | ||
2423 | |||
2424 | /* | 2345 | /* |
2425 | * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something | 2346 | * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something |
2426 | * went wrong during pagecache shootdown. | 2347 | * went wrong during pagecache shootdown. |