diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-10-02 08:45:08 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-10-02 08:45:08 -0400 |
commit | 59458f40e25915a355d8b1d701425fe9f4f9ea23 (patch) | |
tree | f1c9a2934df686e36d75f759ab7313b6f0e0e5f9 /mm/filemap.c | |
parent | 825f9075d74028d11d7f5932f04e1b5db3022b51 (diff) | |
parent | d834c16516d1ebec4766fc58c059bf01311e6045 (diff) |
Merge branch 'master' into gfs2
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 186 |
1 files changed, 53 insertions, 133 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 87d4a398cd16..fef7d879ddf5 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 | ||
@@ -1225,33 +1226,8 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1225 | out: | 1226 | out: |
1226 | return retval; | 1227 | return retval; |
1227 | } | 1228 | } |
1228 | EXPORT_SYMBOL(__generic_file_aio_read); | ||
1229 | |||
1230 | ssize_t | ||
1231 | generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) | ||
1232 | { | ||
1233 | struct iovec local_iov = { .iov_base = buf, .iov_len = count }; | ||
1234 | |||
1235 | BUG_ON(iocb->ki_pos != pos); | ||
1236 | return __generic_file_aio_read(iocb, &local_iov, 1, &iocb->ki_pos); | ||
1237 | } | ||
1238 | EXPORT_SYMBOL(generic_file_aio_read); | 1229 | EXPORT_SYMBOL(generic_file_aio_read); |
1239 | 1230 | ||
1240 | ssize_t | ||
1241 | generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | ||
1242 | { | ||
1243 | struct iovec local_iov = { .iov_base = buf, .iov_len = count }; | ||
1244 | struct kiocb kiocb; | ||
1245 | ssize_t ret; | ||
1246 | |||
1247 | init_sync_kiocb(&kiocb, filp); | ||
1248 | ret = __generic_file_aio_read(&kiocb, &local_iov, 1, ppos); | ||
1249 | if (-EIOCBQUEUED == ret) | ||
1250 | ret = wait_on_sync_kiocb(&kiocb); | ||
1251 | return ret; | ||
1252 | } | ||
1253 | EXPORT_SYMBOL(generic_file_read); | ||
1254 | |||
1255 | int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) | 1231 | int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) |
1256 | { | 1232 | { |
1257 | ssize_t written; | 1233 | ssize_t written; |
@@ -1473,7 +1449,7 @@ outside_data_content: | |||
1473 | * accessible.. | 1449 | * accessible.. |
1474 | */ | 1450 | */ |
1475 | if (area->vm_mm == current->mm) | 1451 | if (area->vm_mm == current->mm) |
1476 | return NULL; | 1452 | return NOPAGE_SIGBUS; |
1477 | /* Fall through to the non-read-ahead case */ | 1453 | /* Fall through to the non-read-ahead case */ |
1478 | no_cached_page: | 1454 | no_cached_page: |
1479 | /* | 1455 | /* |
@@ -1498,7 +1474,7 @@ no_cached_page: | |||
1498 | */ | 1474 | */ |
1499 | if (error == -ENOMEM) | 1475 | if (error == -ENOMEM) |
1500 | return NOPAGE_OOM; | 1476 | return NOPAGE_OOM; |
1501 | return NULL; | 1477 | return NOPAGE_SIGBUS; |
1502 | 1478 | ||
1503 | page_not_uptodate: | 1479 | page_not_uptodate: |
1504 | if (!did_readaround) { | 1480 | if (!did_readaround) { |
@@ -1567,7 +1543,7 @@ page_not_uptodate: | |||
1567 | */ | 1543 | */ |
1568 | shrink_readahead_size_eio(file, ra); | 1544 | shrink_readahead_size_eio(file, ra); |
1569 | page_cache_release(page); | 1545 | page_cache_release(page); |
1570 | return NULL; | 1546 | return NOPAGE_SIGBUS; |
1571 | } | 1547 | } |
1572 | EXPORT_SYMBOL(filemap_nopage); | 1548 | EXPORT_SYMBOL(filemap_nopage); |
1573 | 1549 | ||
@@ -2022,6 +1998,7 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i | |||
2022 | if (unlikely(*pos + *count > inode->i_sb->s_maxbytes)) | 1998 | if (unlikely(*pos + *count > inode->i_sb->s_maxbytes)) |
2023 | *count = inode->i_sb->s_maxbytes - *pos; | 1999 | *count = inode->i_sb->s_maxbytes - *pos; |
2024 | } else { | 2000 | } else { |
2001 | #ifdef CONFIG_BLOCK | ||
2025 | loff_t isize; | 2002 | loff_t isize; |
2026 | if (bdev_read_only(I_BDEV(inode))) | 2003 | if (bdev_read_only(I_BDEV(inode))) |
2027 | return -EPERM; | 2004 | return -EPERM; |
@@ -2033,6 +2010,9 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i | |||
2033 | 2010 | ||
2034 | if (*pos + *count > isize) | 2011 | if (*pos + *count > isize) |
2035 | *count = isize - *pos; | 2012 | *count = isize - *pos; |
2013 | #else | ||
2014 | return -EPERM; | ||
2015 | #endif | ||
2036 | } | 2016 | } |
2037 | return 0; | 2017 | return 0; |
2038 | } | 2018 | } |
@@ -2313,22 +2293,22 @@ out: | |||
2313 | current->backing_dev_info = NULL; | 2293 | current->backing_dev_info = NULL; |
2314 | return written ? written : err; | 2294 | return written ? written : err; |
2315 | } | 2295 | } |
2316 | EXPORT_SYMBOL(generic_file_aio_write_nolock); | ||
2317 | 2296 | ||
2318 | ssize_t | 2297 | ssize_t generic_file_aio_write_nolock(struct kiocb *iocb, |
2319 | generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, | 2298 | const struct iovec *iov, unsigned long nr_segs, loff_t pos) |
2320 | unsigned long nr_segs, loff_t *ppos) | ||
2321 | { | 2299 | { |
2322 | struct file *file = iocb->ki_filp; | 2300 | struct file *file = iocb->ki_filp; |
2323 | struct address_space *mapping = file->f_mapping; | 2301 | struct address_space *mapping = file->f_mapping; |
2324 | struct inode *inode = mapping->host; | 2302 | struct inode *inode = mapping->host; |
2325 | ssize_t ret; | 2303 | ssize_t ret; |
2326 | loff_t pos = *ppos; | ||
2327 | 2304 | ||
2328 | ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, ppos); | 2305 | BUG_ON(iocb->ki_pos != pos); |
2306 | |||
2307 | ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, | ||
2308 | &iocb->ki_pos); | ||
2329 | 2309 | ||
2330 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2310 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
2331 | int err; | 2311 | ssize_t err; |
2332 | 2312 | ||
2333 | err = sync_page_range_nolock(inode, mapping, pos, ret); | 2313 | err = sync_page_range_nolock(inode, mapping, pos, ret); |
2334 | if (err < 0) | 2314 | if (err < 0) |
@@ -2336,51 +2316,21 @@ generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, | |||
2336 | } | 2316 | } |
2337 | return ret; | 2317 | return ret; |
2338 | } | 2318 | } |
2319 | EXPORT_SYMBOL(generic_file_aio_write_nolock); | ||
2339 | 2320 | ||
2340 | static ssize_t | 2321 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
2341 | __generic_file_write_nolock(struct file *file, const struct iovec *iov, | 2322 | unsigned long nr_segs, loff_t pos) |
2342 | unsigned long nr_segs, loff_t *ppos) | ||
2343 | { | ||
2344 | struct kiocb kiocb; | ||
2345 | ssize_t ret; | ||
2346 | |||
2347 | init_sync_kiocb(&kiocb, file); | ||
2348 | ret = __generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos); | ||
2349 | if (ret == -EIOCBQUEUED) | ||
2350 | ret = wait_on_sync_kiocb(&kiocb); | ||
2351 | return ret; | ||
2352 | } | ||
2353 | |||
2354 | ssize_t | ||
2355 | generic_file_write_nolock(struct file *file, const struct iovec *iov, | ||
2356 | unsigned long nr_segs, loff_t *ppos) | ||
2357 | { | ||
2358 | struct kiocb kiocb; | ||
2359 | ssize_t ret; | ||
2360 | |||
2361 | init_sync_kiocb(&kiocb, file); | ||
2362 | ret = generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos); | ||
2363 | if (-EIOCBQUEUED == ret) | ||
2364 | ret = wait_on_sync_kiocb(&kiocb); | ||
2365 | return ret; | ||
2366 | } | ||
2367 | EXPORT_SYMBOL(generic_file_write_nolock); | ||
2368 | |||
2369 | ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf, | ||
2370 | size_t count, loff_t pos) | ||
2371 | { | 2323 | { |
2372 | struct file *file = iocb->ki_filp; | 2324 | struct file *file = iocb->ki_filp; |
2373 | struct address_space *mapping = file->f_mapping; | 2325 | struct address_space *mapping = file->f_mapping; |
2374 | struct inode *inode = mapping->host; | 2326 | struct inode *inode = mapping->host; |
2375 | ssize_t ret; | 2327 | ssize_t ret; |
2376 | struct iovec local_iov = { .iov_base = (void __user *)buf, | ||
2377 | .iov_len = count }; | ||
2378 | 2328 | ||
2379 | BUG_ON(iocb->ki_pos != pos); | 2329 | BUG_ON(iocb->ki_pos != pos); |
2380 | 2330 | ||
2381 | mutex_lock(&inode->i_mutex); | 2331 | mutex_lock(&inode->i_mutex); |
2382 | ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1, | 2332 | ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, |
2383 | &iocb->ki_pos); | 2333 | &iocb->ki_pos); |
2384 | mutex_unlock(&inode->i_mutex); | 2334 | mutex_unlock(&inode->i_mutex); |
2385 | 2335 | ||
2386 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2336 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
@@ -2394,66 +2344,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf, | |||
2394 | } | 2344 | } |
2395 | EXPORT_SYMBOL(generic_file_aio_write); | 2345 | EXPORT_SYMBOL(generic_file_aio_write); |
2396 | 2346 | ||
2397 | ssize_t generic_file_write(struct file *file, const char __user *buf, | ||
2398 | size_t count, loff_t *ppos) | ||
2399 | { | ||
2400 | struct address_space *mapping = file->f_mapping; | ||
2401 | struct inode *inode = mapping->host; | ||
2402 | ssize_t ret; | ||
2403 | struct iovec local_iov = { .iov_base = (void __user *)buf, | ||
2404 | .iov_len = count }; | ||
2405 | |||
2406 | mutex_lock(&inode->i_mutex); | ||
2407 | ret = __generic_file_write_nolock(file, &local_iov, 1, ppos); | ||
2408 | mutex_unlock(&inode->i_mutex); | ||
2409 | |||
2410 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
2411 | ssize_t err; | ||
2412 | |||
2413 | err = sync_page_range(inode, mapping, *ppos - ret, ret); | ||
2414 | if (err < 0) | ||
2415 | ret = err; | ||
2416 | } | ||
2417 | return ret; | ||
2418 | } | ||
2419 | EXPORT_SYMBOL(generic_file_write); | ||
2420 | |||
2421 | ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, | ||
2422 | unsigned long nr_segs, loff_t *ppos) | ||
2423 | { | ||
2424 | struct kiocb kiocb; | ||
2425 | ssize_t ret; | ||
2426 | |||
2427 | init_sync_kiocb(&kiocb, filp); | ||
2428 | ret = __generic_file_aio_read(&kiocb, iov, nr_segs, ppos); | ||
2429 | if (-EIOCBQUEUED == ret) | ||
2430 | ret = wait_on_sync_kiocb(&kiocb); | ||
2431 | return ret; | ||
2432 | } | ||
2433 | EXPORT_SYMBOL(generic_file_readv); | ||
2434 | |||
2435 | ssize_t generic_file_writev(struct file *file, const struct iovec *iov, | ||
2436 | unsigned long nr_segs, loff_t *ppos) | ||
2437 | { | ||
2438 | struct address_space *mapping = file->f_mapping; | ||
2439 | struct inode *inode = mapping->host; | ||
2440 | ssize_t ret; | ||
2441 | |||
2442 | mutex_lock(&inode->i_mutex); | ||
2443 | ret = __generic_file_write_nolock(file, iov, nr_segs, ppos); | ||
2444 | mutex_unlock(&inode->i_mutex); | ||
2445 | |||
2446 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
2447 | int err; | ||
2448 | |||
2449 | err = sync_page_range(inode, mapping, *ppos - ret, ret); | ||
2450 | if (err < 0) | ||
2451 | ret = err; | ||
2452 | } | ||
2453 | return ret; | ||
2454 | } | ||
2455 | EXPORT_SYMBOL(generic_file_writev); | ||
2456 | |||
2457 | /* | 2347 | /* |
2458 | * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something | 2348 | * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something |
2459 | * went wrong during pagecache shootdown. | 2349 | * went wrong during pagecache shootdown. |
@@ -2493,3 +2383,33 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
2493 | } | 2383 | } |
2494 | return retval; | 2384 | return retval; |
2495 | } | 2385 | } |
2386 | |||
2387 | /** | ||
2388 | * try_to_release_page() - release old fs-specific metadata on a page | ||
2389 | * | ||
2390 | * @page: the page which the kernel is trying to free | ||
2391 | * @gfp_mask: memory allocation flags (and I/O mode) | ||
2392 | * | ||
2393 | * The address_space is to try to release any data against the page | ||
2394 | * (presumably at page->private). If the release was successful, return `1'. | ||
2395 | * Otherwise return zero. | ||
2396 | * | ||
2397 | * The @gfp_mask argument specifies whether I/O may be performed to release | ||
2398 | * this page (__GFP_IO), and whether the call may block (__GFP_WAIT). | ||
2399 | * | ||
2400 | * NOTE: @gfp_mask may go away, and this function may become non-blocking. | ||
2401 | */ | ||
2402 | int try_to_release_page(struct page *page, gfp_t gfp_mask) | ||
2403 | { | ||
2404 | struct address_space * const mapping = page->mapping; | ||
2405 | |||
2406 | BUG_ON(!PageLocked(page)); | ||
2407 | if (PageWriteback(page)) | ||
2408 | return 0; | ||
2409 | |||
2410 | if (mapping && mapping->a_ops->releasepage) | ||
2411 | return mapping->a_ops->releasepage(page, gfp_mask); | ||
2412 | return try_to_free_buffers(page); | ||
2413 | } | ||
2414 | |||
2415 | EXPORT_SYMBOL(try_to_release_page); | ||