Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 23433
b: refs/heads/master
c: ebcf28e
h: refs/heads/master
i:
  23431: 06868df
v: v3
  • Loading branch information
Andrew Morton authored and Linus Torvalds committed Mar 24, 2006
1 parent 813152d commit 02c9a46
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 469eb4d03878b676418f853011ebfb54ccf83a5e
refs/heads/master: ebcf28e1c7a295f3321249dd235ad2e45938fdd9
6 changes: 6 additions & 0 deletions trunk/include/linux/fadvise.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif

/*
* Linux-specific fadvise() extensions:
*/
#define LINUX_FADV_ASYNC_WRITE 32 /* Start writeout on range */
#define LINUX_FADV_WRITE_WAIT 33 /* Wait upon writeout to range */

#endif /* FADVISE_H_INCLUDED */
5 changes: 5 additions & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,11 @@ extern int filemap_fdatawait(struct address_space *);
extern int filemap_write_and_wait(struct address_space *mapping);
extern int filemap_write_and_wait_range(struct address_space *mapping,
loff_t lstart, loff_t lend);
extern int wait_on_page_writeback_range(struct address_space *mapping,
pgoff_t start, pgoff_t end);
extern int __filemap_fdatawrite_range(struct address_space *mapping,
loff_t start, loff_t end, int sync_mode);

extern void sync_supers(void);
extern void sync_filesystems(int wait);
extern void emergency_sync(void);
Expand Down
46 changes: 41 additions & 5 deletions trunk/mm/fadvise.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,44 @@
#include <linux/backing-dev.h>
#include <linux/pagevec.h>
#include <linux/fadvise.h>
#include <linux/writeback.h>
#include <linux/syscalls.h>

#include <asm/unistd.h>

/*
* POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
* deactivate the pages and clear PG_Referenced.
*
* LINUX_FADV_ASYNC_WRITE: start async writeout of any dirty pages between file
* offsets `offset' and `offset+len' inclusive. Any pages which are currently
* under writeout are skipped, whether or not they are dirty.
*
* LINUX_FADV_WRITE_WAIT: wait upon writeout of any dirty pages between file
* offsets `offset' and `offset+len'.
*
* By combining these two operations the application may do several things:
*
* LINUX_FADV_ASYNC_WRITE: push some or all of the dirty pages at the disk.
*
* LINUX_FADV_WRITE_WAIT, LINUX_FADV_ASYNC_WRITE: push all of the currently
* dirty pages at the disk.
*
* LINUX_FADV_WRITE_WAIT, LINUX_FADV_ASYNC_WRITE, LINUX_FADV_WRITE_WAIT: push
* all of the currently dirty pages at the disk, wait until they have been
* written.
*
* It should be noted that none of these operations write out the file's
* metadata. So unless the application is strictly performing overwrites of
* already-instantiated disk blocks, there are no guarantees here that the data
* will be available after a crash.
*/
asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
{
struct file *file = fget(fd);
struct address_space *mapping;
struct backing_dev_info *bdi;
loff_t endbyte;
loff_t endbyte; /* inclusive */
pgoff_t start_index;
pgoff_t end_index;
unsigned long nrpages;
Expand Down Expand Up @@ -56,6 +80,8 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
endbyte = offset + len;
if (!len || endbyte < len)
endbyte = -1;
else
endbyte--; /* inclusive */

bdi = mapping->backing_dev_info;

Expand All @@ -78,7 +104,7 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)

/* First and last PARTIAL page! */
start_index = offset >> PAGE_CACHE_SHIFT;
end_index = (endbyte-1) >> PAGE_CACHE_SHIFT;
end_index = endbyte >> PAGE_CACHE_SHIFT;

/* Careful about overflow on the "+1" */
nrpages = end_index - start_index + 1;
Expand All @@ -96,11 +122,21 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
filemap_flush(mapping);

/* First and last FULL page! */
start_index = (offset + (PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT;
start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT;
end_index = (endbyte >> PAGE_CACHE_SHIFT);

if (end_index > start_index)
invalidate_mapping_pages(mapping, start_index, end_index-1);
if (end_index >= start_index)
invalidate_mapping_pages(mapping, start_index,
end_index);
break;
case LINUX_FADV_ASYNC_WRITE:
ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
WB_SYNC_NONE);
break;
case LINUX_FADV_WRITE_WAIT:
ret = wait_on_page_writeback_range(mapping,
offset >> PAGE_CACHE_SHIFT,
endbyte >> PAGE_CACHE_SHIFT);
break;
default:
ret = -EINVAL;
Expand Down
10 changes: 5 additions & 5 deletions trunk/mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ static int sync_page(void *word)
* these two operations is that if a dirty page/buffer is encountered, it must
* be waited upon, and not just skipped over.
*/
static int __filemap_fdatawrite_range(struct address_space *mapping,
loff_t start, loff_t end, int sync_mode)
int __filemap_fdatawrite_range(struct address_space *mapping, loff_t start,
loff_t end, int sync_mode)
{
int ret;
struct writeback_control wbc = {
Expand Down Expand Up @@ -213,8 +213,8 @@ int filemap_fdatawrite(struct address_space *mapping)
}
EXPORT_SYMBOL(filemap_fdatawrite);

static int filemap_fdatawrite_range(struct address_space *mapping,
loff_t start, loff_t end)
static int filemap_fdatawrite_range(struct address_space *mapping, loff_t start,
loff_t end)
{
return __filemap_fdatawrite_range(mapping, start, end, WB_SYNC_ALL);
}
Expand All @@ -233,7 +233,7 @@ EXPORT_SYMBOL(filemap_flush);
* Wait for writeback to complete against pages indexed by start->end
* inclusive
*/
static int wait_on_page_writeback_range(struct address_space *mapping,
int wait_on_page_writeback_range(struct address_space *mapping,
pgoff_t start, pgoff_t end)
{
struct pagevec pvec;
Expand Down

0 comments on commit 02c9a46

Please sign in to comment.