Skip to content

Commit

Permalink
ocfs2: Add CoW support.
Browse files Browse the repository at this point in the history
This patch try CoW support for a refcounted record.

the whole process will be:
1. Calculate how many clusters we need to CoW and where we start.
   Extents that are not completely encompassed by the write will
   be broken on 1MB boundaries.
2. Do CoW for the clusters with the help of page cache.
3. Change the b-tree structure with the new allocated clusters.

Signed-off-by: Tao Ma <tao.ma@oracle.com>
  • Loading branch information
Tao Ma authored and Joel Becker committed Sep 23, 2009
1 parent bcbbb24 commit 6f70fa5
Show file tree
Hide file tree
Showing 6 changed files with 841 additions and 11 deletions.
25 changes: 16 additions & 9 deletions fs/ocfs2/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6998,9 +6998,9 @@ static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh)
return 0;
}

static void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
unsigned int from, unsigned int to,
struct page *page, int zero, u64 *phys)
void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
unsigned int from, unsigned int to,
struct page *page, int zero, u64 *phys)
{
int ret, partial = 0;

Expand Down Expand Up @@ -7068,20 +7068,16 @@ static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start,
ocfs2_unlock_and_free_pages(pages, numpages);
}

static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
struct page **pages, int *num)
int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end,
struct page **pages, int *num)
{
int numpages, ret = 0;
struct super_block *sb = inode->i_sb;
struct address_space *mapping = inode->i_mapping;
unsigned long index;
loff_t last_page_bytes;

BUG_ON(start > end);

BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits !=
(end - 1) >> OCFS2_SB(sb)->s_clustersize_bits);

numpages = 0;
last_page_bytes = PAGE_ALIGN(end);
index = start >> PAGE_CACHE_SHIFT;
Expand Down Expand Up @@ -7109,6 +7105,17 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
return ret;
}

static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
struct page **pages, int *num)
{
struct super_block *sb = inode->i_sb;

BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits !=
(end - 1) >> OCFS2_SB(sb)->s_clustersize_bits);

return ocfs2_grab_pages(inode, start, end, pages, num);
}

/*
* Zero the area past i_size but still within an allocated
* cluster. This avoids exposing nonzero data on subsequent file
Expand Down
5 changes: 5 additions & 0 deletions fs/ocfs2/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec)
return !rec->e_leaf_clusters;
}

int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end,
struct page **pages, int *num);
void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
unsigned int from, unsigned int to,
struct page *page, int zero, u64 *phys);
/*
* Structures which describe a path through a btree, and functions to
* manipulate them.
Expand Down
4 changes: 2 additions & 2 deletions fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
return err;
}

static int ocfs2_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
int ocfs2_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int err = 0;
unsigned int ext_flags;
Expand Down
2 changes: 2 additions & 0 deletions fs/ocfs2/aops.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
struct buffer_head *di_bh);
int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size);

int ocfs2_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create);
/* all ocfs2_dio_end_io()'s fault */
#define ocfs2_iocb_is_rw_locked(iocb) \
test_bit(0, (unsigned long *)&iocb->private)
Expand Down
Loading

0 comments on commit 6f70fa5

Please sign in to comment.