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) >>
25 inode->i_sb->s_blocksize_bits;
27 while (blk_start <= blk_end) {
28 if (inode->i_mapping && inode->i_mapping->a_ops) {
29 if (inode->i_mapping->a_ops->bmap(inode->i_mapping,
38 static int copy_back_page(struct inode *dst,
43 char *kaddr_src, *kaddr_dst;
44 struct snap_cache *cache;
45 struct address_space_operations *c_aops;
46 struct page *src_page, *dst_page;
47 unsigned long index, offset, bytes;
51 index = start >> PAGE_CACHE_SHIFT;
53 offset = start & PAGE_CACHE_MASK;
55 if (!has_pages(src, index))
58 cache = snap_find_cache(src->i_dev);
61 c_aops = filter_c2cfaops(cache->cache_filter);
66 src_page = grab_cache_page(src->i_mapping, index);
68 CERROR("copy block %lu from %lu to %lu ENOMEM \n",
69 index, src->i_ino, dst->i_ino);
73 c_aops->readpage(NULL, src_page);
74 wait_on_page(src_page);
76 kaddr_src = kmap(src_page);
77 if (!Page_Uptodate(src_page)) {
78 CERROR("Can not read page index %lu of inode %lu\n",
83 dst_page = grab_cache_page(dst->i_mapping, index);
85 CERROR("copy block %lu from %lu to %lu ENOMEM \n",
86 index, src->i_ino, dst->i_ino);
90 kaddr_dst = kmap(dst_page);
92 err = c_aops->prepare_write(NULL, dst_page, offset, bytes);
95 memcpy(kaddr_dst, kaddr_src, PAGE_CACHE_SIZE);
96 flush_dcache_page(dst_page);
98 err = c_aops->commit_write(NULL, dst_page, offset, bytes);
100 goto unlock_dst_page;
104 UnlockPage(dst_page);
105 page_cache_release(dst_page);
108 page_cache_release(src_page);
112 static ssize_t currentfs_write (struct file *filp, const char *buf,
113 size_t count, loff_t *ppos)
115 struct snap_cache *cache;
116 struct inode *inode = filp->f_dentry->d_inode;
117 struct file_operations *fops;
118 long start[2]={-1,-1}, end[2]={-1,-1};
119 struct snap_table *table;
120 struct inode *cache_inode = NULL;
121 int slot = 0, index = 0, result = 0;
128 if (currentfs_is_under_dotsnap(filp->f_dentry))
131 cache = snap_find_cache(inode->i_dev);
135 if ( snap_needs_cow(inode) != -1 ) {
136 CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
137 snap_do_cow(inode, filp->f_dentry->d_parent->d_inode->i_ino, 0);
140 fops = filter_c2cffops(cache->cache_filter);
141 if (!fops || !fops->write)
144 if (filp->f_flags & O_APPEND)
151 if (pos & PAGE_CACHE_MASK) {
152 start[0] = pos & PAGE_CACHE_MASK;
156 if ((pos+1) & PAGE_CACHE_MASK) {
158 end[1] = PAGE_CACHE_ALIGN(pos);
161 if (((start[0] >> PAGE_CACHE_SHIFT) == (start[1] >> PAGE_CACHE_SHIFT)) ||
165 for (i = 0; i < 2; i++) {
168 table = &snap_tables[cache->cache_snap_tableno];
169 /*Find the nearest page in snaptable and copy back it*/
170 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
172 index = table->snap_items[slot].index;
173 cache_inode = snap_get_indirect(inode, NULL, index);
175 if (!cache_inode) continue;
177 CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
179 result = copy_back_page(inode, cache_inode, start[i], end[i]);
181 CDEBUG(D_SNAP, "copy page%lu back from ind %lu to %lu\n",
182 (start[i] >> PAGE_CACHE_SHIFT),
197 rc = fops->write(filp, buf, count, ppos);
202 static int currentfs_readpage(struct file *file, struct page *page)
204 struct inode *inode = file->f_dentry->d_inode;
205 unsigned long ind_ino = inode->i_ino;
206 struct inode *pri_inode = NULL;
207 struct inode *cache_inode = NULL;
208 struct address_space_operations *c_aops;
209 struct snap_cache *cache;
210 struct snap_table *table;
211 struct page *cache_page = NULL;
212 int rc = 0, slot = 0, index = 0, search_older = 0;
217 cache = snap_find_cache(inode->i_dev);
222 c_aops = filter_c2cfaops(cache->cache_filter);
224 block = page->index >> inode->i_sb->s_blocksize_bits;
226 /* if there is a block in the cache, return the cache readpage */
227 if(c_aops->bmap(inode->i_mapping, block) ) {
228 CDEBUG(D_SNAP, "block %lu in cache, ino %lu\n",
229 block, inode->i_ino);
230 rc = c_aops->readpage(file, page);
235 * clonefs_readpage will fill this with primary ino number
236 * we need it to follow the cloned chain of primary inode
238 if( file->f_dentry->d_fsdata ){
239 pri_inode = iget(inode->i_sb, (unsigned long)file->f_dentry->d_fsdata);
246 table = &snap_tables[cache->cache_snap_tableno];
248 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
250 index = table->snap_items[slot].index;
251 cache_inode = snap_get_indirect(inode, NULL, index);
253 if (!cache_inode ) continue;
255 /* we only want slots between cache_inode to the oldest one */
256 if(search_older && cache_inode->i_ino == ind_ino )
259 if (!search_older && c_aops->bmap(cache_inode->i_mapping, block))
263 if (pri_inode) iput(pri_inode);
268 down(&cache_inode->i_sem);
270 /*Here we have changed a file to read,
271 *So we should rewrite generic file read here
272 *FIXME later, the code is ugly
275 cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
277 GOTO(exit_release, rc = -ENOMEM);
278 if ((rc = c_aops->readpage(file, cache_page)))
279 GOTO(exit_release, 0);
281 wait_on_page(cache_page);
283 if (!Page_Uptodate(cache_page))
284 GOTO(exit_release, rc = -EIO);
286 memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
289 page_cache_release(cache_page);
291 up(&cache_inode->i_sem);
295 SetPageUptodate(page);
302 page_cache_release(cache_page);
303 up(&cache_inode->i_sem);
309 struct address_space_operations currentfs_file_aops = {
310 readpage: currentfs_readpage,
313 struct file_operations currentfs_file_fops = {
314 write: currentfs_write,
317 struct inode_operations currentfs_file_iops = {