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