Skip to content
Snippets Groups Projects
Commit ff5a3e46 authored by Wang Di's avatar Wang Di
Browse files

add snapfs_internal.h snapfs_support.h Makefile.am

parent e26057da
No related branches found
No related tags found
No related merge requests found
# Copyright (C) 2001 Cluster File Systems, Inc.
#
# This code is issued under the GNU General Public License.
# See the file COPYING in this distribution
DEFS=
SUBDIRS = . utils
MODULE = snapfs
modulefs_DATA = snapfs.o
EXTRA_PROGRAMS = snapfs
snapfs_SOURCES = cache.c clonefs.c dcache.c dir.c dotsnap.c file.c
snapfs_SOURCES += filter.c inode.c journal_ext3.c psdev.c
snapfs_SOURCES += snap.c snaptable.c super.c symlink.c sysctl.c
include $(top_srcdir)/Rules
#ifndef __LINUX_SNAPFS_H
#define __LINUX_SNAPFS_H
/* maximum number of snapshot tables we maintain in the kernel */
#define SNAP_MAX_TABLES 32
#define SNAP_MAX_NAMELEN 64
/* ioctls for manipulating snapshots 40 - 60 */
#define IOC_SNAP_TYPE 'f'
#define IOC_SNAP_MIN_NR 41
#define IOC_SNAP_SETTABLE _IOWR('f', 41, long)
#define IOC_SNAP_PRINTTABLE _IOWR('f', 42, long)
#define IOC_SNAP_GETINDEXFROMNAME _IOWR('f', 43, long)
#define IOC_SNAP_GET_NEXT_INO _IOWR('f', 44, long)
#define IOC_SNAP_GET_INO_INFO _IOWR('f', 45, long)
#define IOC_SNAP_ADD _IOWR('f', 46, long)
#define IOC_SNAP_DELETE _IOWR('f', 47, long)
#define IOC_SNAP_RESTORE _IOWR('f', 48, long)
#define IOC_SNAP_DEBUG _IOWR('f', 49, long)
#define IOC_SNAP_DEVFAIL _IOWR('f', 50, long)
#define IOC_SNAP_SHOW_DOTSNAP _IOWR('f', 51, long)
#define IOC_SNAP_MAX_NR 51
struct snap {
time_t time;
unsigned int index;
unsigned int gen;
unsigned int flags;
char name[SNAP_MAX_NAMELEN];
};
/* snap ioctl data for table fiddling */
struct snap_table_data {
int tblcmd_no; /* which table */
unsigned long dev;
unsigned int tblcmd_count; /* how many snaps */
struct snap tblcmd_snaps[0]; /* sorted times! */
};
/* we have just a single snapshot control device
it contains a list of all the snap_current info's
*/
#define SNAPDEV_NAME "/dev/snapconf"
#define SNAP_PSDEV_MINOR 240
#define SNAP_PSDEV_MAJOR 10
#ifdef __KERNEL__
#if 0
#include <linux/lustre_lib.h>
#else
#include "snapfs_support.h"
#endif
/* What we use to point to IDs in the obdmd data for snapshots. If we use
* obd_id (8 bytes) instead of ino_t (4 bytes), we halve the number of
* available snapshot slots (14 in 56 bytes vs. 7 in 56 bytes until we
* increase the size of OBD_OBDMDSZ).
*/
typedef ino_t snap_id;
/* maximum number of snapshots per device
must fit in "o_obdmd" area of struct obdo */
//#define OBD_OBDMDSZ 54
//#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id))
#define SNAP_MAX 50
/* if time is 0 this designates the "current" snapshot, i.e.
the head of the tree
*/
/* sysctl.c */
extern int init_snapfs_proc_sys(void);
extern void cleanup_spapfs_proc_sys(void);
extern int snap_print_entry;
extern int snap_debug_level;
extern int snap_inodes;
extern long snap_kmemory;
extern int snap_stack;
/* snap cache information: this morally equals the superblock of a
snap_current_fs. However, that superblock is the one of the "cache"
device holding the inodes, hence we store this info in the hash of
mountpoints hanging of our control device.
*/
struct snap_cache {
struct list_head cache_chain;
kdev_t cache_dev;
struct super_block *cache_sb; /* the _real_ device */
struct list_head cache_clone_list;
int cache_snap_tableno;
struct filter_fs *cache_filter;
char cache_type;
char cache_show_dotsnap;
};
/* this is the snap_clone_info for the sb of snap_clone_fs */
struct snap_clone_info {
struct snap_cache *clone_cache;
struct list_head clone_list_entry;
int clone_index;
};
/*
* it is important that things like inode, super and file operations
* for intermezzo are not defined statically. If methods are NULL
* the VFS takes special action based on that. Given that different
* cache types have NULL ops at different slots, we must install opeation
* talbes for InterMezzo with NULL's in the same spot
*/
struct filter_ops {
/* operations on the file store */
struct super_operations filter_sops;
struct inode_operations filter_dir_iops;
struct inode_operations filter_file_iops;
struct inode_operations filter_sym_iops;
struct file_operations filter_dir_fops;
struct file_operations filter_file_fops;
struct file_operations filter_sym_fops;
struct address_space_operations filter_file_aops;
struct dentry_operations filter_dentry_ops;
};
struct cache_ops {
/* operations on the file store */
struct super_operations *cache_sops;
struct inode_operations *cache_dir_iops;
struct inode_operations *cache_file_iops;
struct inode_operations *cache_sym_iops;
struct file_operations *cache_dir_fops;
struct file_operations *cache_file_fops;
struct file_operations *cache_sym_fops;
struct address_space_operations *cache_file_aops;
struct dentry_operations *cache_dentry_ops;
};
#define SNAP_OP_NOOP 0
#define SNAP_OP_CREATE 1
#define SNAP_OP_MKDIR 2
#define SNAP_OP_UNLINK 3
#define SNAP_OP_RMDIR 4
#define SNAP_OP_CLOSE 5
#define SNAP_OP_SYMLINK 6
#define SNAP_OP_RENAME 7
#define SNAP_OP_SETATTR 8
#define SNAP_OP_LINK 9
#define SNAP_OP_OPEN 10
#define SNAP_OP_MKNOD 11
#define SNAP_OP_WRITE 12
#define SNAP_OP_RELEASE 13
struct journal_ops {
void *(*trans_start)(struct inode *, int op);
void (*trans_commit)(void *handle);
};
struct snap_control_device {
struct list_head snap_dev_list;
};
#define D_MAXLEN 1024
#define SNAPSHOT_UNUSED_FLAG (1 << 0)
#define SNAPSHOT_GOOD_FLAG (1 << 1)
#define SNAPSHOT_DELETING_FLAG (1 << 2)
#define SNAPSHOT_BAD_FLAG (1 << 3)
struct snap_disk {
__u64 time;
__u32 gen;
__u32 index;
__u32 flags;
char name[SNAP_MAX_NAMELEN];
};
/* snap ioctl data for attach: current always in first slot of this array */
struct snap_obd_data {
int snap_dev; /* which device contains the data */
unsigned int snap_index;/* which snapshot is ours */
unsigned int snap_table;/* which table do we use */
};
struct snap_table {
struct semaphore tbl_sema;
spinlock_t tbl_lock;
unsigned int tbl_count; /* how many snapshots exist in this table*/
unsigned int generation;
struct snap snap_items[SNAP_MAX];
};
#define DISK_SNAPTABLE_ATTR "Snaptable"
#define DISK_SNAP_TABLE_MAGIC 0x1976
struct snap_disk_table {
unsigned int magic;
unsigned int count;
unsigned int generation;
struct snap_disk snap_items[SNAP_MAX];
};
struct snap_iterdata {
kdev_t dev; /* snap current device number */
int index;
int tableno;
time_t time;
};
struct snap_ioc_data {
kdev_t dev;
char name[SNAP_MAX_NAMELEN];
};
struct snap_ino_list_data{
kdev_t dev;
ino_t ino;
};
struct filter_inode_info {
int flags; /* the flags indicated inode type */
int generation; /*the inode generation*/
};
/* dotsnap.c */
extern int currentfs_is_under_dotsnap(struct dentry *de);
/* cache.c */
inline void snap_free_cache(struct snap_cache *cache);
struct snap_cache *snap_find_cache(kdev_t dev);
/* snaptable.c */
extern struct snap_table snap_tables[SNAP_MAX_TABLES];
void snap_last(struct snap_cache *info, struct snap *snap);
int snap_index2slot(struct snap_table *snap_table, int snap_index);
int snap_needs_cow(struct inode *);
int snapfs_read_snaptable(struct snap_cache *cache, int tableno);
/* snap.c */
int snap_is_redirector(struct inode *inode);
struct inode *snap_redirect(struct inode *inode, struct super_block *clone_sb);
int snap_do_cow(struct inode *inode, ino_t parent_ino, int del);
int snap_iterate(struct super_block *sb,
int (*repeat)(struct inode *inode, void *priv),
struct inode **start, void *priv, int flag);
struct inode *snap_get_indirect(struct inode *pri, int *table, int slot);
int snap_destroy_indirect(struct inode *pri, int index, struct inode *next_ind);
int snap_restore_indirect(struct inode *pri, int index );
int snap_migrate_data(struct inode *dst, struct inode *src);
int snap_set_indirect(struct inode *pri, ino_t ind_ino,
int index, ino_t parent_ino);
/* inode.c */
extern struct super_operations currentfs_super_ops;
void cleanup_filter_info_cache(void);
int init_filter_info_cache(void);
void init_filter_data(struct inode *inode, struct snapshot_operations *snapops,
int flag);
/* dir.c */
extern struct inode_operations currentfs_dir_iops;
extern struct file_operations currentfs_dir_fops;
extern struct address_space_operations currentfs_file_aops;
/* file.c */
extern struct inode_operations currentfs_file_iops;
extern struct file_operations currentfs_file_fops;
/* symlink.c */
extern struct inode_operations currentfs_sym_iops;
extern struct file_operations currentfs_sym_fops;
extern struct dentry_operations currentfs_dentry_ops;
#define FILTER_DID_SUPER_OPS 0x1
#define FILTER_DID_INODE_OPS 0x2
#define FILTER_DID_FILE_OPS 0x4
#define FILTER_DID_DENTRY_OPS 0x8
#define FILTER_DID_DEV_OPS 0x10
#define FILTER_DID_SYMLINK_OPS 0x20
#define FILTER_DID_DIR_OPS 0x40
#define FILTER_DID_SNAPSHOT_OPS 0x80
#define FILTER_DID_JOURNAL_OPS 0x100
struct filter_fs {
int o_flags;
struct filter_ops o_fops;
struct cache_ops o_caops;
struct journal_ops *o_trops;
struct snapshot_operations *o_snapops;
};
#define FILTER_FS_TYPES 3
#define FILTER_FS_EXT2 0
#define FILTER_FS_EXT3 1
#define FILTER_FS_REISER 2
extern struct filter_fs filter_oppar[FILTER_FS_TYPES];
struct filter_fs *filter_get_filter_fs(const char *cache_type);
inline struct super_operations *filter_c2usops(struct filter_fs *cache);
inline struct inode_operations *filter_c2ufiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2udiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2usiops(struct filter_fs *cache);
inline struct super_operations *filter_c2csops(struct filter_fs *cache);
inline struct inode_operations *filter_c2cfiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2cdiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2csiops(struct filter_fs *cache);
inline struct file_operations *filter_c2cffops(struct filter_fs *cache);
inline struct file_operations *filter_c2cdfops(struct filter_fs *cache);
inline struct file_operations *filter_c2csfops(struct filter_fs *cache);
inline struct dentry_operations *filter_c2cdops(struct filter_fs *cache);
inline struct dentry_operations *filter_c2udops(struct filter_fs *cache);
inline struct address_space_operations *filter_c2cfaops(struct filter_fs *cache);
/* for snapfs */
inline struct snapshot_operations *filter_c2csnapops(struct filter_fs *cache);
void filter_setup_file_ops(struct filter_fs *cache,
struct inode *inode,
struct inode_operations *filter_iops,
struct file_operations *filter_fops,
struct address_space_operations *filter_aops);
void filter_setup_dir_ops(struct filter_fs *cache,
struct inode *inode,
struct inode_operations *filter_iops,
struct file_operations *filter_fops);
void filter_setup_symlink_ops(struct filter_fs *cache,
struct inode *inode,
struct inode_operations *filter_iops,
struct file_operations *filter_fops);
void filter_setup_dentry_ops(struct filter_fs *cache,
struct dentry_operations *cache_dop,
struct dentry_operations *filter_dop);
void filter_setup_super_ops(struct filter_fs *cache,
struct super_operations *cache_sops,
struct super_operations *filter_sops);
/* for snapfs */
void filter_setup_snapshot_ops(struct filter_fs *cache,
struct snapshot_operations *cache_snapops);
void filter_setup_journal_ops(struct filter_fs *cache,
struct journal_ops *cache_journal_ops);
static inline void* snap_trans_start(struct snap_cache *cache,
struct inode *inode, int op)
{
if( cache->cache_filter->o_trops )
return cache->cache_filter->o_trops->trans_start(inode, op);
return NULL;
};
static inline void snap_trans_commit(struct snap_cache *cache, void *handle)
{
if( cache->cache_filter->o_trops )
cache->cache_filter->o_trops->trans_commit(handle);
};
static inline void snapfs_cpy_attrs(struct inode *dst, struct inode *src)
{
dst->i_mtime = src->i_mtime;
dst->i_ctime = src->i_ctime;
dst->i_atime = src->i_atime;
dst->i_size = src->i_size;
dst->i_blksize = src->i_blksize;
dst->i_blocks = src->i_blocks;
dst->i_generation = src->i_generation;
dst->i_uid = src->i_uid;
dst->i_gid = src->i_gid;
dst->i_mode = src->i_mode;
}
#ifdef SNAP_DEBUG
extern unsigned int snap_debug_failcode;
#ifdef CONFIG_LOOP_DISCARD
#define BLKDEV_FAIL(dev,fail) loop_discard_io(dev,fail)
#else
#define BLKDEV_FAIL(dev,fail) set_device_ro(dev, 1)
#endif
static inline void snap_debug_device_fail(dev_t dev, unsigned short opcode, unsigned short pos)
{
unsigned int failcode = (opcode<<16) | pos;
if( failcode == snap_debug_failcode && !is_read_only(dev)){
printk(KERN_EMERG "set block device %s into fail mode\n", bdevname(dev));
BLKDEV_FAIL(dev, 1);
}
}
#else
#define snap_debug_device_fail(args...) do{}while(0)
#endif
extern int snap_debug_level;
extern int snap_print_entry;
#endif /*_KERNEL_*/
#endif /* __LINUX_SNAPFS_H */
/*Got these defination from lustre*/
#define S_SNAP (1 << 0)
#define D_TRACE (1 << 0) /* ENTRY/EXIT markers */
#define D_INODE (1 << 1)
#define D_SUPER (1 << 2)
#define D_EXT2 (1 << 3) /* anything from ext2_debug */
#define D_MALLOC (1 << 4) /* print malloc, free information */
#define D_CACHE (1 << 5) /* cache-related items */
#define D_INFO (1 << 6) /* general information */
#define D_IOCTL (1 << 7) /* ioctl related information */
#define D_BLOCKS (1 << 8) /* ext2 block allocation */
#define D_NET (1 << 9) /* network communications */
#define D_WARNING (1 << 10) /* CWARN(...) == CDEBUG (D_WARNING, ...) */
#define D_BUFFS (1 << 11)
#define D_OTHER (1 << 12)
#define D_DENTRY (1 << 13)
#define D_PAGE (1 << 15) /* bulk page handling */
#define D_DLMTRACE (1 << 16)
#define D_ERROR (1 << 17) /* CERROR(...) == CDEBUG (D_ERROR, ...) */
#define D_EMERG (1 << 18) /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
#define D_HA (1 << 19) /* recovery and failover */
#define D_RPCTRACE (1 << 20) /* for distributed debugging */
#define D_VFSTRACE (1 << 21)
#define D_SNAP (1 << 22)
#ifdef __KERNEL__
# include <linux/sched.h> /* THREAD_SIZE */
#else
# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */
# define THREAD_SIZE 8192
# endif
#endif
# include <linux/vmalloc.h>
# define snap_debug_msg(mask, file, fn, line, stack, format, a...) \
printk("%02x (@%lu %s:%s,l. %d %d %lu): " format, \
(mask), (long)time(0), file, fn, line, \
getpid() , stack, ## a);
#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
#ifdef __KERNEL__
# ifdef __ia64__
# define CDEBUG_STACK (THREAD_SIZE - \
((unsigned long)__builtin_dwarf_cfa() & \
(THREAD_SIZE - 1)))
# else
# define CDEBUG_STACK (THREAD_SIZE - \
((unsigned long)__builtin_frame_address(0) & \
(THREAD_SIZE - 1)))
# endif
#define CHECK_STACK(stack) \
do { \
if ((stack) > 3*THREAD_SIZE/4 && (stack) > snap_stack) { \
printk( "maximum lustre stack %u\n", \
snap_stack = (stack)); \
} \
} while (0)
#else /* __KERNEL__ */
#define CHECK_STACK(stack) do { } while(0)
#define CDEBUG_STACK (0L)
#endif /* __KERNEL__ */
#if 1
#define CDEBUG(mask, format, a...) \
do { \
CHECK_STACK(CDEBUG_STACK); \
if (!(mask) || ((mask) & (D_ERROR | D_EMERG | D_WARNING)) || \
(snap_debug_level & (mask))) \
printk(format, ## a); \
} while (0)
#define CWARN(format, a...) CDEBUG(D_WARNING, format, ## a)
#define CERROR(format, a...) CDEBUG(D_ERROR, format, ## a)
#define CEMERG(format, a...) CDEBUG(D_EMERG, format, ## a)
#define GOTO(label, rc) \
do { \
long GOTO__ret = (long)(rc); \
CDEBUG(D_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n", \
#label, (unsigned long)GOTO__ret, (signed long)GOTO__ret,\
(signed long)GOTO__ret); \
goto label; \
} while (0)
#define RETURN(rc) \
do { \
typeof(rc) RETURN__ret = (rc); \
CDEBUG(D_TRACE, "Process %d leaving %s (rc=%lu : %ld : %lx)\n", \
current->pid, __FUNCTION__, (long)RETURN__ret, \
(long)RETURN__ret, (long)RETURN__ret); \
return RETURN__ret; \
} while (0)
#define ENTRY \
do { \
CDEBUG(D_TRACE, "Process %d enter %s\n", \
current->pid, __FUNCTION__); \
} while (0)
#define EXIT \
do { \
CDEBUG(D_TRACE, "Process %d leaving %s \n", \
current->pid, __FUNCTION__); \
} while(0)
#else
#define CDEBUG(mask, format, a...) do { } while (0)
#define CWARN(format, a...) do { } while (0)
#define CERROR(format, a...) printk("<3>" format, ## a)
#define CEMERG(format, a...) printk("<0>" format, ## a)
#define GOTO(label, rc) do { (void)(rc); goto label; } while (0)
#define RETURN(rc) return (rc)
#define ENTRY do { } while (0)
#define EXIT do { } while (0)
#endif
#define SNAP_ALLOC(ptr, size) \
do { \
if (size <= 4096) { \
ptr = kmalloc((unsigned long) size, GFP_KERNEL); \
CDEBUG(D_MALLOC, "Proc %d %s:%d kmalloced: %d at %x.\n",\
current->pid, __FUNCTION__, __LINE__, \
(int) size, (int) ptr); \
} else { \
ptr = vmalloc((unsigned long) size); \
CDEBUG(D_MALLOC, "Proc %d %s:%d vmalloced: %d at %x.\n",\
current->pid, __FUNCTION__, __LINE__, \
(int) size, (int) ptr); \
} \
if (ptr == 0) { \
printk("kernel malloc returns 0 at %s:%d\n", \
__FILE__, __LINE__); \
} else { \
memset(ptr, 0, size); \
snap_kmemory += size; \
} \
} while (0)
#define SNAP_FREE(ptr,size) \
do { \
snap_kmemory -= size; \
if (size <= 4096) { \
CDEBUG(D_MALLOC, "Proc %d %s:%d kfreed: %d at %x.\n", \
current->pid, __FUNCTION__, __LINE__, \
(int) size, (int) ptr); \
kfree((ptr)); \
} else { \
CDEBUG(D_MALLOC, "Proc %d %s:%d vfreed: %d at %x.\n", \
current->pid, __FUNCTION__, __LINE__, \
(int) size, (int) ptr); \
vfree((ptr)); \
} \
} while (0)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment