implement simple fs aops
Implement new aops for some of the simpler filesystems. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
674b892ede
Коммит
800d15a53e
|
@ -41,8 +41,8 @@ extern struct super_block * configfs_sb;
|
|||
|
||||
static const struct address_space_operations configfs_aops = {
|
||||
.readpage = simple_readpage,
|
||||
.prepare_write = simple_prepare_write,
|
||||
.commit_write = simple_commit_write
|
||||
.write_begin = simple_write_begin,
|
||||
.write_end = simple_write_end,
|
||||
};
|
||||
|
||||
static struct backing_dev_info configfs_backing_dev_info = {
|
||||
|
|
|
@ -189,15 +189,19 @@ static int hugetlbfs_readpage(struct file *file, struct page * page)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hugetlbfs_prepare_write(struct file *file,
|
||||
struct page *page, unsigned offset, unsigned to)
|
||||
static int hugetlbfs_write_begin(struct file *file,
|
||||
struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hugetlbfs_commit_write(struct file *file,
|
||||
struct page *page, unsigned offset, unsigned to)
|
||||
static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata)
|
||||
{
|
||||
BUG();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -569,8 +573,8 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
|
|||
|
||||
static const struct address_space_operations hugetlbfs_aops = {
|
||||
.readpage = hugetlbfs_readpage,
|
||||
.prepare_write = hugetlbfs_prepare_write,
|
||||
.commit_write = hugetlbfs_commit_write,
|
||||
.write_begin = hugetlbfs_write_begin,
|
||||
.write_end = hugetlbfs_write_end,
|
||||
.set_page_dirty = hugetlbfs_set_page_dirty,
|
||||
};
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
const struct address_space_operations ramfs_aops = {
|
||||
.readpage = simple_readpage,
|
||||
.prepare_write = simple_prepare_write,
|
||||
.commit_write = simple_commit_write,
|
||||
.write_begin = simple_write_begin,
|
||||
.write_end = simple_write_end,
|
||||
.set_page_dirty = __set_page_dirty_no_writeback,
|
||||
};
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
|
|||
|
||||
const struct address_space_operations ramfs_aops = {
|
||||
.readpage = simple_readpage,
|
||||
.prepare_write = simple_prepare_write,
|
||||
.commit_write = simple_commit_write,
|
||||
.write_begin = simple_write_begin,
|
||||
.write_end = simple_write_end,
|
||||
.set_page_dirty = __set_page_dirty_no_writeback,
|
||||
};
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ extern struct super_block * sysfs_sb;
|
|||
|
||||
static const struct address_space_operations sysfs_aops = {
|
||||
.readpage = simple_readpage,
|
||||
.prepare_write = simple_prepare_write,
|
||||
.commit_write = simple_commit_write
|
||||
.write_begin = simple_write_begin,
|
||||
.write_end = simple_write_end,
|
||||
};
|
||||
|
||||
static struct backing_dev_info sysfs_backing_dev_info = {
|
||||
|
|
34
mm/shmem.c
34
mm/shmem.c
|
@ -1108,7 +1108,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
|
|||
* Normally, filepage is NULL on entry, and either found
|
||||
* uptodate immediately, or allocated and zeroed, or read
|
||||
* in under swappage, which is then assigned to filepage.
|
||||
* But shmem_readpage and shmem_prepare_write pass in a locked
|
||||
* But shmem_readpage and shmem_write_begin pass in a locked
|
||||
* filepage, which may be found not uptodate by other callers
|
||||
* too, and may need to be copied from the swappage read in.
|
||||
*/
|
||||
|
@ -1445,7 +1445,7 @@ static const struct inode_operations shmem_symlink_inode_operations;
|
|||
static const struct inode_operations shmem_symlink_inline_operations;
|
||||
|
||||
/*
|
||||
* Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write;
|
||||
* Normally tmpfs avoids the use of shmem_readpage and shmem_write_begin;
|
||||
* but providing them allows a tmpfs file to be used for splice, sendfile, and
|
||||
* below the loop driver, in the generic fashion that many filesystems support.
|
||||
*/
|
||||
|
@ -1458,10 +1458,30 @@ static int shmem_readpage(struct file *file, struct page *page)
|
|||
}
|
||||
|
||||
static int
|
||||
shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
|
||||
shmem_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
return shmem_getpage(inode, page->index, &page, SGP_WRITE, NULL);
|
||||
struct inode *inode = mapping->host;
|
||||
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
|
||||
*pagep = NULL;
|
||||
return shmem_getpage(inode, index, pagep, SGP_WRITE, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
shmem_write_end(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata)
|
||||
{
|
||||
struct inode *inode = mapping->host;
|
||||
|
||||
set_page_dirty(page);
|
||||
page_cache_release(page);
|
||||
|
||||
if (pos+copied > inode->i_size)
|
||||
i_size_write(inode, pos+copied);
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
@ -2337,8 +2357,8 @@ static const struct address_space_operations shmem_aops = {
|
|||
.set_page_dirty = __set_page_dirty_no_writeback,
|
||||
#ifdef CONFIG_TMPFS
|
||||
.readpage = shmem_readpage,
|
||||
.prepare_write = shmem_prepare_write,
|
||||
.commit_write = simple_commit_write,
|
||||
.write_begin = shmem_write_begin,
|
||||
.write_end = shmem_write_end,
|
||||
#endif
|
||||
.migratepage = migrate_page,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче