diff options
author | Tao Ma <tao.ma@oracle.com> | 2009-08-24 20:05:12 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2009-09-22 23:09:36 -0400 |
commit | 6f70fa519976a379d72781d927cf8e5f5b05ec86 (patch) | |
tree | 563cdeb116f2016c3c4b7a627a51f0a85eec1566 /fs/ocfs2/alloc.c | |
parent | bcbbb24a6a5c5b3e7b8e5284e0bfa23f45c32377 (diff) |
ocfs2: Add CoW support.
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>
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r-- | fs/ocfs2/alloc.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 03438a677933..b8fc95d10630 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -6998,9 +6998,9 @@ static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh) | |||
6998 | return 0; | 6998 | return 0; |
6999 | } | 6999 | } |
7000 | 7000 | ||
7001 | static void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, | 7001 | void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, |
7002 | unsigned int from, unsigned int to, | 7002 | unsigned int from, unsigned int to, |
7003 | struct page *page, int zero, u64 *phys) | 7003 | struct page *page, int zero, u64 *phys) |
7004 | { | 7004 | { |
7005 | int ret, partial = 0; | 7005 | int ret, partial = 0; |
7006 | 7006 | ||
@@ -7068,20 +7068,16 @@ out: | |||
7068 | ocfs2_unlock_and_free_pages(pages, numpages); | 7068 | ocfs2_unlock_and_free_pages(pages, numpages); |
7069 | } | 7069 | } |
7070 | 7070 | ||
7071 | static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, | 7071 | int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end, |
7072 | struct page **pages, int *num) | 7072 | struct page **pages, int *num) |
7073 | { | 7073 | { |
7074 | int numpages, ret = 0; | 7074 | int numpages, ret = 0; |
7075 | struct super_block *sb = inode->i_sb; | ||
7076 | struct address_space *mapping = inode->i_mapping; | 7075 | struct address_space *mapping = inode->i_mapping; |
7077 | unsigned long index; | 7076 | unsigned long index; |
7078 | loff_t last_page_bytes; | 7077 | loff_t last_page_bytes; |
7079 | 7078 | ||
7080 | BUG_ON(start > end); | 7079 | BUG_ON(start > end); |
7081 | 7080 | ||
7082 | BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits != | ||
7083 | (end - 1) >> OCFS2_SB(sb)->s_clustersize_bits); | ||
7084 | |||
7085 | numpages = 0; | 7081 | numpages = 0; |
7086 | last_page_bytes = PAGE_ALIGN(end); | 7082 | last_page_bytes = PAGE_ALIGN(end); |
7087 | index = start >> PAGE_CACHE_SHIFT; | 7083 | index = start >> PAGE_CACHE_SHIFT; |
@@ -7109,6 +7105,17 @@ out: | |||
7109 | return ret; | 7105 | return ret; |
7110 | } | 7106 | } |
7111 | 7107 | ||
7108 | static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, | ||
7109 | struct page **pages, int *num) | ||
7110 | { | ||
7111 | struct super_block *sb = inode->i_sb; | ||
7112 | |||
7113 | BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits != | ||
7114 | (end - 1) >> OCFS2_SB(sb)->s_clustersize_bits); | ||
7115 | |||
7116 | return ocfs2_grab_pages(inode, start, end, pages, num); | ||
7117 | } | ||
7118 | |||
7112 | /* | 7119 | /* |
7113 | * Zero the area past i_size but still within an allocated | 7120 | * Zero the area past i_size but still within an allocated |
7114 | * cluster. This avoids exposing nonzero data on subsequent file | 7121 | * cluster. This avoids exposing nonzero data on subsequent file |