5 * A snap shot file system.
9 #define DEBUG_SUBSYSTEM S_SNAP
11 #include <linux/kmod.h>
12 #include <linux/init.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
16 #include <linux/snap.h>
17 #include "snapfs_internal.h"
20 * Return true if the inode is a redirector inode.
22 int snap_is_redirector(struct inode *cache_inode)
24 struct snap_cache *cache;
25 struct snapshot_operations *snapops;
27 cache = snap_find_cache(cache_inode->i_dev);
31 snapops = filter_c2csnapops(cache->cache_filter);
32 if (!snapops || !snapops->is_redirector) {
36 CDEBUG(D_SNAP, "ino %ld\n", cache_inode->i_ino);
37 return snapops->is_redirector(cache_inode);
41 * Using a cache inode and clone super block find the real one.
43 struct inode *snap_redirect(struct inode *cache_inode,
44 struct super_block *clone_sb)
46 struct snap_clone_info *clone_info;
47 struct snap_table *table;
48 struct inode *redirected;
49 struct snap_cache *cache;
50 struct snapshot_operations *snapops;
52 int my_table[SNAP_MAX];
57 cache = snap_find_cache(cache_inode->i_dev);
61 snapops = filter_c2csnapops(cache->cache_filter);
62 if (!snapops || !snapops->get_indirect) {
66 CDEBUG(D_SNAP, "cache ino %ld\n", cache_inode->i_ino);
67 clone_info = (struct snap_clone_info *)&clone_sb->u.generic_sbp;
69 table = &snap_tables[clone_info->clone_cache->cache_snap_tableno];
71 /* first find if there are indirected at the clone_index */
72 redirected = snapops->get_indirect(cache_inode, NULL,
73 clone_info->clone_index);
74 /* if not found, get the FIRST index after this and before NOW */
75 /* XXX fix this later, now use tbl_count, not NOW */
78 clone_slot = snap_index2slot(table, clone_info->clone_index);
79 for (slot = table->tbl_count; slot >= clone_slot; slot --) {
80 my_table[slot-clone_slot+1] = table->snap_items[slot].index;
82 index = table->tbl_count - clone_slot + 1;
83 redirected = snapops->get_indirect(cache_inode, my_table, index);
87 CDEBUG(D_SNAP,"redirected ino %ld\n",redirected->i_ino);
93 * Make a copy of the data and plug a redirector in between if there
94 * is no redirector yet.
96 int snap_do_cow(struct inode *inode, ino_t parent_ino, int del)
98 struct snap_cache *cache;
100 struct inode *ind = NULL;
101 struct snapshot_operations *snapops;
104 CDEBUG(D_SNAP, "snap_do_cow, ino %ld\n", inode->i_ino);
106 cache = snap_find_cache(inode->i_dev);
110 snapops = filter_c2csnapops(cache->cache_filter);
111 if (!snapops || !snapops->create_indirect) {
115 snap_last(cache, &snap);
116 ind = snapops->create_indirect(inode, snap.index, 0, parent_ino, del);
123 int snap_iterate(struct super_block *sb,
124 int (*repeat)(struct inode *inode, void *priv),
125 struct inode **start, void *priv, int flag)
127 struct inode *inode = sb->s_root->d_inode;
128 struct snap_cache *cache;
129 struct snapshot_operations *snapops;
133 cache = snap_find_cache(inode->i_dev);
137 snapops = filter_c2csnapops(cache->cache_filter);
138 if (!snapops || !snapops->iterate) {
142 return snapops->iterate(sb, repeat, start, priv, flag);
145 int snap_destroy_indirect(struct inode *pri, int index, struct inode *next_ind )
147 struct snap_cache *cache;
148 struct snapshot_operations *snapops;
151 cache = snap_find_cache(pri->i_dev);
154 snapops = filter_c2csnapops(cache->cache_filter);
155 if (!snapops || !snapops->destroy_indirect)
158 return snapops->destroy_indirect(pri, index, next_ind);
161 int snap_restore_indirect(struct inode *pri, int index )
163 struct snap_cache *cache;
164 struct snapshot_operations *snapops;
168 cache = snap_find_cache(pri->i_dev);
172 snapops = filter_c2csnapops(cache->cache_filter);
173 if (!snapops || !snapops->restore_indirect)
176 return snapops->restore_indirect(pri, index);
179 struct inode *snap_get_indirect(struct inode *pri, int *table, int slot)
181 struct snap_cache *cache;
182 struct snapshot_operations *snapops;
186 cache = snap_find_cache(pri->i_dev);
190 snapops = filter_c2csnapops(cache->cache_filter);
191 if (!snapops || !snapops->get_indirect)
194 return snapops->get_indirect(pri, table, slot);
197 int snap_set_indirect(struct inode *pri, ino_t ind_ino, int index, ino_t parent_ino)
199 struct snap_cache *cache;
200 struct snapshot_operations *snapops;
204 cache = snap_find_cache(pri->i_dev);
208 snapops = filter_c2csnapops(cache->cache_filter);
209 if (!snapops || !snapops->set_indirect)
213 return snapops->set_indirect(pri, ind_ino, index, parent_ino);