aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-10-02 08:45:08 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-10-02 08:45:08 -0400
commit59458f40e25915a355d8b1d701425fe9f4f9ea23 (patch)
treef1c9a2934df686e36d75f759ab7313b6f0e0e5f9 /mm/filemap.c
parent825f9075d74028d11d7f5932f04e1b5db3022b51 (diff)
parentd834c16516d1ebec4766fc58c059bf01311e6045 (diff)
Merge branch 'master' into gfs2
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c186
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 */
1151ssize_t 1151ssize_t
1152__generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, 1152generic_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,
1225out: 1226out:
1226 return retval; 1227 return retval;
1227} 1228}
1228EXPORT_SYMBOL(__generic_file_aio_read);
1229
1230ssize_t
1231generic_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}
1238EXPORT_SYMBOL(generic_file_aio_read); 1229EXPORT_SYMBOL(generic_file_aio_read);
1239 1230
1240ssize_t
1241generic_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}
1253EXPORT_SYMBOL(generic_file_read);
1254
1255int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) 1231int 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 */
1478no_cached_page: 1454no_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
1503page_not_uptodate: 1479page_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}
1572EXPORT_SYMBOL(filemap_nopage); 1548EXPORT_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}
2316EXPORT_SYMBOL(generic_file_aio_write_nolock);
2317 2296
2318ssize_t 2297ssize_t generic_file_aio_write_nolock(struct kiocb *iocb,
2319generic_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}
2319EXPORT_SYMBOL(generic_file_aio_write_nolock);
2339 2320
2340static ssize_t 2321ssize_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
2354ssize_t
2355generic_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}
2367EXPORT_SYMBOL(generic_file_write_nolock);
2368
2369ssize_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}
2395EXPORT_SYMBOL(generic_file_aio_write); 2345EXPORT_SYMBOL(generic_file_aio_write);
2396 2346
2397ssize_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}
2419EXPORT_SYMBOL(generic_file_write);
2420
2421ssize_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}
2433EXPORT_SYMBOL(generic_file_readv);
2434
2435ssize_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}
2455EXPORT_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 */
2402int 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
2415EXPORT_SYMBOL(try_to_release_page);