From ff5a3e46380fdcb9eced220b1d82d0291e347340 Mon Sep 17 00:00:00 2001
From: wangdi <wangdi>
Date: Sun, 4 Jan 2004 07:28:26 +0000
Subject: [PATCH] add snapfs_internal.h snapfs_support.h Makefile.am

---
 lustre/snapfs/Makefile.am       |  19 ++
 lustre/snapfs/snapfs_internal.h | 410 ++++++++++++++++++++++++++++++++
 lustre/snapfs/snapfs_support.h  | 156 ++++++++++++
 3 files changed, 585 insertions(+)
 create mode 100644 lustre/snapfs/Makefile.am
 create mode 100644 lustre/snapfs/snapfs_internal.h
 create mode 100644 lustre/snapfs/snapfs_support.h

diff --git a/lustre/snapfs/Makefile.am b/lustre/snapfs/Makefile.am
new file mode 100644
index 0000000000..15d50ab37b
--- /dev/null
+++ b/lustre/snapfs/Makefile.am
@@ -0,0 +1,19 @@
+# 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
diff --git a/lustre/snapfs/snapfs_internal.h b/lustre/snapfs/snapfs_internal.h
new file mode 100644
index 0000000000..ce43dbfbc0
--- /dev/null
+++ b/lustre/snapfs/snapfs_internal.h
@@ -0,0 +1,410 @@
+#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 */
diff --git a/lustre/snapfs/snapfs_support.h b/lustre/snapfs/snapfs_support.h
new file mode 100644
index 0000000000..7da4746f7f
--- /dev/null
+++ b/lustre/snapfs/snapfs_support.h
@@ -0,0 +1,156 @@
+/*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)
+
-- 
GitLab