Whamcloud - gitweb
update snapfs
[fs/lustre-release.git] / lustre / snapfs / snapfs_internal.h
1 #ifndef __LINUX_SNAPFS_H
2 #define __LINUX_SNAPFS_H
3 /* maximum number of snapshot tables we maintain in the kernel */
4 #define SNAP_MAX                32      
5 #define SNAP_MAX_TABLES         32      
6 #define SNAP_MAX_NAMELEN        64
7
8 /* ioctls for manipulating snapshots 40 - 60 */
9 #define IOC_SNAP_TYPE                   'f'
10 #define IOC_SNAP_MIN_NR                 41
11
12 #define IOC_SNAP_SETTABLE               _IOWR('f', 41, long)
13 #define IOC_SNAP_PRINTTABLE             _IOWR('f', 42, long)
14 #define IOC_SNAP_GETINDEXFROMNAME       _IOWR('f', 43, long)
15 #define IOC_SNAP_GET_NEXT_INO           _IOWR('f', 44, long)
16 #define IOC_SNAP_GET_INO_INFO           _IOWR('f', 45, long)
17
18 #define IOC_SNAP_ADD                    _IOWR('f', 46, long)
19 #define IOC_SNAP_DELETE                 _IOWR('f', 47, long)
20 #define IOC_SNAP_RESTORE                _IOWR('f', 48, long)
21 #define IOC_SNAP_DEBUG                  _IOWR('f', 49, long)
22 #define IOC_SNAP_DEVFAIL                _IOWR('f', 50, long)
23 #define IOC_SNAP_SHOW_DOTSNAP           _IOWR('f', 51, long)
24
25 #define IOC_SNAP_MAX_NR                 51 
26
27 struct snap {
28         time_t          time;
29         unsigned int    index;
30         unsigned int    gen;
31         unsigned int    flags;
32         char    name[SNAP_MAX_NAMELEN];
33 };
34
35
36 /*FIXME, use ioc_data temporary, will use obd_ioc_data later*/
37 struct ioc_data {
38         unsigned int ioc_inlen;
39         char         *ioc_inbuf;
40         char         ioc_bulk[0];
41 };
42
43 /* snap ioctl data for table fiddling */
44 struct ioc_snap_tbl_data {
45         int             no;             /* which table */
46         unsigned long   dev;
47         unsigned int    count;          /* how many snaps */
48         struct snap     snaps[0];       /* sorted times! */
49 };
50
51 /* we have just a single snapshot control device
52    it contains a list of all the snap_current info's
53 */
54 #define SNAPDEV_NAME "/dev/snapconf"
55 #define SNAP_PSDEV_MINOR 240
56 #define SNAP_PSDEV_MAJOR 10
57
58 #define SNAP_TABLE_OUTBUF_LEN   1020
59
60 #ifdef __KERNEL__
61
62 #if 0
63 #include <linux/lustre_lib.h>
64 #else
65 #include "snapfs_support.h" 
66 #endif
67 /* What we use to point to IDs in the obdmd data for snapshots.  If we use
68  * obd_id (8 bytes) instead of ino_t (4 bytes), we halve the number of
69  * available snapshot slots (14 in 56 bytes vs. 7 in 56 bytes until we
70  * increase the size of OBD_OBDMDSZ).
71  */
72 typedef ino_t   snap_id;
73
74
75 /* maximum number of snapshots per device 
76    must fit in "o_obdmd" area of struct obdo */
77 //#define OBD_OBDMDSZ  54
78 //#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id))
79
80
81
82 /* if time is 0 this designates the "current" snapshot, i.e.
83    the head of the tree 
84 */
85
86 /* sysctl.c */
87 extern int init_snapfs_proc_sys(void);
88 extern void cleanup_spapfs_proc_sys(void);
89 extern int snap_print_entry;
90 extern int snap_debug_level;
91 extern int snap_inodes;
92 extern long snap_kmemory;
93 extern int snap_stack;
94
95 /* snap cache information: this morally equals the superblock of a
96  snap_current_fs.  However, that superblock is the one of the "cache"
97  device holding the inodes, hence we store this info in the hash of
98  mountpoints hanging of our control device. 
99 */
100 struct snap_cache {
101         struct list_head cache_chain;
102
103         kdev_t cache_dev;
104         struct super_block *cache_sb; /* the _real_ device */
105
106         struct list_head cache_clone_list;
107         int cache_snap_tableno;
108
109         struct filter_fs *cache_filter;
110
111         char cache_type;
112         char cache_show_dotsnap;
113 };
114
115 /* this is the snap_clone_info for the sb of snap_clone_fs */
116 struct snap_clone_info {
117         struct snap_cache *clone_cache;
118         struct list_head clone_list_entry;
119         int clone_index;
120 };
121
122 /* 
123  * it is important that things like inode, super and file operations
124  * for intermezzo are not defined statically.  If methods are NULL
125  * the VFS takes special action based on that.  Given that different
126  * cache types have NULL ops at different slots, we must install opeation 
127  * talbes for InterMezzo with NULL's in the same spot
128  */
129
130 struct filter_ops {
131         /* operations on the file store */
132         struct super_operations filter_sops;
133
134         struct inode_operations filter_dir_iops;
135         struct inode_operations filter_file_iops;
136         struct inode_operations filter_sym_iops;
137
138         struct file_operations filter_dir_fops;
139         struct file_operations filter_file_fops;
140         struct file_operations filter_sym_fops;
141
142         struct address_space_operations filter_file_aops;
143         struct dentry_operations filter_dentry_ops;
144 };
145
146
147 struct cache_ops {
148         /* operations on the file store */
149         struct super_operations *cache_sops;
150
151         struct inode_operations *cache_dir_iops;
152         struct inode_operations *cache_file_iops;
153         struct inode_operations *cache_sym_iops;
154
155         struct file_operations *cache_dir_fops;
156         struct file_operations *cache_file_fops;
157         struct file_operations *cache_sym_fops;
158
159         struct address_space_operations *cache_file_aops;
160         struct dentry_operations *cache_dentry_ops;
161 };
162
163
164 #define SNAP_OP_NOOP            0
165 #define SNAP_OP_CREATE          1
166 #define SNAP_OP_MKDIR           2
167 #define SNAP_OP_UNLINK          3
168 #define SNAP_OP_RMDIR           4
169 #define SNAP_OP_CLOSE           5
170 #define SNAP_OP_SYMLINK         6
171 #define SNAP_OP_RENAME          7
172 #define SNAP_OP_SETATTR         8
173 #define SNAP_OP_LINK            9
174 #define SNAP_OP_OPEN            10
175 #define SNAP_OP_MKNOD           11
176 #define SNAP_OP_WRITE           12
177 #define SNAP_OP_RELEASE         13
178
179 struct journal_ops {
180         void *(*trans_start)(struct inode *, int op);
181         void (*trans_commit)(void *handle);
182 };
183
184 struct snap_control_device {
185         struct list_head snap_dev_list;
186 };
187
188 #define D_MAXLEN 1024
189
190 #define SNAPSHOT_UNUSED_FLAG            (1 << 0)
191 #define SNAPSHOT_GOOD_FLAG              (1 << 1)
192 #define SNAPSHOT_DELETING_FLAG          (1 << 2)
193 #define SNAPSHOT_BAD_FLAG               (1 << 3)        
194
195 struct snap_disk {
196         __u64   time;
197         __u32   gen;
198         __u32   index;
199         __u32   flags;
200         char    name[SNAP_MAX_NAMELEN];
201 };
202 /* snap ioctl data for attach: current always in first slot of this array */
203 struct snap_obd_data {
204         int          snap_dev;  /* which device contains the data */
205         unsigned int snap_index;/* which snapshot is ours */
206         unsigned int snap_table;/* which table do we use */
207 };
208 #define DISK_SNAPTABLE_ATTR     "Snaptable"
209 #define DISK_SNAP_TABLE_MAGIC   0x1976
210 struct snap_disk_table {
211         unsigned int            magic;
212         unsigned int            count;
213         unsigned int            generation;
214         struct  snap_disk       snap_items[SNAP_MAX];
215 };
216
217 /*Snap Table*/
218 struct snap_table {
219         struct semaphore    tbl_sema;
220         spinlock_t          tbl_lock;
221         unsigned int        tbl_count; /* how many snapshots exist in this table*/
222         unsigned int        generation;
223         struct snap         snap_items[SNAP_MAX]; 
224 };
225
226 struct snap_iterdata {
227         kdev_t dev;     /* snap current device number */ 
228         int index;
229         int tableno;
230         time_t time;
231 };
232
233 struct snap_ioc_data {
234         kdev_t dev;
235         char name[SNAP_MAX_NAMELEN];
236 };
237
238 struct snap_ino_list_data{
239         kdev_t dev;
240         ino_t ino;
241 };
242 struct filter_inode_info {
243         int flags;              /* the flags indicated inode type */
244         int generation;         /*the inode generation*/
245 };
246 /* dotsnap.c */
247 extern int currentfs_is_under_dotsnap(struct dentry *de);
248
249 /* cache.c */
250 inline void snap_free_cache(struct snap_cache *cache);
251 struct snap_cache *snap_find_cache(kdev_t dev);
252
253 /* snaptable.c */
254 extern struct snap_table snap_tables[SNAP_MAX_TABLES];
255 void snap_last(struct snap_cache *info, struct snap *snap);
256 int snap_index2slot(struct snap_table *snap_table, int snap_index);
257 int snap_needs_cow(struct inode *);
258 int snapfs_read_snaptable(struct snap_cache *cache, int tableno);
259 /* snap.c */
260 int snap_is_redirector(struct inode *inode);
261 struct inode *snap_redirect(struct inode *inode, struct super_block *clone_sb);
262 int snap_do_cow(struct inode *inode, ino_t parent_ino, int del);
263
264 int snap_iterate(struct super_block *sb,
265                 int (*repeat)(struct inode *inode, void *priv),
266                 struct inode **start, void *priv, int flag);
267
268 struct inode *snap_get_indirect(struct inode *pri, int *table, int slot);
269 int snap_destroy_indirect(struct inode *pri, int index, struct inode *next_ind);
270 int snap_restore_indirect(struct inode *pri, int index );
271 int snap_migrate_data(struct inode *dst, struct inode *src);
272 int snap_set_indirect(struct inode *pri, ino_t ind_ino, 
273                         int index, ino_t parent_ino);
274
275 /* inode.c */
276 extern struct super_operations currentfs_super_ops;
277 void cleanup_filter_info_cache(void);
278 int init_filter_info_cache(void);
279 void init_filter_data(struct inode *inode, struct snapshot_operations *snapops,
280                      int flag);
281
282 /* dir.c */
283 extern struct inode_operations currentfs_dir_iops;
284 extern struct file_operations currentfs_dir_fops;
285 extern struct address_space_operations currentfs_file_aops;
286
287 /* file.c */
288 extern struct inode_operations currentfs_file_iops;
289 extern struct file_operations currentfs_file_fops;
290
291 /* symlink.c */
292 extern struct inode_operations currentfs_sym_iops;
293 extern struct file_operations currentfs_sym_fops;
294
295 extern struct dentry_operations currentfs_dentry_ops;
296
297
298
299 #define FILTER_DID_SUPER_OPS    0x1
300 #define FILTER_DID_INODE_OPS    0x2
301 #define FILTER_DID_FILE_OPS     0x4
302 #define FILTER_DID_DENTRY_OPS   0x8
303 #define FILTER_DID_DEV_OPS      0x10
304 #define FILTER_DID_SYMLINK_OPS  0x20
305 #define FILTER_DID_DIR_OPS      0x40
306 #define FILTER_DID_SNAPSHOT_OPS 0x80
307 #define FILTER_DID_JOURNAL_OPS  0x100
308
309 struct filter_fs {
310         int o_flags;
311         struct filter_ops o_fops;
312         struct cache_ops  o_caops;
313         struct journal_ops *o_trops;
314         struct snapshot_operations *o_snapops;
315 };
316
317 #define FILTER_FS_TYPES 3
318 #define FILTER_FS_EXT2 0
319 #define FILTER_FS_EXT3 1
320 #define FILTER_FS_REISER 2
321 extern struct filter_fs filter_oppar[FILTER_FS_TYPES];
322
323 struct filter_fs *filter_get_filter_fs(const char *cache_type);
324 inline struct super_operations *filter_c2usops(struct filter_fs *cache);
325 inline struct inode_operations *filter_c2ufiops(struct filter_fs *cache);
326 inline struct inode_operations *filter_c2udiops(struct filter_fs *cache);
327 inline struct inode_operations *filter_c2usiops(struct filter_fs *cache);
328 inline struct super_operations *filter_c2csops(struct filter_fs *cache);
329 inline struct inode_operations *filter_c2cfiops(struct filter_fs *cache);
330 inline struct inode_operations *filter_c2cdiops(struct filter_fs *cache);
331 inline struct inode_operations *filter_c2csiops(struct filter_fs *cache);
332 inline struct file_operations *filter_c2cffops(struct filter_fs *cache);
333 inline struct file_operations *filter_c2cdfops(struct filter_fs *cache);
334 inline struct file_operations *filter_c2csfops(struct filter_fs *cache);
335 inline struct dentry_operations *filter_c2cdops(struct filter_fs *cache);
336 inline struct dentry_operations *filter_c2udops(struct filter_fs *cache);
337 inline struct address_space_operations *filter_c2cfaops(struct filter_fs *cache);
338 /* for snapfs */
339 inline struct snapshot_operations *filter_c2csnapops(struct filter_fs *cache);
340
341 void filter_setup_file_ops(struct filter_fs        *cache, 
342                            struct inode            *inode,
343                            struct inode_operations *filter_iops,
344                            struct file_operations  *filter_fops,
345                            struct address_space_operations *filter_aops);
346
347 void filter_setup_dir_ops(struct filter_fs *cache, 
348                           struct inode     *inode,
349                           struct inode_operations *filter_iops, 
350                           struct file_operations *filter_fops);
351
352 void filter_setup_symlink_ops(struct filter_fs *cache, 
353                               struct inode *inode,
354                               struct inode_operations *filter_iops, 
355                               struct file_operations *filter_fops);
356
357 void filter_setup_dentry_ops(struct filter_fs *cache,
358                              struct dentry_operations *cache_dop, 
359                              struct dentry_operations *filter_dop);
360 void filter_setup_super_ops(struct filter_fs *cache, 
361                             struct super_operations *cache_sops, 
362                             struct super_operations *filter_sops);
363 /* for snapfs */
364 void filter_setup_snapshot_ops(struct filter_fs *cache, 
365                                struct snapshot_operations *cache_snapops);
366 void filter_setup_journal_ops(struct filter_fs *cache, 
367                               struct journal_ops *cache_journal_ops);
368
369 static inline void* snap_trans_start(struct snap_cache *cache, 
370                                      struct inode *inode, int op)
371 {
372         if( cache->cache_filter->o_trops )
373                 return cache->cache_filter->o_trops->trans_start(inode, op);
374         return NULL;
375 };
376 static inline void snap_trans_commit(struct snap_cache *cache, void *handle)
377 {
378         if( cache->cache_filter->o_trops )
379                 cache->cache_filter->o_trops->trans_commit(handle);
380 };
381
382 static inline void snapfs_cpy_attrs(struct inode *dst, struct inode *src)
383 {
384         dst->i_mtime = src->i_mtime;
385         dst->i_ctime = src->i_ctime;
386         dst->i_atime = src->i_atime;
387         dst->i_size = src->i_size;
388         dst->i_blksize = src->i_blksize;
389         dst->i_blocks = src->i_blocks;
390         dst->i_generation = src->i_generation;
391         dst->i_uid = src->i_uid;
392         dst->i_gid = src->i_gid;
393         dst->i_mode = src->i_mode;
394 }
395 #ifdef SNAP_DEBUG
396 extern unsigned int snap_debug_failcode;
397 #ifdef CONFIG_LOOP_DISCARD
398 #define BLKDEV_FAIL(dev,fail) loop_discard_io(dev,fail)
399 #else
400 #define BLKDEV_FAIL(dev,fail) set_device_ro(dev, 1)
401 #endif
402
403 static inline void snap_debug_device_fail(dev_t dev, unsigned short opcode, unsigned short pos)
404 {
405         unsigned int failcode = (opcode<<16) | pos;
406
407         if( failcode == snap_debug_failcode && !is_read_only(dev)){
408                 printk(KERN_EMERG "set block device %s into fail mode\n", bdevname(dev));
409                 BLKDEV_FAIL(dev, 1);
410         }
411 }
412 #else
413 #define snap_debug_device_fail(args...) do{}while(0)
414 #endif
415
416 extern int snap_debug_level;
417 extern int snap_print_entry;
418
419 #endif /*_KERNEL_*/
420 #endif /* __LINUX_SNAPFS_H */