aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/alloc.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-08-24 20:05:12 -0400
committerJoel Becker <joel.becker@oracle.com>2009-09-22 23:09:36 -0400
commit6f70fa519976a379d72781d927cf8e5f5b05ec86 (patch)
tree563cdeb116f2016c3c4b7a627a51f0a85eec1566 /fs/ocfs2/alloc.c
parentbcbbb24a6a5c5b3e7b8e5284e0bfa23f45c32377 (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.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 03438a67793..b8fc95d1063 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
7001static void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, 7001void 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
7071static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, 7071int 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
7108static 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