ocfs2: shared writeable mmap

Implement cluster consistent shared writeable mappings using the
->page_mkwrite() callback.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
This commit is contained in:
Mark Fasheh
2007-05-09 15:16:19 -07:00
parent 607d44aa3f
commit 7307de8051
4 changed files with 200 additions and 39 deletions

View File

@@ -1034,7 +1034,8 @@ out:
*/
static int ocfs2_grab_pages_for_write(struct address_space *mapping,
struct ocfs2_write_ctxt *wc,
u32 cpos, loff_t user_pos, int new)
u32 cpos, loff_t user_pos, int new,
struct page *mmap_page)
{
int ret = 0, i;
unsigned long start, target_index, index;
@@ -1058,11 +1059,36 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
for(i = 0; i < wc->w_num_pages; i++) {
index = start + i;
wc->w_pages[i] = find_or_create_page(mapping, index, GFP_NOFS);
if (!wc->w_pages[i]) {
ret = -ENOMEM;
mlog_errno(ret);
goto out;
if (index == target_index && mmap_page) {
/*
* ocfs2_pagemkwrite() is a little different
* and wants us to directly use the page
* passed in.
*/
lock_page(mmap_page);
if (mmap_page->mapping != mapping) {
unlock_page(mmap_page);
/*
* Sanity check - the locking in
* ocfs2_pagemkwrite() should ensure
* that this code doesn't trigger.
*/
ret = -EINVAL;
mlog_errno(ret);
goto out;
}
page_cache_get(mmap_page);
wc->w_pages[i] = mmap_page;
} else {
wc->w_pages[i] = find_or_create_page(mapping, index,
GFP_NOFS);
if (!wc->w_pages[i]) {
ret = -ENOMEM;
mlog_errno(ret);
goto out;
}
}
if (index == target_index)
@@ -1213,10 +1239,10 @@ static void ocfs2_set_target_boundaries(struct ocfs2_super *osb,
}
}
static int ocfs2_write_begin_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
struct buffer_head *di_bh)
int ocfs2_write_begin_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
struct buffer_head *di_bh, struct page *mmap_page)
{
int ret, i, credits = OCFS2_INODE_UPDATE_CREDITS;
unsigned int num_clusters = 0, clusters_to_alloc = 0;
@@ -1318,7 +1344,7 @@ static int ocfs2_write_begin_nolock(struct address_space *mapping,
* extent.
*/
ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
clusters_to_alloc);
clusters_to_alloc, mmap_page);
if (ret) {
mlog_errno(ret);
goto out_commit;
@@ -1386,7 +1412,7 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
}
ret = ocfs2_write_begin_nolock(mapping, pos, len, flags, pagep,
fsdata, di_bh);
fsdata, di_bh, NULL);
if (ret) {
mlog_errno(ret);
goto out_fail_data;
@@ -1407,9 +1433,9 @@ out_fail:
return ret;
}
static int ocfs2_write_end_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
int ocfs2_write_end_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{
int i;
unsigned from, to, start = pos & (PAGE_CACHE_SIZE - 1);