2 * Super block/filesystem wide operations
4 * Copryright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and
5 * Michael Callahan <callahan@maths.ox.ac.uk>
7 * Rewritten for Linux 2.1. Peter Braam <braam@cs.cmu.edu>
8 * Copyright (C) Carnegie Mellon University
10 * Copyright (C) 2000, Mountain View Data, Inc, authors
11 * Peter Braam <braam@mountainviewdata.com>,
12 * Harrison Xing <harrisonx@mountainviewdata.com>
16 #define DEBUG_SUBSYSTEM S_SNAP
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/string.h>
21 #include <linux/slab.h>
22 #include <linux/stat.h>
23 #include <linux/unistd.h>
24 #include <linux/jbd.h>
25 #include <linux/ext3_fs.h>
26 #include <linux/snap.h>
27 #include "snapfs_internal.h"
30 /* Clone is a simple file system, read only that just follows redirectors
31 we have placed the entire implementation except clone_read_super in
35 struct inode_operations clonefs_dir_inode_ops;
36 struct inode_operations clonefs_file_inode_ops;
37 struct inode_operations clonefs_symlink_inode_ops;
38 //struct inode_operations clonefs_special_inode_operations;
39 struct file_operations clonefs_dir_file_ops;
40 struct file_operations clonefs_file_file_ops;
41 //struct file_operations clonefs_special_file_operations;
42 struct address_space_operations clonefs_file_address_ops;
44 /* support routines for following redirectors */
46 /* Parameter is clonefs inode, 'inode', and typically this may be
47 called before read_inode has completed on this clonefs inode,
48 i.e. we may only assume that i_ino is valid.
50 We return an underlying (likely disk) fs inode. This involved
51 handling any redirector inodes found along the way.
53 This function is used by all clone fs interface functions to get an
57 struct inode *clonefs_get_inode(struct inode *inode)
59 struct snap_clone_info *clone_sb;
60 struct inode *cache_inode, *redirected_inode;
64 /* this only works if snapfs_current does NOT overwrite read_inode */
65 clone_sb = (struct snap_clone_info *) &inode->i_sb->u.generic_sbp;
67 /* basic invariant: clone and current ino's are equal */
68 cache_inode = iget(clone_sb->clone_cache->cache_sb, inode->i_ino);
70 redirected_inode = snap_redirect(cache_inode, inode->i_sb);
72 CDEBUG(D_SNAP, "redirected_inode: %lx, cache_inode %lx\n",
73 (unsigned long) redirected_inode, (unsigned long) cache_inode);
75 CDEBUG(D_SNAP, "cache_inode: %lx, ino %ld, sb %lx, count %d\n",
76 (unsigned long) cache_inode, cache_inode->i_ino,
77 (unsigned long) cache_inode->i_sb, atomic_read(&cache_inode->i_count));
81 return redirected_inode;
85 /* super operations */
86 static void clonefs_read_inode(struct inode *inode)
88 struct inode *cache_inode;
92 CDEBUG(D_SNAP, "inode: %lx, ino %ld, sb %lx, count %d\n",
93 (unsigned long)inode, inode->i_ino, (long) inode->i_sb,
94 atomic_read(&inode->i_count));
96 /* redirecting inode in the cache */
97 cache_inode = clonefs_get_inode(inode);
99 make_bad_inode(inode);
102 /* copy attrs of that inode to our clone inode */
103 snapfs_cpy_attrs(inode, cache_inode);
105 if (S_ISREG(inode->i_mode)) {
106 inode->i_op = &clonefs_file_inode_ops;
107 if (inode->i_mapping)
108 inode->i_mapping->a_ops = &clonefs_file_address_ops;
109 inode->i_fop = &clonefs_file_file_ops;
110 } else if (S_ISDIR(inode->i_mode)) {
111 inode->i_op = &clonefs_dir_inode_ops;
112 inode->i_fop = &clonefs_dir_file_ops;
113 } else if (S_ISLNK(inode->i_mode)) {
114 inode->i_op = &clonefs_symlink_inode_ops;
116 /* init special inode
117 * FIXME whether we should replace special inode ops*/
118 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
119 init_special_inode(inode, inode->i_mode,
120 kdev_t_to_nr(inode->i_rdev));
122 init_special_inode(inode, inode->i_mode, inode->i_rdev);
127 CDEBUG(D_SNAP, "cache_inode: %lx ino %ld, sb %lx, count %d\n",
128 (unsigned long) cache_inode, cache_inode->i_ino,
129 (unsigned long) cache_inode->i_sb,
130 atomic_read(&cache_inode->i_count));
135 static void clonefs_put_super(struct super_block *sb)
137 struct snap_clone_info *clone_sb;
140 CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
141 (unsigned long) sb, (unsigned long) &sb->u.generic_sbp);
142 clone_sb = (struct snap_clone_info *)&sb->u.generic_sbp;
143 dput(clone_sb->clone_cache->cache_sb->s_root);
144 list_del(&clone_sb->clone_list_entry);
149 static int clonefs_statfs(struct super_block *sb, struct statfs *buf)
151 struct snap_clone_info *clone_sb;
152 struct snap_cache *cache;
155 clone_sb = (struct snap_clone_info *)&sb->u.generic_sbp;
157 cache = clone_sb->clone_cache;
159 CERROR("clone_statfs: no cache\n");
163 return cache->cache_filter->o_caops.cache_sops->statfs
164 (cache->cache_sb, buf);
167 struct super_operations clone_super_ops =
169 read_inode: clonefs_read_inode, /* read_inode */
170 put_super: clonefs_put_super, /* put_super */
171 statfs: clonefs_statfs, /* statfs */
175 /* ***************** end of clonefs super ops ******************* */
176 /* ***************** begin clonefs dir ops ******************* */
178 static void d_unalloc(struct dentry *dentry)
181 list_del(&dentry->d_hash);
182 INIT_LIST_HEAD(&dentry->d_hash);
183 dput(dentry); /* this will free the dentry memory */
186 static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
188 atomic_set(&dentry->d_count, 1);
189 dentry->d_vfs_flags = 0;
191 dentry->d_inode = inode;
193 dentry->d_fsdata = NULL;
194 dentry->d_mounted = 0;
195 INIT_LIST_HEAD(&dentry->d_hash);
196 INIT_LIST_HEAD(&dentry->d_lru);
197 INIT_LIST_HEAD(&dentry->d_subdirs);
198 INIT_LIST_HEAD(&dentry->d_alias);
201 * Return the underlying fs dentry with name in 'dentry' that points
202 * to the right inode. 'dir' is the clone fs directory to search for
205 struct dentry *clonefs_lookup(struct inode *dir, struct dentry *dentry)
207 struct inode *cache_dir = NULL;
208 struct dentry *cache_dentry = NULL;
209 struct inode *cache_inode;
210 struct dentry *result;
213 struct snap_clone_info *clone_sb;
217 cache_dir = clonefs_get_inode(dir);
219 RETURN(ERR_PTR(-ENOENT));
220 /*FIXME later, we make parent dentry here
221 *there may some problems in lookup
223 prepare_parent_dentry(&tmp, cache_dir);
224 cache_dentry = d_alloc(&tmp, &dentry->d_name);
228 RETURN(ERR_PTR(-ENOENT));
231 /* Lock cache directory inode. */
232 down(&cache_dir->i_sem);
234 * Call underlying fs lookup function to set the 'd_inode' pointer
235 * to the corresponding directory inode.
237 * Note: If the lookup function does not return NULL, return
238 * from 'clone_lookup' with an error.
240 result = cache_dir->i_op->lookup(cache_dir, cache_dentry);
243 up(&cache_dir->i_sem);
245 dentry->d_inode = NULL;
246 RETURN(ERR_PTR(-ENOENT));
248 /* Unlock cache directory inode. */
249 up(&cache_dir->i_sem);
252 * If there is no inode pointer in the underlying fs 'cache_dentry'
253 * then the directory doesn't have an entry with this name. In fs/ext2
254 * we see that we return 0 and put dentry->d_inode = NULL;
256 cache_inode = cache_dentry->d_inode;
257 if ( cache_inode == NULL ) {
260 clone_sb = (struct snap_clone_info *) &dir->i_sb->u.generic_sbp;
261 /* note, iget below will follow a redirector, since
262 it calls into clone_read_inode
264 inode = iget(dir->i_sb, cache_inode->i_ino);
267 /* dput(cache_dentry) will not put the dentry away
268 * immediately, unless we first arrange that its hash list is
272 if ( cache_inode != NULL ) {
273 CDEBUG(D_INODE, "cache ino %ld, count %d, dir %ld, count %d\n",
274 cache_inode->i_ino, atomic_read(&cache_inode->i_count),
275 cache_dir->i_ino, atomic_read(&cache_dir->i_count));
278 d_unalloc(cache_dentry);
282 * Add 'inode' to the directory entry 'dentry'.
284 d_add(dentry, inode);
290 /* instantiate a file handle to the cache file */
291 static void clonefs_prepare_snapfile(struct inode *i,
292 struct file *clone_file,
293 struct inode *cache_inode,
294 struct file *cache_file,
295 struct dentry *cache_dentry)
299 cache_file->f_pos = clone_file->f_pos;
300 cache_file->f_mode = clone_file->f_mode;
301 cache_file->f_flags = clone_file->f_flags;
302 cache_file->f_count = clone_file->f_count;
303 cache_file->f_owner = clone_file->f_owner;
304 cache_file->f_op = cache_inode->i_fop;
305 cache_file->f_dentry = cache_dentry;
306 cache_file->f_dentry->d_inode = cache_inode;
311 /* update the clonefs file struct after IO in cache file */
312 static void clonefs_restore_snapfile(struct inode *cache_inode,
313 struct file *cache_file,
314 struct inode *clone_inode,
315 struct file *clone_file)
319 cache_file->f_pos = clone_file->f_pos;
320 cache_inode->i_size = clone_inode->i_size;
325 static int clonefs_readdir(struct file *file, void *dirent,
329 struct inode *cache_inode;
330 struct file open_file;
331 struct dentry open_dentry;
332 struct inode *inode = file->f_dentry->d_inode;
339 cache_inode = clonefs_get_inode(inode);
342 make_bad_inode(inode);
346 CDEBUG(D_INODE,"clone ino %ld\n",cache_inode->i_ino);
348 clonefs_prepare_snapfile(inode, file, cache_inode, &open_file,
350 /* potemkin case: we are handed a directory inode */
352 if (open_file.f_op->readdir) {
353 down(&cache_inode->i_sem);
354 result = open_file.f_op->readdir(&open_file, dirent, filldir);
355 up(&cache_inode->i_sem);
357 clonefs_restore_snapfile(inode, file, cache_inode, &open_file);
362 struct file_operations clonefs_dir_file_ops = {
363 readdir: clonefs_readdir, /* readdir */
366 struct inode_operations clonefs_dir_inode_ops = {
367 lookup: clonefs_lookup, /* lookup */
371 /* ***************** end of clonefs dir ops ******************* */
372 /* ***************** begin clonefs file ops ******************* */
374 static int clonefs_readpage(struct file *file, struct page *page)
377 struct inode *cache_inode;
378 struct file open_file;
379 struct dentry open_dentry;
384 inode = file->f_dentry->d_inode;
385 cache_inode = clonefs_get_inode(file->f_dentry->d_inode);
387 make_bad_inode(file->f_dentry->d_inode);
391 clonefs_prepare_snapfile(inode, file, cache_inode, &open_file,
393 /* tell currentfs_readpage the primary inode number */
394 open_dentry.d_fsdata = (void*)inode->i_ino;
395 page->mapping->host = cache_inode;
396 /* potemkin case: we are handed a directory inode */
397 down(&cache_inode->i_sem);
398 /* XXX - readpage NULL on directories... */
399 result = cache_inode->i_mapping->a_ops->readpage(&open_file, page);
401 up(&cache_inode->i_sem);
402 page->mapping->host = inode;
403 clonefs_restore_snapfile(inode, file, cache_inode, &open_file);
408 struct file_operations clonefs_file_file_ops = {
409 read: generic_file_read, /* read -- bad */
410 mmap: generic_file_mmap, /* mmap */
413 struct address_space_operations clonefs_file_address_ops = {
414 readpage: clonefs_readpage
418 /* ***************** end of clonefs file ops ******************* */
419 /* ***************** begin clonefs symlink ops ******************* */
421 static int clonefs_readlink(struct dentry *dentry, char *buf, int len)
424 struct inode * cache_inode;
425 struct inode * old_inode;
429 cache_inode = clonefs_get_inode(dentry->d_inode);
433 if ( ! cache_inode ) {
434 CDEBUG(D_INODE, "clonefs_get_inode failed, NULL\n");
438 /* XXX: shall we allocate a new dentry ?
439 The following is safe for ext3, etc. because ext2_readlink only
440 use the inode info */
442 /* save the old dentry inode */
443 old_inode = dentry->d_inode;
444 /* set dentry inode to cache inode */
445 dentry->d_inode = cache_inode;
447 if ( cache_inode->i_op->readlink ) {
448 res = cache_inode->i_op->readlink(dentry, buf, len);
450 CDEBUG(D_INODE,"NO readlink for ino %lu\n", cache_inode->i_ino);
453 /* restore the old inode */
454 dentry->d_inode = old_inode;
461 static int clonefs_follow_link(struct dentry * dentry, struct nameidata *nd)
463 struct inode * cache_inode;
464 struct inode * old_inode;
469 cache_inode = clonefs_get_inode(dentry->d_inode);
470 if ( ! cache_inode ) {
471 CDEBUG(D_INODE, "clonefs_get_inode failed, NULL\n");
475 /* XXX: shall we allocate a new dentry ?
476 The following is safe for ext2, etc. because ext2_follow_link
477 only use the inode info */
479 /* save the old dentry inode */
480 old_inode = dentry->d_inode;
481 /* set dentry inode to cache inode */
482 dentry->d_inode = cache_inode;
484 if ( cache_inode->i_op->follow_link ) {
485 res = cache_inode->i_op->follow_link(dentry, nd);
488 /* restore the old inode */
489 dentry->d_inode = old_inode;
496 struct inode_operations clonefs_symlink_inode_ops =
498 /*FIXME later getxattr, listxattr,
499 * other method need to be replaced too
501 readlink: clonefs_readlink, /* readlink */
502 follow_link: clonefs_follow_link,/* follow_link */