4 * A snap shot file system.
8 #define DEBUG_SUBSYSTEM S_SNAP
10 #include <linux/kmod.h>
11 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/jbd.h>
15 #include <linux/ext3_fs.h>
16 #include <linux/string.h>
17 #include <linux/snap.h>
18 #include "snapfs_internal.h"
21 extern int currentfs_remount(struct super_block * sb, int *flags, char *data);
23 /* XXX PJB: this is exactly what we need to put things under
24 filters - we don't want the ext2 methods hardcoded, we want them
25 in the filter (in read_super) and then call those methods.
26 See how InterMezzo gets the journal operations .
29 extern void currentfs_dotsnap_read_inode(struct snap_cache *, struct inode *);
31 static kmem_cache_t *filter_info_cache = NULL;
33 void cleanup_filter_info_cache()
35 kmem_cache_destroy(filter_info_cache);
38 int init_filter_info_cache()
40 filter_info_cache = kmem_cache_create("snapfs_filter_info",
41 sizeof(struct filter_inode_info),
43 if (!filter_info_cache) {
44 CERROR("unable to create snap_inode info cache\n");
51 void init_filter_data(struct inode *inode,
54 struct filter_inode_info *i;
55 struct snap_cache *cache;
56 struct snapshot_operations *snapops;
58 if (inode->i_filterdata || inode->i_ino & 0xF0000000)
60 cache = snap_find_cache(inode->i_dev);
62 CERROR("currentfs_read_inode: cannot find cache\n");
63 make_bad_inode(inode);
66 snapops = filter_c2csnapops(cache->cache_filter);
68 if (inode->i_filterdata) return;
70 inode->i_filterdata = (struct filter_inode_info *) \
71 kmem_cache_alloc(filter_info_cache, SLAB_KERNEL);
72 i = inode->i_filterdata;
73 i -> generation = snapops->get_generation(inode);
77 void set_filter_ops(struct snap_cache *cache, struct inode *inode)
79 /* XXX now set the correct snap_{file,dir,sym}_iops */
80 if (S_ISDIR(inode->i_mode)) {
81 inode->i_op = filter_c2udiops(cache->cache_filter);
82 inode->i_fop = filter_c2udfops(cache->cache_filter);
83 } else if (S_ISREG(inode->i_mode)) {
84 if ( !filter_c2cfiops(cache->cache_filter) ) {
85 filter_setup_file_ops(cache->cache_filter, inode,
88 ¤tfs_file_aops);
90 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
91 inode->i_ino, inode->i_op);
92 inode->i_fop = filter_c2uffops(cache->cache_filter);
93 inode->i_op = filter_c2ufiops(cache->cache_filter);
95 inode->i_mapping->a_ops = filter_c2ufaops(cache->cache_filter);
98 else if (S_ISLNK(inode->i_mode)) {
99 if ( !filter_c2csiops(cache->cache_filter) ) {
100 filter_setup_symlink_ops(cache->cache_filter, inode,
101 ¤tfs_sym_iops, ¤tfs_sym_fops);
103 inode->i_op = filter_c2usiops(cache->cache_filter);
104 inode->i_fop = filter_c2usfops(cache->cache_filter);
105 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
106 inode->i_ino, inode->i_op);
109 int currentfs_setxattr(struct dentry *dentry, const char *name,
110 const void *value, size_t size, int flags)
112 struct snap_cache *cache;
113 struct inode *inode = dentry->d_inode;
114 struct inode_operations *iops;
119 cache = snap_find_cache(inode->i_dev);
121 CERROR("currentfs_setxattr: cannot find cache\n");
125 iops = filter_c2cfiops(cache->cache_filter);
127 if (!iops || !iops->setxattr) {
130 if ( snap_needs_cow(inode) != -1 ) {
131 CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
132 snap_do_cow(inode, dentry->d_parent->d_inode->i_ino, 0);
135 rc = iops->setxattr(dentry, name, value, size, flags);
139 int currentfs_removexattr(struct dentry *dentry, const char *name)
141 struct snap_cache *cache;
142 struct inode *inode = dentry->d_inode;
143 struct inode_operations *iops;
148 cache = snap_find_cache(inode->i_dev);
150 CERROR("currentfs_setxattr: cannot find cache\n");
154 iops = filter_c2cfiops(cache->cache_filter);
156 if (!iops || !iops->removexattr) {
160 if (snap_needs_cow(inode) != -1) {
161 CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
162 snap_do_cow(inode, dentry->d_parent->d_inode->i_ino, 0);
164 rc = iops->removexattr(dentry, name);
169 int currentfs_setattr(struct dentry *dentry, struct iattr *attr)
171 struct snap_cache *cache;
172 struct inode *inode = dentry->d_inode;
173 struct inode_operations *iops;
178 cache = snap_find_cache(inode->i_dev);
180 CERROR("currentfs_setxattr: cannot find cache\n");
184 iops = filter_c2cfiops(cache->cache_filter);
186 if (!iops || !iops->setattr) {
189 if ( snap_needs_cow(inode) != -1 ) {
190 CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
191 snap_do_cow(inode, dentry->d_parent->d_inode->i_ino, 0);
194 rc = iops->setattr(dentry, attr);
198 /* Superblock operations. */
199 static void currentfs_read_inode(struct inode *inode)
201 struct snap_cache *cache;
206 CDEBUG(D_INODE, "read_inode ino %lu\n", inode->i_ino);
208 cache = snap_find_cache(inode->i_dev);
210 CERROR("currentfs_read_inode: cannot find cache\n");
211 make_bad_inode(inode);
215 if (inode->i_ino & 0xF0000000) {
216 currentfs_dotsnap_read_inode(cache, inode);
220 if(filter_c2csops(cache->cache_filter))
221 filter_c2csops(cache->cache_filter)->read_inode(inode);
223 CDEBUG(D_INODE, "read_inode ino %lu icount %d \n",
224 inode->i_ino, atomic_read(&inode->i_count));
225 set_filter_ops(cache, inode);
226 /*init filter_data struct
227 * FIXME flag should be set future*/
228 init_filter_data(inode, 0);
229 CDEBUG(D_INODE, "read_inode ino %lu icount %d \n",
230 inode->i_ino, atomic_read(&inode->i_count));
234 static void currentfs_put_super(struct super_block *sb)
237 struct snap_cache *cache;
240 CDEBUG(D_SUPER, "sb %lx, sb->u.generic_sbp: %lx\n",
241 (ulong) sb, (ulong) sb->u.generic_sbp);
242 cache = snap_find_cache(sb->s_dev);
247 /* handle COMPAT_FEATUREs */
248 #ifdef CONFIG_SNAPFS_EXT2
249 else if( cache->cache_type == FILTER_FS_EXT2 ){
250 if( !EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_SNAPFS) ){
251 sb->u.ext2_sb.s_feature_compat &=
252 ~EXT2_FEATURE_COMPAT_BLOCKCOW;
253 sb->u.ext2_sb.s_es->s_feature_compat &=
254 cpu_to_le32(~EXT2_FEATURE_COMPAT_BLOCKCOW);
258 #ifdef CONFIG_SNAPFS_EXT3
259 else if( cache->cache_type == FILTER_FS_EXT3 ){
260 if( !EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_SNAPFS) ){
261 sb->u.ext3_sb.s_es->s_feature_compat &=
262 cpu_to_le32(~EXT3_FEATURE_COMPAT_BLOCKCOW);
267 * If there is a saved 'put_super' function for the underlying
270 if (cache->cache_filter->o_caops.cache_sops->put_super) {
271 cache->cache_filter->o_caops.cache_sops->put_super(sb);
274 if (!list_empty(&cache->cache_clone_list)) {
275 CWARN("snap_put_super: clones exist!\n");
278 list_del(&cache->cache_chain);
279 snap_free_cache(cache);
281 CDEBUG(D_SUPER, "sb %lx, sb->u.generic_sbp: %lx\n",
282 (ulong) sb, (ulong) sb->u.generic_sbp);
287 static void currentfs_clear_inode(struct inode *inode)
289 struct snap_cache *cache;
290 struct super_operations *sops;
292 cache = snap_find_cache(inode->i_dev);
294 CDEBUG(D_INODE, "inode has invalid dev\n");
298 if (inode->i_filterdata) {
299 kmem_cache_free(filter_info_cache, inode->i_filterdata);
300 inode->i_filterdata = NULL;
303 sops = filter_c2csops(cache->cache_filter);
304 if (sops && sops->clear_inode)
305 sops->clear_inode(inode);
308 struct super_operations currentfs_super_ops = {
309 read_inode: currentfs_read_inode,
310 put_super: currentfs_put_super,
311 clear_inode: currentfs_clear_inode,