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 } else if (S_ISDIR(inode->i_mode)) {
110 inode->i_op = &clonefs_dir_inode_ops;
111 } else if (S_ISLNK(inode->i_mode)) {
112 inode->i_op = &clonefs_symlink_inode_ops;
114 /* init special inode
115 * FIXME whether we should replace special inode ops*/
116 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
117 init_special_inode(inode, inode->i_mode,
118 kdev_t_to_nr(inode->i_rdev));
120 init_special_inode(inode, inode->i_mode, inode->i_rdev);
125 CDEBUG(D_SNAP, "cache_inode: %lx ino %ld, sb %lx, count %d\n",
126 (unsigned long) cache_inode, cache_inode->i_ino,
127 (unsigned long) cache_inode->i_sb,
128 atomic_read(&cache_inode->i_count));
133 static void clonefs_put_super(struct super_block *sb)
135 struct snap_clone_info *clone_sb;
138 CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
139 (unsigned long) sb, (unsigned long) &sb->u.generic_sbp);
140 clone_sb = (struct snap_clone_info *)&sb->u.generic_sbp;
141 dput(clone_sb->clone_cache->cache_sb->s_root);
142 list_del(&clone_sb->clone_list_entry);
147 static int clonefs_statfs(struct super_block *sb, struct statfs *buf)
149 struct snap_clone_info *clone_sb;
150 struct snap_cache *cache;
153 clone_sb = (struct snap_clone_info *)&sb->u.generic_sbp;
155 cache = clone_sb->clone_cache;
157 CERROR("clone_statfs: no cache\n");
161 return cache->cache_filter->o_caops.cache_sops->statfs
162 (cache->cache_sb, buf);
165 struct super_operations clone_super_ops =
167 read_inode: clonefs_read_inode, /* read_inode */
168 put_super: clonefs_put_super, /* put_super */
169 statfs: clonefs_statfs, /* statfs */
173 /* ***************** end of clonefs super ops ******************* */
174 /* ***************** begin clonefs dir ops ******************* */
176 static void d_unalloc(struct dentry *dentry)
179 list_del(&dentry->d_hash);
180 INIT_LIST_HEAD(&dentry->d_hash);
181 dput(dentry); /* this will free the dentry memory */
185 * Return the underlying fs dentry with name in 'dentry' that points
186 * to the right inode. 'dir' is the clone fs directory to search for
189 struct dentry *clonefs_lookup(struct inode *dir, struct dentry *dentry)
191 struct inode *cache_dir;
192 struct dentry *cache_dentry;
193 struct inode *cache_inode;
194 struct dentry *result;
196 struct snap_clone_info *clone_sb;
200 cache_dir = clonefs_get_inode(dir);
202 cache_dentry = d_alloc(dentry->d_parent, &dentry->d_name);
205 RETURN(ERR_PTR(-ENOENT));
208 /* Lock cache directory inode. */
209 down(&cache_dir->i_sem);
211 * Call underlying fs lookup function to set the 'd_inode' pointer
212 * to the corresponding directory inode.
214 * Note: If the lookup function does not return NULL, return
215 * from 'clone_lookup' with an error.
217 result = cache_dir->i_op->lookup(cache_dir, cache_dentry);
220 up(&cache_dir->i_sem);
222 dentry->d_inode = NULL;
223 RETURN(ERR_PTR(-ENOENT));
225 /* Unlock cache directory inode. */
226 up(&cache_dir->i_sem);
229 * If there is no inode pointer in the underlying fs 'cache_dentry'
230 * then the directory doesn't have an entry with this name. In fs/ext2
231 * we see that we return 0 and put dentry->d_inode = NULL;
233 cache_inode = cache_dentry->d_inode;
234 if ( cache_inode == NULL ) {
237 clone_sb = (struct snap_clone_info *) &dir->i_sb->u.generic_sbp;
238 /* note, iget below will follow a redirector, since
239 it calls into clone_read_inode
241 inode = iget(dir->i_sb, cache_inode->i_ino);
244 /* dput(cache_dentry) will not put the dentry away
245 * immediately, unless we first arrange that its hash list is
249 if ( cache_inode != NULL ) {
250 CDEBUG(D_INODE, "cache ino %ld, count %d, dir %ld, count %d\n",
251 cache_inode->i_ino, atomic_read(&cache_inode->i_count),
252 cache_dir->i_ino, atomic_read(&cache_dir->i_count));
255 d_unalloc(cache_dentry);
259 * Add 'inode' to the directory entry 'dentry'.
261 d_add(dentry, inode);
267 /* instantiate a file handle to the cache file */
268 static void clonefs_prepare_snapfile(struct inode *i,
269 struct file *clone_file,
270 struct inode *cache_inode,
271 struct file *cache_file,
272 struct dentry *cache_dentry)
276 cache_file->f_pos = clone_file->f_pos;
277 cache_file->f_mode = clone_file->f_mode;
278 cache_file->f_flags = clone_file->f_flags;
279 cache_file->f_count = clone_file->f_count;
280 cache_file->f_owner = clone_file->f_owner;
281 cache_file->f_op = cache_inode->i_fop;
282 cache_file->f_dentry = cache_dentry;
283 cache_file->f_dentry->d_inode = cache_inode;
288 /* update the clonefs file struct after IO in cache file */
289 static void clonefs_restore_snapfile(struct inode *cache_inode,
290 struct file *cache_file,
291 struct inode *clone_inode,
292 struct file *clone_file)
296 cache_file->f_pos = clone_file->f_pos;
297 cache_inode->i_size = clone_inode->i_size;
302 static int clonefs_readdir(struct file *file, void *dirent,
306 struct inode *cache_inode;
307 struct file open_file;
308 struct dentry open_dentry;
309 struct inode *inode=file->f_dentry->d_inode;
316 cache_inode = clonefs_get_inode(inode);
319 make_bad_inode(inode);
323 CDEBUG(D_INODE,"clone ino %ld\n",cache_inode->i_ino);
325 clonefs_prepare_snapfile(inode, file, cache_inode, &open_file,
327 /* potemkin case: we are handed a directory inode */
329 if (open_file.f_op->readdir) {
330 down(&cache_inode->i_sem);
331 result = open_file.f_op->readdir(&open_file, dirent, filldir);
332 up(&cache_inode->i_sem);
334 clonefs_restore_snapfile(inode, file, cache_inode, &open_file);
339 struct file_operations clonefs_dir_file_ops = {
340 readdir: clonefs_readdir, /* readdir */
343 struct inode_operations clonefs_dir_inode_ops = {
344 lookup: clonefs_lookup, /* lookup */
348 /* ***************** end of clonefs dir ops ******************* */
349 /* ***************** begin clonefs file ops ******************* */
351 static int clonefs_readpage(struct file *file, struct page *page)
354 struct inode *cache_inode;
355 struct file open_file;
356 struct dentry open_dentry;
361 inode = file->f_dentry->d_inode;
362 cache_inode = clonefs_get_inode(file->f_dentry->d_inode);
364 make_bad_inode(file->f_dentry->d_inode);
368 clonefs_prepare_snapfile(inode, file, cache_inode, &open_file,
370 /* tell currentfs_readpage the primary inode number */
371 open_dentry.d_fsdata = (void*)inode->i_ino;
373 /* potemkin case: we are handed a directory inode */
374 down(&cache_inode->i_sem);
375 /* XXX - readpage NULL on directories... */
376 result = cache_inode->i_mapping->a_ops->readpage(&open_file, page);
378 up(&cache_inode->i_sem);
379 clonefs_restore_snapfile(inode, file, cache_inode, &open_file);
384 struct file_operations clonefs_file_file_ops = {
385 read: generic_file_read, /* read -- bad */
386 mmap: generic_file_mmap, /* mmap */
389 struct address_space_operations clonefs_file_address_ops = {
390 readpage: clonefs_readpage
394 /* ***************** end of clonefs file ops ******************* */
395 /* ***************** begin clonefs symlink ops ******************* */
397 static int clonefs_readlink(struct dentry *dentry, char *buf, int len)
400 struct inode * cache_inode;
401 struct inode * old_inode;
405 cache_inode = clonefs_get_inode(dentry->d_inode);
409 if ( ! cache_inode ) {
410 CDEBUG(D_INODE, "clonefs_get_inode failed, NULL\n");
414 /* XXX: shall we allocate a new dentry ?
415 The following is safe for ext3, etc. because ext2_readlink only
416 use the inode info */
418 /* save the old dentry inode */
419 old_inode = dentry->d_inode;
420 /* set dentry inode to cache inode */
421 dentry->d_inode = cache_inode;
423 if ( cache_inode->i_op->readlink ) {
424 res = cache_inode->i_op->readlink(dentry, buf, len);
426 CDEBUG(D_INODE,"NO readlink for ino %lu\n", cache_inode->i_ino);
429 /* restore the old inode */
430 dentry->d_inode = old_inode;
437 static int clonefs_follow_link(struct dentry * dentry, struct nameidata *nd)
439 struct inode * cache_inode;
440 struct inode * old_inode;
445 cache_inode = clonefs_get_inode(dentry->d_inode);
446 if ( ! cache_inode ) {
447 CDEBUG(D_INODE, "clonefs_get_inode failed, NULL\n");
451 /* XXX: shall we allocate a new dentry ?
452 The following is safe for ext2, etc. because ext2_follow_link
453 only use the inode info */
455 /* save the old dentry inode */
456 old_inode = dentry->d_inode;
457 /* set dentry inode to cache inode */
458 dentry->d_inode = cache_inode;
460 if ( cache_inode->i_op->follow_link ) {
461 res = cache_inode->i_op->follow_link(dentry, nd);
464 /* restore the old inode */
465 dentry->d_inode = old_inode;
472 struct inode_operations clonefs_symlink_inode_ops =
474 /*FIXME later getxattr, listxattr,
475 * other method need to be replaced too
477 readlink: clonefs_readlink, /* readlink */
478 follow_link: clonefs_follow_link,/* follow_link */