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 = NULL, *dst_page = NULL;
47 unsigned long index, offset, bytes;
51 offset = (start & (PAGE_CACHE_SIZE -1)); /* Within page */
53 index = start >> PAGE_CACHE_SHIFT;
55 if (!has_pages(src, index) || bytes > 4096)
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, 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, offset + bytes);
99 CDEBUG(D_SNAP, "copy back pages %p index %lu src %lu dst %lu \n",
100 dst_page, dst_page->index, src->i_ino, dst->i_ino);
102 goto unlock_dst_page;
106 UnlockPage(dst_page);
107 page_cache_release(dst_page);
110 page_cache_release(src_page);
114 static ssize_t currentfs_write (struct file *filp, const char *buf,
115 size_t count, loff_t *ppos)
117 struct snap_cache *cache;
118 struct inode *inode = filp->f_dentry->d_inode;
119 struct file_operations *fops;
120 long start[2]={-1,-1}, end[2]={-1,-1};
121 struct snap_table *table;
122 struct inode *cache_inode = NULL;
123 int slot = 0, index = 0, result = 0;
130 if (currentfs_is_under_dotsnap(filp->f_dentry))
133 cache = snap_find_cache(inode->i_dev);
139 if ( snap_needs_cow(inode) != -1 ) {
140 CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
141 snap_do_cow(inode, filp->f_dentry->d_parent->d_inode->i_ino, 0);
144 fops = filter_c2cffops(cache->cache_filter);
145 if (!fops || !fops->write) {
149 if (filp->f_flags & O_APPEND)
159 CDEBUG(D_SNAP, "write offset %lld count %u \n", pos, count);
161 if (pos & (PAGE_CACHE_SIZE - 1)) {
162 start[0] = pos & PAGE_CACHE_MASK;
166 if ((pos+1) & (PAGE_CACHE_SIZE - 1)) {
168 end[1] = PAGE_CACHE_ALIGN(pos);
171 if (((start[0] >> PAGE_CACHE_SHIFT) == (start[1] >> PAGE_CACHE_SHIFT)) ||
175 CDEBUG(D_SNAP, "copy back start[0] %ld end[0] %ld start[1] %ld end[1] %ld \n",
176 start[0], end[0], start[1], end[1]);
177 for (i = 0; i < 2; i++) {
180 table = &snap_tables[cache->cache_snap_tableno];
181 /*Find the nearest page in snaptable and copy back it*/
182 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
184 index = table->snap_items[slot].index;
185 cache_inode = snap_get_indirect(inode, NULL, index);
187 if (!cache_inode) continue;
189 CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
191 result = copy_back_page(inode, cache_inode, start[i], end[i]);
193 CDEBUG(D_SNAP, "copy page%lu back from ind %lu to %lu\n",
194 (start[i] >> PAGE_CACHE_SHIFT),
212 rc = fops->write(filp, buf, count, ppos);
217 static int currentfs_readpage(struct file *file, struct page *page)
219 struct inode *inode = file->f_dentry->d_inode;
220 unsigned long ind_ino = inode->i_ino;
221 struct inode *pri_inode = NULL;
222 struct inode *cache_inode = NULL;
223 struct address_space_operations *c_aops;
224 struct snap_cache *cache;
225 struct snap_table *table;
226 struct page *cache_page = NULL;
227 int rc = 0, slot = 0, index = 0, search_older = 0;
232 cache = snap_find_cache(inode->i_dev);
237 c_aops = filter_c2cfaops(cache->cache_filter);
239 block = (page->index << PAGE_CACHE_SHIFT) >> inode->i_sb->s_blocksize_bits;
241 /* if there is a block in the cache, return the cache readpage */
242 if(c_aops->bmap(inode->i_mapping, block) ) {
243 CDEBUG(D_SNAP, "block %lu in cache, ino %lu\n",
244 block, inode->i_ino);
245 rc = c_aops->readpage(file, page);
250 * clonefs_readpage will fill this with primary ino number
251 * we need it to follow the cloned chain of primary inode
253 if( file->f_dentry->d_fsdata ){
254 pri_inode = iget(inode->i_sb, (unsigned long)file->f_dentry->d_fsdata);
261 table = &snap_tables[cache->cache_snap_tableno];
263 for (slot = table->tbl_count - 1; slot >= 1; slot--) {
264 index = table->snap_items[slot].index;
265 cache_inode = snap_get_indirect(inode, NULL, index);
267 if (!cache_inode ) continue;
269 /* we only want slots between cache_inode to the oldest one */
270 if(search_older && cache_inode->i_ino == ind_ino )
273 if (!search_older && c_aops->bmap(cache_inode->i_mapping, block))
278 if (pri_inode) iput(pri_inode);
281 CDEBUG(D_SNAP, "block %lu is a hole of inode %lu \n",
282 block, inode->i_ino);
283 memset(kmap(page), 0, PAGE_CACHE_SIZE);
284 flush_dcache_page(page);
287 CDEBUG(D_INODE, "readpage ino %lu icount %d \n", cache_inode->i_ino,
288 atomic_read(&cache_inode->i_count));
289 down(&cache_inode->i_sem);
291 /*Here we have changed a file to read,
292 *So we should rewrite generic file read here
293 *FIXME later, the code is ugly
296 cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
298 GOTO(exit_release, rc = -ENOMEM);
299 if ((rc = c_aops->readpage(file, cache_page)))
300 GOTO(exit_release, 0);
302 wait_on_page(cache_page);
304 if (!Page_Uptodate(cache_page))
305 GOTO(exit_release, rc = -EIO);
307 memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
308 flush_dcache_page(page);
311 page_cache_release(cache_page);
313 up(&cache_inode->i_sem);
317 SetPageUptodate(page);
324 page_cache_release(cache_page);
325 up(&cache_inode->i_sem);
331 struct address_space_operations currentfs_file_aops = {
332 readpage: currentfs_readpage,
335 struct file_operations currentfs_file_fops = {
336 write: currentfs_write,
339 struct inode_operations currentfs_file_iops = {
340 setattr: currentfs_setattr,
341 setxattr: currentfs_setxattr,
342 removexattr: currentfs_removexattr,