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 */
187 * Return the underlying fs dentry with name in 'dentry' that points
188 * to the right inode. 'dir' is the clone fs directory to search for
191 struct dentry *clonefs_lookup(struct inode *dir, struct dentry *dentry)
193 struct inode *cache_dir = NULL;
194 struct dentry *cache_dentry = NULL, *tmp = NULL;
195 struct inode *cache_inode;
196 struct dentry *result;
198 struct snap_clone_info *clone_sb;
202 cache_dir = clonefs_get_inode(dir);
204 RETURN(ERR_PTR(-ENOENT));
206 tmp = dget(list_entry(cache_dir->i_dentry.next, struct dentry, d_alias));
208 cache_dentry = d_alloc(tmp->d_parent, &dentry->d_name);
213 RETURN(ERR_PTR(-ENOENT));
216 /* Lock cache directory inode. */
217 down(&cache_dir->i_sem);
220 * Call underlying fs lookup function to set the 'd_inode' pointer
221 * to the corresponding directory inode.
223 * Note: If the lookup function does not return NULL, return
224 * from 'clone_lookup' with an error.
226 result = cache_dir->i_op->lookup(cache_dir, cache_dentry);
229 up(&cache_dir->i_sem);
231 dentry->d_inode = NULL;
232 RETURN(ERR_PTR(-ENOENT));
234 /* Unlock cache directory inode. */
235 up(&cache_dir->i_sem);
238 * If there is no inode pointer in the underlying fs 'cache_dentry'
239 * then the directory doesn't have an entry with this name. In fs/ext2
240 * we see that we return 0 and put dentry->d_inode = NULL;
242 cache_inode = cache_dentry->d_inode;
243 if ( cache_inode == NULL ) {
246 clone_sb = (struct snap_clone_info *) &dir->i_sb->u.generic_sbp;
247 /* note, iget below will follow a redirector, since
248 it calls into clone_read_inode
250 inode = iget(dir->i_sb, cache_inode->i_ino);
253 /* dput(cache_dentry) will not put the dentry away
254 * immediately, unless we first arrange that its hash list is
258 if ( cache_inode != NULL ) {
259 CDEBUG(D_INODE, "cache ino %ld, count %d, dir %ld, count %d\n",
260 cache_inode->i_ino, atomic_read(&cache_inode->i_count),
261 cache_dir->i_ino, atomic_read(&cache_dir->i_count));
264 d_unalloc(cache_dentry);
268 * Add 'inode' to the directory entry 'dentry'.
270 d_add(dentry, inode);
276 /* instantiate a file handle to the cache file */
277 static void clonefs_prepare_snapfile(struct inode *i,
278 struct file *clone_file,
279 struct inode *cache_inode,
280 struct file *cache_file,
281 struct dentry *cache_dentry)
285 cache_file->f_pos = clone_file->f_pos;
286 cache_file->f_mode = clone_file->f_mode;
287 cache_file->f_flags = clone_file->f_flags;
288 cache_file->f_count = clone_file->f_count;
289 cache_file->f_owner = clone_file->f_owner;
290 cache_file->f_op = cache_inode->i_fop;
291 cache_file->f_dentry = cache_dentry;
292 cache_file->f_dentry->d_inode = cache_inode;
297 /* update the clonefs file struct after IO in cache file */
298 static void clonefs_restore_snapfile(struct inode *cache_inode,
299 struct file *cache_file,
300 struct inode *clone_inode,
301 struct file *clone_file)
305 cache_file->f_pos = clone_file->f_pos;
306 cache_inode->i_size = clone_inode->i_size;
311 static int clonefs_readdir(struct file *file, void *dirent,
315 struct inode *cache_inode;
316 struct file open_file;
317 struct dentry open_dentry;
318 struct inode *inode = file->f_dentry->d_inode;
325 cache_inode = clonefs_get_inode(inode);
328 make_bad_inode(inode);
332 CDEBUG(D_INODE,"clone ino %ld\n",cache_inode->i_ino);
334 clonefs_prepare_snapfile(inode, file, cache_inode, &open_file,
336 /* potemkin case: we are handed a directory inode */
338 if (open_file.f_op->readdir) {
339 down(&cache_inode->i_sem);
340 result = open_file.f_op->readdir(&open_file, dirent, filldir);
341 up(&cache_inode->i_sem);
343 clonefs_restore_snapfile(inode, file, cache_inode, &open_file);
348 struct file_operations clonefs_dir_file_ops = {
349 readdir: clonefs_readdir, /* readdir */
352 struct inode_operations clonefs_dir_inode_ops = {
353 lookup: clonefs_lookup, /* lookup */
357 /* ***************** end of clonefs dir ops ******************* */
358 /* ***************** begin clonefs file ops ******************* */
360 static int clonefs_readpage(struct file *file, struct page *page)
363 struct inode *cache_inode;
364 struct file open_file;
365 struct dentry open_dentry;
370 inode = file->f_dentry->d_inode;
371 cache_inode = clonefs_get_inode(file->f_dentry->d_inode);
373 make_bad_inode(file->f_dentry->d_inode);
377 clonefs_prepare_snapfile(inode, file, cache_inode, &open_file,
379 /* tell currentfs_readpage the primary inode number */
380 open_dentry.d_fsdata = (void*)inode->i_ino;
382 /* potemkin case: we are handed a directory inode */
383 down(&cache_inode->i_sem);
384 /* XXX - readpage NULL on directories... */
385 result = cache_inode->i_mapping->a_ops->readpage(&open_file, page);
387 up(&cache_inode->i_sem);
388 clonefs_restore_snapfile(inode, file, cache_inode, &open_file);
393 struct file_operations clonefs_file_file_ops = {
394 read: generic_file_read, /* read -- bad */
395 mmap: generic_file_mmap, /* mmap */
398 struct address_space_operations clonefs_file_address_ops = {
399 readpage: clonefs_readpage
403 /* ***************** end of clonefs file ops ******************* */
404 /* ***************** begin clonefs symlink ops ******************* */
406 static int clonefs_readlink(struct dentry *dentry, char *buf, int len)
409 struct inode * cache_inode;
410 struct inode * old_inode;
414 cache_inode = clonefs_get_inode(dentry->d_inode);
418 if ( ! cache_inode ) {
419 CDEBUG(D_INODE, "clonefs_get_inode failed, NULL\n");
423 /* XXX: shall we allocate a new dentry ?
424 The following is safe for ext3, etc. because ext2_readlink only
425 use the inode info */
427 /* save the old dentry inode */
428 old_inode = dentry->d_inode;
429 /* set dentry inode to cache inode */
430 dentry->d_inode = cache_inode;
432 if ( cache_inode->i_op->readlink ) {
433 res = cache_inode->i_op->readlink(dentry, buf, len);
435 CDEBUG(D_INODE,"NO readlink for ino %lu\n", cache_inode->i_ino);
438 /* restore the old inode */
439 dentry->d_inode = old_inode;
446 static int clonefs_follow_link(struct dentry * dentry, struct nameidata *nd)
448 struct inode * cache_inode;
449 struct inode * old_inode;
454 cache_inode = clonefs_get_inode(dentry->d_inode);
455 if ( ! cache_inode ) {
456 CDEBUG(D_INODE, "clonefs_get_inode failed, NULL\n");
460 /* XXX: shall we allocate a new dentry ?
461 The following is safe for ext2, etc. because ext2_follow_link
462 only use the inode info */
464 /* save the old dentry inode */
465 old_inode = dentry->d_inode;
466 /* set dentry inode to cache inode */
467 dentry->d_inode = cache_inode;
469 if ( cache_inode->i_op->follow_link ) {
470 res = cache_inode->i_op->follow_link(dentry, nd);
473 /* restore the old inode */
474 dentry->d_inode = old_inode;
481 struct inode_operations clonefs_symlink_inode_ops =
483 /*FIXME later getxattr, listxattr,
484 * other method need to be replaced too
486 readlink: clonefs_readlink, /* readlink */
487 follow_link: clonefs_follow_link,/* follow_link */