5 #define DEBUG_SUBSYSTEM S_SNAP
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10 #include <linux/slab.h>
11 #include <linux/stat.h>
12 #include <linux/unistd.h>
13 #include <linux/pagemap.h>
14 #include <linux/jbd.h>
15 #include <linux/ext3_fs.h>
16 #include <linux/snap.h>
18 #include "snapfs_internal.h"
20 static int has_pages(struct inode *inode, int index)
22 unsigned long offset = index << PAGE_CACHE_SHIFT;
23 unsigned long blk_start = offset >> inode->i_sb->s_blocksize_bits;
24 unsigned long blk_end = (offset + PAGE_CACHE_SIZE) >> inode->i_sb->s_blocksize_bits;
27 while (blk_start <= blk_end) {
28 if (inode->i_mapping && inode->i_mapping->a_ops) {
29 inside = inode->i_mapping->a_ops->bmap(inode->i_mapping, blk_start);
36 static int copy_back_page(struct inode *dst, struct inode *src,
39 char *kaddr_src, *kaddr_dst;
40 struct snap_cache *cache;
41 struct address_space_operations *c_aops;
42 struct page *src_page, *dst_page;
46 if (!has_pages(src, index))
49 cache = snap_find_cache(src->i_dev);
52 c_aops = filter_c2cfaops(cache->cache_filter);
57 src_page = grab_cache_page(src->i_mapping, index);
59 CERROR("copy block %d from %lu to %lu ENOMEM \n",
60 index, src->i_ino, dst->i_ino);
64 c_aops->readpage(NULL, src_page);
65 wait_on_page(src_page);
67 kaddr_src = kmap(src_page);
68 if (!Page_Uptodate(src_page)) {
69 CERROR("Can not read page index %d of inode %lu\n",
74 dst_page = grab_cache_page(dst->i_mapping, index);
76 CERROR("copy block %d from %lu to %lu ENOMEM \n",
77 index, src->i_ino, dst->i_ino);
81 kaddr_dst = kmap(dst_page);
83 err = c_aops->prepare_write(NULL, dst_page, 0, PAGE_CACHE_SIZE);
86 memcpy(kaddr_dst, kaddr_src, PAGE_CACHE_SIZE);
87 flush_dcache_page(dst_page);
89 err = c_aops->commit_write(NULL, dst_page, 0, PAGE_CACHE_SIZE);
96 page_cache_release(dst_page);
99 page_cache_release(src_page);
103 static ssize_t currentfs_write (struct file *filp, const char *buf,
104 size_t count, loff_t *ppos)
106 struct snap_cache *cache;
107 struct inode *inode = filp->f_dentry->d_inode;
108 struct file_operations *fops;
109 long page[2]={-1,-1};
110 struct snap_table *table;
111 struct inode *cache_inode = NULL;
112 int slot = 0, index = 0, result = 0;
119 if (currentfs_is_under_dotsnap(filp->f_dentry))
122 cache = snap_find_cache(inode->i_dev);
126 if ( snap_needs_cow(inode) != -1 ) {
127 CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
128 snap_do_cow(inode, filp->f_dentry->d_parent->d_inode->i_ino, 0);
131 fops = filter_c2cffops(cache->cache_filter);
132 if (!fops || !fops->write)
135 if (filp->f_flags & O_APPEND)
144 * we only need to copy back the first and last blocks
147 mask = inode->i_sb->s_blocksize-1;
149 block[0] = pos >> inode->i_sb->s_blocksize_bits;
152 block[1] = pos >> inode->i_sb->s_blocksize_bits;
153 if( block[0] == block[1] )
156 snapops = filter_c2csnapops(cache->cache_filter);
158 for (i = 0; i < 2; i++) {
161 table = &snap_tables[cache->cache_snap_tableno];
162 /*Find the nearest block in snaptable and copy back it*/
163 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
165 index = table->snap_items[slot].index;
166 cache_inode = snap_get_indirect(inode, NULL, index);
168 if (!cache_inode) continue;
170 CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
172 if (snapops && snapops->copy_block) {
173 result = snapops->copy_block(inode, cache_inode, block[i]);
175 CDEBUG(D_SNAP, "copy block %lu back from ind %lu to %lu\n",
176 block[i], cache_inode->i_ino, inode->i_ino);
191 if (pos & PAGE_CACHE_MASK)
192 page[0] = pos >> PAGE_CACHE_SHIFT;
194 if ((pos+1) & PAGE_CACHE_MASK)
195 page[1] = pos >> PAGE_CACHE_SHIFT;
196 if (page[0] == page[1])
199 for (i = 0; i < 2; i++) {
202 table = &snap_tables[cache->cache_snap_tableno];
203 /*Find the nearest page in snaptable and copy back it*/
204 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
206 index = table->snap_items[slot].index;
207 cache_inode = snap_get_indirect(inode, NULL, index);
209 if (!cache_inode) continue;
211 CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
213 result = copy_back_page(inode, cache_inode, page[i]);
215 CDEBUG(D_SNAP, "copy page%lu back from ind %lu to %lu\n",
216 page[i], cache_inode->i_ino, inode->i_ino);
230 rc = fops->write(filp, buf, count, ppos);
235 static int currentfs_readpage(struct file *file, struct page *page)
237 struct inode *inode = file->f_dentry->d_inode;
238 unsigned long ind_ino = inode->i_ino;
239 struct inode *pri_inode = NULL;
240 struct inode *cache_inode = NULL;
241 struct address_space_operations *c_aops;
242 struct snap_cache *cache;
243 struct snap_table *table;
244 struct page *cache_page = NULL;
245 int rc = 0, slot = 0, index = 0, search_older = 0;
250 cache = snap_find_cache(inode->i_dev);
255 c_aops = filter_c2cfaops(cache->cache_filter);
257 block = page->index >> inode->i_sb->s_blocksize_bits;
259 /* if there is a block in the cache, return the cache readpage */
260 if(c_aops->bmap(inode->i_mapping, block) ) {
261 CDEBUG(D_SNAP, "block %lu in cache, ino %lu\n",
262 block, inode->i_ino);
263 rc = c_aops->readpage(file, page);
268 * clonefs_readpage will fill this with primary ino number
269 * we need it to follow the cloned chain of primary inode
271 if( file->f_dentry->d_fsdata ){
272 pri_inode = iget(inode->i_sb, (unsigned long)file->f_dentry->d_fsdata);
279 table = &snap_tables[cache->cache_snap_tableno];
281 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
283 index = table->snap_items[slot].index;
284 cache_inode = snap_get_indirect(inode, NULL, index);
286 if (!cache_inode ) continue;
288 /* we only want slots between cache_inode to the oldest one */
289 if(search_older && cache_inode->i_ino == ind_ino )
292 if (!search_older && c_aops->bmap(cache_inode->i_mapping, block))
296 if (pri_inode) iput(pri_inode);
301 down(&cache_inode->i_sem);
303 /*Here we have changed a file to read,
304 *So we should rewrite generic file read here
305 *FIXME later, the code is ugly
308 cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
310 GOTO(exit_release, rc = -ENOMEM);
311 if ((rc = c_aops->readpage(file, cache_page)))
312 GOTO(exit_release, 0);
314 wait_on_page(cache_page);
316 if (!Page_Uptodate(cache_page))
317 GOTO(exit_release, rc = -EIO);
319 memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
322 page_cache_release(cache_page);
324 up(&cache_inode->i_sem);
328 SetPageUptodate(page);
335 page_cache_release(cache_page);
336 up(&cache_inode->i_sem);
342 struct address_space_operations currentfs_file_aops = {
343 readpage: currentfs_readpage,
346 struct file_operations currentfs_file_fops = {
347 write: currentfs_write,
350 struct inode_operations currentfs_file_iops = {