Whamcloud - gitweb
1)reorganize the smfs hook ops to make smfs walk a list of hooks ops in hook macro
authorwangdi <wangdi>
Mon, 2 Aug 2004 14:58:13 +0000 (14:58 +0000)
committerwangdi <wangdi>
Mon, 2 Aug 2004 14:58:13 +0000 (14:58 +0000)
2)remove clonefs in llite, we do not need them now
3)add snap_dot_info in snap_super_info

12 files changed:
lustre/include/linux/lustre_smfs.h
lustre/include/linux/lustre_snap.h
lustre/llite/llite_lib.c
lustre/smfs/cache.c
lustre/smfs/cache_space.c
lustre/smfs/dir.c
lustre/smfs/file.c
lustre/smfs/journal.c
lustre/smfs/kml.c
lustre/smfs/smfs_cow.c
lustre/smfs/smfs_internal.h
lustre/smfs/super.c

index 7bb62cb..8ef548e 100644 (file)
@@ -70,7 +70,14 @@ struct mds_kml_pack_info {
         int mpi_size[4];
         int mpi_total_size;
 };
         int mpi_size[4];
         int mpi_total_size;
 };
-
+typedef int (*smfs_hook_func)(struct inode *inode, struct dentry *dentry,
+                             void *data1, void *data2, int op, void *handle);
+struct smfs_hook_ops {
+        struct list_head smh_list;
+        char *           smh_name;
+        smfs_hook_func   smh_post_op;
+        smfs_hook_func   smh_pre_op;
+};
 struct smfs_super_info {
         struct super_block       *smsi_sb;
         struct vfsmount          *smsi_mnt;         /* mount the cache kern */
 struct smfs_super_info {
         struct super_block       *smsi_sb;
         struct vfsmount          *smsi_mnt;         /* mount the cache kern */
@@ -85,13 +92,15 @@ struct smfs_super_info {
         char                     *smsi_cache_ftype; /* cache file system type */
         char                     *smsi_ftype;       /* file system type */
        struct obd_export        *smsi_exp;         /* file system obd exp */
         char                     *smsi_cache_ftype; /* cache file system type */
         char                     *smsi_ftype;       /* file system type */
        struct obd_export        *smsi_exp;         /* file system obd exp */
-       struct snap_info         *smsi_snap_info;    /* snap table cow */
+       struct snap_info         *smsi_snap_info;   /* snap table cow */
         smfs_pack_rec_func      smsi_pack_rec[PACK_MAX]; /* sm_pack_rec type ops */
         smfs_pack_rec_func      smsi_pack_rec[PACK_MAX]; /* sm_pack_rec type ops */
-        __u32                    smsi_flags;       /* flags */
+        __u32                    smsi_flags;        /* flags */
         __u32                    smsi_ops_check;
         __u32                    smsi_ops_check;
+        struct list_head         smsi_hook_list;
 };
 
 };
 
-#define SMFS_FILE_TYPE "smfs"
+
+#define SMFS_FILE_TYPE         "smfs"
 #define SMFS_FILE_MAGIC        0x19760218
 
 struct smfs_file_info {
 #define SMFS_FILE_MAGIC        0x19760218
 
 struct smfs_file_info {
index 6421423..c253979 100644 (file)
@@ -165,6 +165,12 @@ struct snap_table {
        struct  snap    sntbl_items[0];
 };
 
        struct  snap    sntbl_items[0];
 };
 
+struct snap_dot_info {
+         char *dot_name;
+         int   dot_name_len;
+         int   dot_snap_enable;
+};
+
 struct snap_info {
         struct fsfilt_operations *snap_fsfilt;  
         struct fsfilt_operations *snap_cache_fsfilt; 
 struct snap_info {
         struct fsfilt_operations *snap_fsfilt;  
         struct fsfilt_operations *snap_cache_fsfilt; 
@@ -173,13 +179,9 @@ struct snap_info {
        spinlock_t               sntbl_lock;
         struct snap_table        *sntbl;
         struct dentry            *sn_cowed_dentry;
        spinlock_t               sntbl_lock;
         struct snap_table        *sntbl;
         struct dentry            *sn_cowed_dentry;
-};
-#define SM_CLONE_FS        0x01
-#define SET_CLONE_INDEX(clone_info, index)            \
-                       (((struct clonefs_info *)clone_info)->clone_index = index)
-#define SET_CLONE_FLAGS(clone_info, flags)            \
-                       (((struct clonefs_info *)clone_info)->clone_flags = flags)
+        struct snap_dot_info     *sn_dot_info;
 
 
+};
 
 extern int smfs_add_snap_item(struct super_block *sb, char *name);
 extern int smfs_start_cow(struct super_block *sb);
 
 extern int smfs_add_snap_item(struct super_block *sb, char *name);
 extern int smfs_start_cow(struct super_block *sb);
index d8ae8e8..2cab4c8 100644 (file)
@@ -106,74 +106,6 @@ int lustre_init_ea_size(struct ll_sb_info *sbi)
 
         RETURN(rc);
 }
 
         RETURN(rc);
 }
-#if CONFIG_SNAPFS
-int lustre_set_clone_info(struct super_block *sb, int clone_index)
-{
-        struct ll_sb_info *sbi = ll_s2sbi(sb);
-        
-        ENTRY;
-
-        CDEBUG(D_INFO, "set clone index %d\n", clone_index);
-        if (!clone_index)
-                RETURN(0); 
-        
-        if (sbi->ll_mdc_exp) {
-                struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp);
-                struct client_obd *cl_obd = &obd->u.cli;
-
-                OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
-                if (!cl_obd->cl_clone_info) 
-                        RETURN(-ENOMEM);
-                SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index);
-                SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS);
-                cl_obd->cl_clone_info->cl_clone_info->clone_magic = 
-                                                  cpu_to_le32(CLONE_INFO_MAGI);
-        }
-        
-        if (sbi->ll_osc_exp) {
-                struct obd_device *obd = class_exp2obd(sbi->ll_osc_exp);
-                struct client_obd *cl_obd = &obd->u.cli;
-
-                OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
-                if (!cl_obd->cl_clone_info) 
-                        RETURN(-ENOMEM);
-                SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index);
-                SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS);
-                cl_obd->cl_clone_info->cl_clone_info->clone_magic = 
-                                                  cpu_to_le32(CLONE_INFO_MAGI);
-        }
-        RETURN(0); 
-}
-
-int lustre_cleanup_clone_info(struct super_block *sb)
-{
-        struct ll_sb_info *sbi = ll_s2sbi(sb);
-       
-        ENTRY; 
-
-        if (sbi->ll_mdc_exp) {
-                struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp);
-                struct client_obd *cl_obd = &obd->u.cli;
-
-                if (!cl_obd->cl_clone_info) 
-                        RETURN(0); 
-                CDEBUG(D_INFO, "clean clone info %p\n", cl_obd->cl_clone_info);
-                OBD_FREE(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
-        }
-        
-        if (sbi->ll_osc_exp) {
-                struct obd_device *obd = class_exp2obd(sbi->ll_osc_exp);
-                struct client_obd *cl_obd = &obd->u.cli;
-
-                if (!cl_obd->cl_clone_info) 
-                        RETURN(0); 
-                CDEBUG(D_INFO, "clean clone info %p\n", cl_obd->cl_clone_info);
-                OBD_FREE(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
-        }
-        RETURN(0); 
-}
-#endif
-
 
 int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc)
 {
 
 int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc)
 {
@@ -471,16 +403,6 @@ int ll_fill_super(struct super_block *sb, void *data, int silent)
         }
 
         err = lustre_common_fill_super(sb, mdc, osc);
         }
 
         err = lustre_common_fill_super(sb, mdc, osc);
-#if CONFIG_SNAPFS        
-        if (clone_opts) {
-                int clone_index = 0;
-                char *endp;
-
-                /*set clone info to the super block*/
-                clone_index = simple_strtoul(clone_opts, &endp, 0);
-                err = lustre_set_clone_info(sb, clone_index);                
-        }
-#endif         
 out:
         if (err)
                 lustre_free_sbi(sb);
 out:
         if (err)
                 lustre_free_sbi(sb);
@@ -712,15 +634,6 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
 
         if (err)
                 GOTO(out_free, err);
 
         if (err)
                 GOTO(out_free, err);
-
-#if CONFIG_SNAPFS
-        if (lmd->lmd_clone_index) {
-                err = lustre_set_clone_info(sb, lmd->lmd_clone_index);                
-        }
-        
-        if (err)
-                GOTO(out_free, err);
-#endif
         
 out_dev:
         if (mdc)
         
 out_dev:
         if (mdc)
@@ -754,9 +667,6 @@ out_free:
                 }
                 OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
         }
                 }
                 OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
         }
-#if CONFIG_SNAPFS
-        lustre_cleanup_clone_info(sb);
-#endif
         lustre_free_sbi(sb);
 
         goto out_dev;
         lustre_free_sbi(sb);
 
         goto out_dev;
@@ -804,10 +714,6 @@ void lustre_put_super(struct super_block *sb)
                 force_umount = obd->obd_no_recov;
         obd = NULL;
 
                 force_umount = obd->obd_no_recov;
         obd = NULL;
 
-#if CONFIG_SNAPFS
-        lustre_cleanup_clone_info(sb);
-#endif
-
         lustre_common_put_super(sb);
         if (sbi->ll_lmd != NULL) {
                 char * cln_prof;
         lustre_common_put_super(sb);
         if (sbi->ll_lmd != NULL) {
                 char * cln_prof;
index 17b40dd..717e3af 100644 (file)
@@ -322,3 +322,78 @@ void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb)
         sb->s_op = cache_sops(smb);
         return;
 }
         sb->s_op = cache_sops(smb);
         return;
 }
+struct smfs_hook_ops *smfs_alloc_hook_ops(char *name, smfs_hook_func pre_hook, 
+                                       smfs_hook_func post_hook)
+{
+        struct smfs_hook_ops *smfs_hops = NULL;
+        
+        ENTRY;
+        OBD_ALLOC(smfs_hops, sizeof(struct smfs_hook_ops));
+
+        if (!smfs_hops)
+                RETURN(NULL);
+        OBD_ALLOC(smfs_hops->smh_name, strlen(name) + 1);
+        
+        if (!smfs_hops->smh_name) { 
+                OBD_FREE(smfs_hops, sizeof(struct smfs_hook_ops));
+                RETURN(NULL);
+        }
+        
+        memcpy(smfs_hops->smh_name, name, strlen(name));  
+       
+        smfs_hops->smh_post_op = post_hook;  
+        smfs_hops->smh_pre_op = pre_hook;  
+        
+        RETURN(smfs_hops); 
+}
+
+void smfs_free_hook_ops(struct smfs_hook_ops *hops)
+{
+        if (hops) {
+                if (hops->smh_name){
+                        OBD_FREE(hops->smh_name, strlen(hops->smh_name) + 1);
+                }
+                OBD_FREE(hops, sizeof(struct smfs_hook_ops));
+        }
+}
+
+int smfs_register_hook_ops(struct super_block *sb, 
+                           struct smfs_hook_ops *smh_ops)
+{
+        struct smfs_super_info *smb = S2SMI(sb);
+        struct list_head *hlist = &smb->smsi_hook_list;
+        struct list_head *p;
+        ENTRY;
+        list_for_each(p, hlist) {
+                struct smfs_hook_ops *found;               
+                found = list_entry(p, struct smfs_hook_ops, smh_list);
+                if (!strcmp(found->smh_name, smh_ops->smh_name)) {
+                        CWARN("hook ops %s list  reregister\n", smh_ops->smh_name);
+                        RETURN(0);
+                }
+        }
+       list_add(&smh_ops->smh_list, hlist);
+        RETURN(0);
+} 
+struct smfs_hook_ops  *smfs_unregister_hook_ops(struct super_block *sb, 
+                                                char *name)
+{
+        struct smfs_super_info *smb = S2SMI(sb);
+        struct list_head *hlist = &smb->smsi_hook_list;
+        struct list_head *p;
+        ENTRY;      
+        list_for_each(p, hlist) {
+               struct smfs_hook_ops *found;
+
+                found = list_entry(p, typeof(*found), smh_list);
+                if (!memcmp(found->smh_name, name, strlen(name))) {
+                        list_del(p);
+                        RETURN(found);
+                }
+        } 
+        RETURN(NULL);
+}
+                        
index 45bcf40..3f88fc7 100644 (file)
@@ -43,16 +43,69 @@ struct cache_purge_param {
 static struct cache_purge_queue smfs_cpq;
 static struct cache_purge_queue *cpq = &smfs_cpq;
 
 static struct cache_purge_queue smfs_cpq;
 static struct cache_purge_queue *cpq = &smfs_cpq;
 
+#define CACHE_HOOK "cache_hook"
+int cache_space_pre_hook(struct inode *inode, struct dentry *dentry,
+                         void *data1, void *data2, int op, void *handle)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (smfs_cache_hook(inode)) {                                          
+               if (!handle) {                                                  
+                        handle = smfs_trans_start(inode, KML_CACHE_NOOP, NULL);   
+                        if (IS_ERR(handle)) {                                   
+                                RETURN(PTR_ERR(handle));
+                        }                                                       
+                }                                                               
+                cache_space_pre(inode, op);                                       
+        }                                                                       
+        RETURN(rc); 
+}
+
+int cache_space_post_hook(struct inode *inode, struct dentry *dentry,
+                         void *data1, void *data2, int op, void *handle)
+{
+        int rc = 0;
+        ENTRY;
+        if (smfs_cache_hook(inode)) {      
+                struct inode *new_inode = (struct inode*)data1;
+                struct dentry *new_dentry = (struct dentry*)data2;                    
+                LASSERT(handle != NULL);                                
+                rc = cache_space_post(op, handle, inode, dentry, new_inode, 
+                                      new_dentry);
+        }
+        RETURN(rc);                                                               
+}
+
 int cache_space_hook_init(struct super_block *sb)
 {
         struct smfs_super_info  *smfs_info = S2SMI(sb);
 int cache_space_hook_init(struct super_block *sb)
 {
         struct smfs_super_info  *smfs_info = S2SMI(sb);
+        struct smfs_hook_ops    *cache_hops;
+        int    rc = 0;
+        ENTRY;
 
 
+        cache_hops = smfs_alloc_hook_ops(CACHE_HOOK, cache_space_pre_hook, 
+                                         cache_space_post_hook);
+        if (!cache_hops) {
+                RETURN(-ENOMEM);
+        }
+        rc = smfs_register_hook_ops(sb, cache_hops);      
+        if (rc) {
+                smfs_free_hook_ops(cache_hops);
+                RETURN(rc);
+        }
         SMFS_SET_CACHE_HOOK(smfs_info);
         SMFS_SET_CACHE_HOOK(smfs_info);
-        return 0;
+
+        RETURN(0);
 }
 }
+
 int cache_space_hook_exit(struct super_block *sb)
 {
         struct smfs_super_info  *smfs_info = S2SMI(sb);
 int cache_space_hook_exit(struct super_block *sb)
 {
         struct smfs_super_info  *smfs_info = S2SMI(sb);
+        struct smfs_hook_ops *cache_hops; 
+
+        cache_hops = smfs_unregister_hook_ops(sb, CACHE_HOOK);
+        smfs_free_hook_ops(cache_hops);
 
         SMFS_CLEAN_CACHE_HOOK(smfs_info);
         return 0;
 
         SMFS_CLEAN_CACHE_HOOK(smfs_info);
         return 0;
@@ -619,28 +672,32 @@ static int cache_space_hook_rename(void *handle, struct inode *old_dir,
 typedef int (*cache_hook_op)(void *handle, struct inode *old_dir,
                              struct dentry *old_dentry, struct inode *new_dir,
                              struct dentry *new_dentry);
 typedef int (*cache_hook_op)(void *handle, struct inode *old_dir,
                              struct dentry *old_dentry, struct inode *new_dir,
                              struct dentry *new_dentry);
-static  cache_hook_op cache_space_hook_ops[CACHE_HOOK_MAX + 1] = {
-        [CACHE_HOOK_CREATE]     cache_space_hook_create,
-        [CACHE_HOOK_LOOKUP]     cache_space_hook_lookup,
-        [CACHE_HOOK_LINK]       cache_space_hook_link,
-        [CACHE_HOOK_UNLINK]     cache_space_hook_unlink,
-        [CACHE_HOOK_SYMLINK]    cache_space_hook_create,
-        [CACHE_HOOK_MKDIR]      cache_space_hook_mkdir,
-        [CACHE_HOOK_RMDIR]      cache_space_hook_rmdir,
-        [CACHE_HOOK_MKNOD]      cache_space_hook_create,
-        [CACHE_HOOK_RENAME]     cache_space_hook_rename,
+
+static  cache_hook_op cache_space_hook_ops[HOOK_MAX + 1] = {
+        [HOOK_CREATE]     cache_space_hook_create,
+        [HOOK_LOOKUP]     cache_space_hook_lookup,
+        [HOOK_LINK]       cache_space_hook_link,
+        [HOOK_UNLINK]     cache_space_hook_unlink,
+        [HOOK_SYMLINK]    cache_space_hook_create,
+        [HOOK_MKDIR]      cache_space_hook_mkdir,
+        [HOOK_RMDIR]      cache_space_hook_rmdir,
+        [HOOK_MKNOD]      cache_space_hook_create,
+        [HOOK_RENAME]     cache_space_hook_rename,
+        [HOOK_SETATTR]    NULL,
+        [HOOK_WRITE]      NULL,
 };
 
 int cache_space_post(int op, void *handle, struct inode *old_dir,
                struct dentry *old_dentry, struct inode *new_dir,
                struct dentry *new_dentry)
 {
 };
 
 int cache_space_post(int op, void *handle, struct inode *old_dir,
                struct dentry *old_dentry, struct inode *new_dir,
                struct dentry *new_dentry)
 {
-        int rc;
+        int rc = 0;
         ENTRY;
 
         ENTRY;
 
-        LASSERT(op <= CACHE_HOOK_MAX && cache_space_hook_ops[op] != NULL);
+        LASSERT(op <= HOOK_MAX + 1);
 
 
-        rc = cache_space_hook_ops[op](handle, old_dir, old_dentry,
-                                      new_dir, new_dentry);
+        if (cache_space_hook_ops[op]) 
+                rc = cache_space_hook_ops[op](handle, old_dir, old_dentry,
+                                              new_dir, new_dentry);
         RETURN(rc);
 }
         RETURN(rc);
 }
index ccb130b..0c07e7c 100644 (file)
@@ -65,19 +65,16 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
         handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
         if (IS_ERR(handle))
                        RETURN(-ENOSPC);
         handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
         if (IS_ERR(handle))
                        RETURN(-ENOSPC);
-
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_CREATE, handle, dir, rc);
-
+        
+        lock_kernel();
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle, PRE_HOOK, rc, 
+                  exit); 
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
-        lock_kernel();
         if (!cache_dentry || !cache_parent)
                 GOTO(exit, rc = -ENOMEM);
         if (!cache_dentry || !cache_parent)
                 GOTO(exit, rc = -ENOMEM);
-
-
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, REINT_CREATE, "create", rc, exit);
-        
+       
         pre_smfs_inode(dir, cache_dir);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         if (cache_dir && cache_dir->i_op->create)
         pre_smfs_inode(dir, cache_dir);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         if (cache_dir && cache_dir->i_op->create)
@@ -99,13 +96,8 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
         d_instantiate(dentry, inode);
         sm_set_inode_ops(cache_dentry->d_inode, inode);
         post_smfs_inode(dir, cache_dir);
         d_instantiate(dentry, inode);
         sm_set_inode_ops(cache_dentry->d_inode, inode);
         post_smfs_inode(dir, cache_dir);
-
-        /*Do KML post hook*/
-
-        SMFS_KML_POST(dir, dentry, NULL, NULL, REINT_CREATE,
-                      "create", rc, exit);
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_CREATE, handle, dir, dentry,
-                             NULL, NULL, rc, exit);
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle, POST_HOOK, rc, 
+                  exit); 
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
@@ -135,8 +127,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         if (!(cache_dir = I2CI(dir)))
                 RETURN(ERR_PTR(-ENOENT));
 
         if (!(cache_dir = I2CI(dir)))
                 RETURN(ERR_PTR(-ENOENT));
 
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_LOOKUP, handle, dir, rc2);
-        
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, PRE_HOOK, rc2, 
+                  exit); 
         if (rc2)
                 RETURN(ERR_PTR(rc2));
 
         if (rc2)
                 RETURN(ERR_PTR(rc2));
 
@@ -150,8 +142,6 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         if (!cache_dir && cache_dir->i_op->lookup)
                 GOTO(exit, rc = ERR_PTR(-ENOENT));
 
         if (!cache_dir && cache_dir->i_op->lookup)
                 GOTO(exit, rc = ERR_PTR(-ENOENT));
 
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, SNAP_LOOKUP, "lookup", rc2, exit);
-
         /* perform lookup in backing fs. */
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
         /* perform lookup in backing fs. */
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
@@ -177,8 +167,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         d_add(dentry, inode);
         rc = NULL;
 
         d_add(dentry, inode);
         rc = NULL;
 
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_LOOKUP, handle, dir, dentry,
-                             NULL, NULL, rc2, exit);
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, POST_HOOK, rc2, 
+                  exit); 
 exit:
         if (rc2)
                 rc = ERR_PTR(rc2);
 exit:
         if (rc2)
                 rc = ERR_PTR(rc2);
@@ -207,12 +197,10 @@ static int smfs_link(struct dentry * old_dentry,
         handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
         if (IS_ERR(handle))
                  RETURN(-ENOSPC);
         handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
         if (IS_ERR(handle))
                  RETURN(-ENOSPC);
-
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_LINK, handle, dir, rc);
         
         lock_kernel();
         
         lock_kernel();
-        
-        SMFS_PRE_COW(dir, old_dentry, NULL, NULL, REINT_LINK, "link", rc, exit);
+        SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle, PRE_HOOK, rc, 
+                  exit); 
         
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
         
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
@@ -239,11 +227,9 @@ static int smfs_link(struct dentry * old_dentry,
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
 
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
 
-        SMFS_KML_POST(dir, old_dentry, dentry, NULL,
-                      REINT_LINK, "link", rc, exit);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_LINK, handle,
-                             dir, old_dentry, NULL, NULL, rc, exit);
+        SMFS_HOOK(dir, old_dentry, dentry, NULL, HOOK_LINK, handle, POST_HOOK, 
+                  rc, exit); 
+        
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
@@ -271,9 +257,8 @@ static int smfs_unlink(struct inode * dir,
         if (IS_ERR(handle))
                 RETURN(-ENOSPC);
 
         if (IS_ERR(handle))
                 RETURN(-ENOSPC);
 
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_UNLINK, handle, dir, rc);
-
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, REINT_UNLINK, "unlink", rc, exit);
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc, 
+                  exit); 
         
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
         
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
@@ -289,11 +274,9 @@ static int smfs_unlink(struct inode * dir,
         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
         post_smfs_inode(dir, cache_dir);
         unlock_kernel();
         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
         post_smfs_inode(dir, cache_dir);
         unlock_kernel();
-        SMFS_KML_POST(dir, dentry, &mode, NULL, REINT_UNLINK,
-                      "unlink", rc, exit);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_UNLINK, handle, dir, dentry,
-                             NULL, NULL, rc, exit);
+        
+        SMFS_HOOK(dir, dentry, &mode, NULL, HOOK_UNLINK, handle, POST_HOOK, 
+                  rc, exit); 
 exit:
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
 exit:
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
@@ -314,23 +297,21 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
         if (!cache_dir)
                 RETURN(-ENOENT);
 
         if (!cache_dir)
                 RETURN(-ENOENT);
 
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
-
-        if (!cache_parent || !cache_dentry)
-                GOTO(exit, rc = -ENOMEM);
-
         handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
         if (IS_ERR(handle))
                 RETURN(-ENOSPC);
         handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
         if (IS_ERR(handle))
                 RETURN(-ENOSPC);
+        
+        lock_kernel();
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc, 
+                  exit); 
 
 
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_SYMLINK, handle, dir, rc);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
 
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, REINT_CREATE, "symlink", rc, 
-                     exit);
-        
+        if (!cache_parent || !cache_dentry)
+                GOTO(exit, rc = -ENOMEM);
+       
         pre_smfs_inode(dir, cache_dir);
         pre_smfs_inode(dir, cache_dir);
-        lock_kernel();
         if (cache_dir->i_op->symlink)
                 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
 
         if (cache_dir->i_op->symlink)
                 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
 
@@ -343,11 +324,9 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
                 rc = -ENOENT;
 
         tgt_len = strlen(symname) + 1;
                 rc = -ENOENT;
 
         tgt_len = strlen(symname) + 1;
-        SMFS_KML_POST(dir, dentry, (char*)symname, &tgt_len, REINT_CREATE,
-                      "symlink", rc, exit);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_SYMLINK, handle, dir, dentry,
-                             NULL, NULL, rc, exit);
+        
+        SMFS_HOOK(dir, dentry, (char *)symname, &tgt_len, HOOK_SYMLINK, handle, 
+                  POST_HOOK, rc, exit); 
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
@@ -373,14 +352,14 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
         if (IS_ERR(handle))
                 RETURN(-ENOSPC);
 
         if (IS_ERR(handle))
                 RETURN(-ENOSPC);
 
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_MKDIR, handle, dir, rc);
-
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, REINT_CREATE, "mkdir", rc, 
-                     exit);
+        lock_kernel();
+        
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc, 
+                  exit); 
+        
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
-        lock_kernel();
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -400,11 +379,8 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
 
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
 
-        SMFS_KML_POST(dir, dentry, NULL, NULL,
-                      REINT_CREATE, "mkdir", rc, exit);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_MKDIR, handle,
-                             dir, dentry, NULL, NULL, rc, exit);
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, POST_HOOK, rc,
+                  exit); 
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
@@ -431,14 +407,14 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
                 RETURN(-ENOSPC);
         }
 
                 RETURN(-ENOSPC);
         }
 
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_RMDIR, handle, dir, rc);
+        lock_kernel();
 
 
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, REINT_UNLINK, "rmdir", rc, exit);
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc, 
+                  exit); 
 
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
 
 
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
 
-        lock_kernel();
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -451,11 +427,8 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
         unlock_kernel();
         
         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
         unlock_kernel();
         
-        SMFS_KML_POST(dir, dentry, &mode, NULL,
-                      REINT_UNLINK, "rmdir", rc, exit);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_RMDIR, handle, dir, dentry,
-                             NULL, NULL, rc, exit);
+        SMFS_HOOK(dir, dentry, &mode, NULL, HOOK_RMDIR, handle, POST_HOOK, 
+                  rc, exit); 
 exit:
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
 exit:
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
@@ -486,12 +459,13 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry,
                 CERROR("smfs_do_mkdir: no space for transaction\n");
                 RETURN(-ENOSPC);
         }
                 CERROR("smfs_do_mkdir: no space for transaction\n");
                 RETURN(-ENOSPC);
         }
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_MKNOD, handle, dir, rc);
 
 
-        SMFS_PRE_COW(dir, dentry, NULL, NULL, REINT_CREATE, "mknod", rc, exit);
+        lock_kernel();
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc, 
+                  exit); 
+        
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
-        lock_kernel();
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -512,11 +486,9 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry,
         pre_smfs_inode(dir, cache_dir);
         pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
 
         pre_smfs_inode(dir, cache_dir);
         pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
 
-        SMFS_KML_POST(dir, dentry, NULL, NULL,
-                      REINT_CREATE, "mknod", rc, exit);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_MKNOD, handle, dir,
-                             dentry, NULL, NULL, rc, exit);
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, POST_HOOK, rc, 
+                  exit); 
+        
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_dentry);
@@ -552,10 +524,10 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
         }
         lock_kernel();
 
         }
         lock_kernel();
 
-        SMFS_PRE_COW(old_dir, old_dentry, new_dir, new_dentry, REINT_RENAME, 
-                     "rename", rc, exit);
-        SMFS_CACHE_HOOK_PRE(CACHE_HOOK_RENAME, handle, old_dir, rc);
-
+        
+        SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME, handle, 
+                  PRE_HOOK, rc, exit); 
+        
         cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry);
         cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
                                            old_dentry);
         cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry);
         cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
                                            old_dentry);
@@ -578,13 +550,11 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
         post_smfs_inode(old_dir, cache_old_dir);
         post_smfs_inode(new_dir, cache_new_dir);
 
         post_smfs_inode(old_dir, cache_old_dir);
         post_smfs_inode(new_dir, cache_new_dir);
 
-        SMFS_KML_POST(old_dir, old_dentry, new_dir,
-                      new_dentry, REINT_RENAME, "rename", rc, exit);
+        SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME, handle, 
+                  POST_HOOK, rc, exit); 
+        
         if (new_dentry->d_inode)
                 post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
         if (new_dentry->d_inode)
                 post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
-
-        SMFS_CACHE_HOOK_POST(CACHE_HOOK_RENAME, handle, old_dir, old_dentry,
-                             new_dir, new_dentry, rc, exit);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_old_dentry);
 exit:
         unlock_kernel();
         post_smfs_dentry(cache_old_dentry);
index d7f325e..45602dd 100644 (file)
@@ -68,9 +68,8 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
         else {
                 tmp_ppos = *ppos;
         }
         else {
                 tmp_ppos = *ppos;
         }
-
-        SMFS_PRE_COW(filp->f_dentry->d_inode, filp->f_dentry, &count, &tmp_ppos, 
-                     REINT_WRITE, "write", rc, exit);  
+        SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, &count, &tmp_ppos,
+                  HOOK_WRITE, NULL, PRE_HOOK, rc, exit);
 
         if (ppos != &(filp->f_pos)) {
                 cache_ppos = &tmp_ppos;
 
         if (ppos != &(filp->f_pos)) {
                 cache_ppos = &tmp_ppos;
@@ -86,8 +85,8 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
                                                count, cache_ppos);
         }
 
                                                count, cache_ppos);
         }
 
-        SMFS_KML_POST(filp->f_dentry->d_inode, filp->f_dentry,
-                      ppos, &count, REINT_WRITE, "write", rc, exit);
+        SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, ppos, &count,
+                  HOOK_WRITE, NULL, POST_HOOK, rc, exit);
 exit:
         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
         *ppos = *cache_ppos;
 exit:
         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
         *ppos = *cache_ppos;
@@ -434,8 +433,9 @@ int smfs_setattr(struct dentry *dentry, struct iattr *attr)
         if (cache_inode->i_op->setattr)
                 rc = cache_inode->i_op->setattr(cache_dentry, attr);
 
         if (cache_inode->i_op->setattr)
                 rc = cache_inode->i_op->setattr(cache_dentry, attr);
 
-        SMFS_KML_POST(dentry->d_inode, dentry, attr, NULL,
-                      REINT_SETATTR, "setattr", rc, exit);
+        SMFS_HOOK(dentry->d_inode, dentry, attr, NULL, HOOK_SETATTR, NULL, 
+                  POST_HOOK, rc, exit); 
+                  
 exit:
         post_smfs_inode(dentry->d_inode, cache_inode);
         post_smfs_dentry(cache_dentry);
 exit:
         post_smfs_inode(dentry->d_inode, cache_inode);
         post_smfs_dentry(cache_dentry);
index d23fcd5..ab62e7a 100644 (file)
@@ -518,19 +518,27 @@ exit:
 }
 
 typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry,
 }
 
 typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry,
-                            void *data1, void *data2);
-
-static post_kml_rec smfs_kml_post[REINT_MAX + 1] = {
-        [REINT_SETATTR] smfs_post_rec_setattr,
-        [REINT_CREATE]  smfs_post_rec_create,
-        [REINT_LINK]    smfs_post_rec_link,
-        [REINT_UNLINK]  smfs_post_rec_unlink,
-        [REINT_RENAME]  smfs_post_rec_rename,
-        [REINT_WRITE]   smfs_post_rec_write,
+                           void *data1, void *data2);
+
+static post_kml_rec smfs_kml_post[HOOK_MAX + 1] = {
+        [HOOK_CREATE]  smfs_post_rec_create,
+        [HOOK_LOOKUP]  NULL,
+        [HOOK_LINK]    smfs_post_rec_link,
+        [HOOK_UNLINK]  smfs_post_rec_unlink,
+        [HOOK_SYMLINK] smfs_post_rec_create,
+        [HOOK_MKDIR]   smfs_post_rec_create,
+        [HOOK_RMDIR]   smfs_post_rec_unlink,
+        [HOOK_MKNOD]   smfs_post_rec_create,
+        [HOOK_RENAME]  smfs_post_rec_rename,
+        [HOOK_SETATTR] smfs_post_rec_setattr,
+        [HOOK_WRITE]   smfs_post_rec_write,
 };
 
 int smfs_post_kml_rec(struct inode *dir, struct dentry *dst_dentry,
                       void *data1, void *data2, int op)
 {
 };
 
 int smfs_post_kml_rec(struct inode *dir, struct dentry *dst_dentry,
                       void *data1, void *data2, int op)
 {
-        return smfs_kml_post[op](dir, dst_dentry, data1, data2);
+        if (smfs_kml_post[op]) {
+                return smfs_kml_post[op](dir, dst_dentry, data1, data2);
+        }
+        return 0;
 }
 }
index 310e4da..8275ba2 100644 (file)
@@ -47,10 +47,23 @@ smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb)
 
         return smsi->smsi_pack_rec[index];
 }
 
         return smsi->smsi_pack_rec[index];
 }
+static int smfs_rec_post_hook(struct inode *inode, struct dentry *dentry,
+                              void *data1, void *data2, int op, void *handle)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (smfs_do_rec(inode))                                  
+                rc = smfs_post_kml_rec(inode, dentry, data1, data2, op);  
+        
+        RETURN(rc);
+}
 
 
+#define KML_HOOK "kml_hook"
 int smfs_rec_init(struct super_block *sb)
 {
         struct smfs_super_info *smfs_info = S2SMI(sb);
 int smfs_rec_init(struct super_block *sb)
 {
         struct smfs_super_info *smfs_info = S2SMI(sb);
+        struct smfs_hook_ops   *rec_hops = NULL;
         int rc = 0;
 
         SMFS_SET_REC(smfs_info);
         int rc = 0;
 
         SMFS_SET_REC(smfs_info);
@@ -58,14 +71,29 @@ int smfs_rec_init(struct super_block *sb)
         ost_rec_pack_init(sb);
         mds_rec_pack_init(sb);
 
         ost_rec_pack_init(sb);
         mds_rec_pack_init(sb);
 
+        rec_hops = smfs_alloc_hook_ops(KML_HOOK, NULL, smfs_rec_post_hook);
+        if (!rec_hops) {
+                RETURN(-ENOMEM);
+        }
+        rc = smfs_register_hook_ops(sb, rec_hops);      
+
+        if (rc && rec_hops) {
+                smfs_unregister_hook_ops(sb, rec_hops->smh_name);
+                smfs_free_hook_ops(rec_hops);
+        } 
         RETURN(rc);
 }
 
 int smfs_rec_cleanup(struct super_block *sb)
 {
         RETURN(rc);
 }
 
 int smfs_rec_cleanup(struct super_block *sb)
 {
+        struct smfs_hook_ops *rec_hops; 
         int rc = 0;
 
         int rc = 0;
 
+        rec_hops = smfs_unregister_hook_ops(sb, KML_HOOK);
+        smfs_free_hook_ops(rec_hops);
         SMFS_CLEAN_REC(S2SMI(sb));
         SMFS_CLEAN_REC(S2SMI(sb));
+        
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
index a041bf9..f6655bc 100644 (file)
@@ -123,6 +123,59 @@ static int smfs_init_cowed_dir(struct super_block *sb, struct dentry* cowed_dir)
         snap_info->sn_cowed_dentry = dentry;
         RETURN(rc);
 }
         snap_info->sn_cowed_dentry = dentry;
         RETURN(rc);
 }
+#define DOT_SNAP_NAME          ".snap"
+static int smfs_init_dotinfo(struct super_block *sb)
+{
+        struct snap_info *snap_info = S2SNAPI(sb);
+        struct snap_dot_info *dot_info = NULL;
+        int rc = 0;
+        ENTRY;
+
+        if (snap_info->sn_dot_info)
+                RETURN(-EEXIST);
+       
+        OBD_ALLOC(snap_info->sn_dot_info, sizeof(struct snap_dot_info));
+        
+        if (!snap_info->sn_dot_info)
+                RETURN(-ENOMEM); 
+      
+        dot_info = snap_info->sn_dot_info;
+        OBD_ALLOC(dot_info->dot_name,  strlen(DOT_SNAP_NAME) + 1);
+
+        if (!dot_info->dot_name) {
+                OBD_FREE(snap_info->sn_dot_info, sizeof(struct snap_dot_info));
+                RETURN(-ENOMEM); 
+        } 
+        memcpy(dot_info->dot_name, DOT_SNAP_NAME, strlen(DOT_SNAP_NAME));
+        
+        dot_info->dot_name_len = strlen(DOT_SNAP_NAME); 
+        dot_info->dot_snap_enable = 1;
+        
+        RETURN(rc);
+}
+
+static int smfs_cleanup_dotinfo(struct super_block *sb)
+{       
+        struct snap_info *snap_info = S2SNAPI(sb);
+        struct snap_dot_info *dot_info = NULL;
+        int rc = 0;
+        ENTRY;
+
+        if (!snap_info->sn_dot_info)
+                RETURN(rc);
+       
+        dot_info = snap_info->sn_dot_info;
+
+        if (dot_info->dot_name) { 
+                OBD_FREE(dot_info->dot_name, dot_info->dot_name_len + 1);
+        }
+        
+        OBD_FREE(dot_info, sizeof(struct snap_dot_info));
+
+        RETURN(rc);
+}
+
 int smfs_start_cow(struct super_block *sb)
 {
         int rc = 0;
 int smfs_start_cow(struct super_block *sb)
 {
         int rc = 0;
@@ -163,6 +216,12 @@ int smfs_start_cow(struct super_block *sb)
                 CERROR("can not init snaptable rc=%d\n", rc);
                 RETURN(rc);
         }
                 CERROR("can not init snaptable rc=%d\n", rc);
                 RETURN(rc);
         }
+        /*init dot snap info*/
+        rc = smfs_init_dotinfo(sb);
+        if (rc) {
+                CERROR("can not init dot snap info rc=%d\n", rc);
+                RETURN(rc);
+        }
         /*init cowed dir to put the primary cowed inode
          *FIXME-WANGDI, later the s_root may not be the 
          *snap dir, we can indicate any dir to be cowed*/
         /*init cowed dir to put the primary cowed inode
          *FIXME-WANGDI, later the s_root may not be the 
          *snap dir, we can indicate any dir to be cowed*/
@@ -188,32 +247,68 @@ int smfs_stop_cow(struct super_block *sb)
                 table_size =  SNAPTABLE_SIZE(snap_table->sntbl_max_count);
                 OBD_FREE(snap_info->sntbl, table_size);
         }
                 table_size =  SNAPTABLE_SIZE(snap_table->sntbl_max_count);
                 OBD_FREE(snap_info->sntbl, table_size);
         }
-        
+        smfs_cleanup_dotinfo(sb);
+         
         RETURN(rc);
 }
 EXPORT_SYMBOL(smfs_stop_cow);
 
         RETURN(rc);
 }
 EXPORT_SYMBOL(smfs_stop_cow);
 
+#define COW_HOOK "cow_hook"
+static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry, 
+                             void *data1, void *data2, int op, void *handle)
+{
+        int rc = 0;
+        ENTRY;
+        if (smfs_do_cow(inode)) {                                              
+                rc = smfs_cow(inode, dentry, data1, data2, op);           
+        }
+        RETURN(rc);                                                                     
+}
 int smfs_cow_init(struct super_block *sb)
 {
         struct smfs_super_info *smfs_info = S2SMI(sb);
 int smfs_cow_init(struct super_block *sb)
 {
         struct smfs_super_info *smfs_info = S2SMI(sb);
+        struct smfs_hook_ops *cow_hops = NULL;
         int rc = 0;
 
         int rc = 0;
 
+        ENTRY;
+
         SMFS_SET_COW(smfs_info);
       
         SMFS_SET_COW(smfs_info);
       
+        cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook, NULL);
+        if (!cow_hops) {
+                RETURN(-ENOMEM);
+        }
+        rc = smfs_register_hook_ops(sb, cow_hops);      
+
+        if (rc) {
+                smfs_free_hook_ops(cow_hops);
+                RETURN(rc);
+        }
         OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
         
         if (!smfs_info->smsi_snap_info) 
         OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
         
         if (!smfs_info->smsi_snap_info) 
-                RETURN(-ENOMEM);
-        
+                GOTO(exit, rc = -ENOMEM);
+exit:
+        if (rc && cow_hops) {
+                smfs_unregister_hook_ops(sb, cow_hops->smh_name);
+                smfs_free_hook_ops(cow_hops);
+        } 
         RETURN(rc);
 }
 
 int smfs_cow_cleanup(struct super_block *sb)
 {
         
         RETURN(rc);
 }
 
 int smfs_cow_cleanup(struct super_block *sb)
 {
         
-        struct snap_info       *snap_info = S2SNAPI(sb);       
-        
+        struct snap_info   *snap_info = S2SNAPI(sb);   
+        struct smfs_hook_ops *cow_hops; 
         ENTRY;
         ENTRY;
+
+        cow_hops = smfs_unregister_hook_ops(sb, COW_HOOK);
+        smfs_free_hook_ops(cow_hops);
+
         SMFS_CLEAN_COW(S2SMI(sb));
         if (snap_info) 
                OBD_FREE(snap_info, sizeof(*snap_info)); 
         SMFS_CLEAN_COW(S2SMI(sb));
         if (snap_info) 
                OBD_FREE(snap_info, sizeof(*snap_info)); 
@@ -438,7 +533,7 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
        ind = snapops->fs_create_indirect(inode, snap.sn_index, snap.sn_gen, 
                                           dparent->d_inode, del);
        if(ind && IS_ERR(ind)) {
        ind = snapops->fs_create_indirect(inode, snap.sn_index, snap.sn_gen, 
                                           dparent->d_inode, del);
        if(ind && IS_ERR(ind)) {
-                CERROR("Create ind inode %lu index %d gen %d del %d\n rc%d\n",
+                CERROR("Create ind inode %lu index %d gen %d del %d\n rc%u\n",
                         inode->i_ino, snap.sn_index, snap.sn_gen, del,
                         PTR_ERR(ind));
                RETURN(PTR_ERR(ind));
                         inode->i_ino, snap.sn_index, snap.sn_gen, del,
                         PTR_ERR(ind));
                RETURN(PTR_ERR(ind));
@@ -742,20 +837,26 @@ EXPORT_SYMBOL(smfs_cow_get_ind);
 typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry, 
                          void *new_dir, void *new_dentry);
 
 typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry, 
                          void *new_dir, void *new_dentry);
 
-
-static cow_funcs smfs_cow_funcs[REINT_MAX + 2] = {
-        [REINT_SETATTR] smfs_cow_setattr,
-        [REINT_CREATE]  smfs_cow_create,
-        [REINT_LINK]    smfs_cow_link,
-        [REINT_UNLINK]  smfs_cow_unlink,
-        [REINT_RENAME]  smfs_cow_rename,
-        [REINT_WRITE]   smfs_cow_write,
-        [SNAP_LOOKUP]   smfs_cow_lookup,
+static cow_funcs smfs_cow_funcs[HOOK_MAX + 1] = {
+        [HOOK_CREATE]   smfs_cow_create,
+        [HOOK_LOOKUP]   smfs_cow_lookup,
+        [HOOK_LINK]     smfs_cow_link,
+        [HOOK_UNLINK]   smfs_cow_unlink,
+        [HOOK_SYMLINK]  smfs_cow_create,
+        [HOOK_MKDIR]    smfs_cow_create,
+        [HOOK_RMDIR]    smfs_cow_unlink, 
+        [HOOK_MKNOD]    smfs_cow_create,
+        [HOOK_RENAME]   smfs_cow_rename,
+        [HOOK_SETATTR]  smfs_cow_setattr,
+        [HOOK_WRITE]    smfs_cow_write,
 };
 
 int smfs_cow(struct inode *dir, struct dentry *dentry, void *new_dir, 
              void *new_dentry, int op)
 {
 };
 
 int smfs_cow(struct inode *dir, struct dentry *dentry, void *new_dir, 
              void *new_dentry, int op)
 {
-        return smfs_cow_funcs[op](dir, dentry, new_dir, new_dentry);
+        if (smfs_cow_funcs[op]) {
+                return smfs_cow_funcs[op](dir, dentry, new_dir, new_dentry);
+        }
+        return 0;
 }
 
 }
 
index c3ef77e..51f593b 100644 (file)
@@ -59,16 +59,6 @@ struct smfs_control_device {
 
 #define MYPATHLEN(buffer, path) ((buffer) + PAGE_SIZE - (path))
 
 
 #define MYPATHLEN(buffer, path) ((buffer) + PAGE_SIZE - (path))
 
-#define SMFS_KML_POST(dir, dentry, data1, data2, op, name, rc, label)   \
-do {                                                                    \
-        if (smfs_do_rec(dir) && !rc) {                                  \
-                CDEBUG(D_INODE, "Do %s kml post for dir %lu \n",        \
-                              name, dir->i_ino);                        \
-                rc = smfs_post_kml_rec(dir, dentry, data1, data2, op);  \
-                if (rc)                                                 \
-                        GOTO(label, rc);                                \
-        }                                                               \
-} while(0)
 
 #define PACK_KML_REC_INIT(buffer, op_code)          \
 do{                                                 \
 
 #define PACK_KML_REC_INIT(buffer, op_code)          \
 do{                                                 \
@@ -77,6 +67,7 @@ do{                                                 \
         buffer += sizeof(opcode);                   \
 } while (0)
 
         buffer += sizeof(opcode);                   \
 } while (0)
 
+
 extern int init_smfs_proc_sys(void);
 /*options.c*/
 extern int get_opt(struct option **option, char **pos);
 extern int init_smfs_proc_sys(void);
 /*options.c*/
 extern int get_opt(struct option **option, char **pos);
@@ -126,6 +117,17 @@ static inline struct journal_operations *journal_ops(struct smfs_super_info *smb
 {
         return &smb->sm_ops->sm_journal_ops;
 }
 {
         return &smb->sm_ops->sm_journal_ops;
 }
+
+struct smfs_hook_ops *smfs_alloc_hook_ops(char *name, 
+                                          smfs_hook_func pre_hook, 
+                                          smfs_hook_func post_hook);
+
+void smfs_free_hook_ops(struct smfs_hook_ops *hops);
+int smfs_register_hook_ops(struct super_block *sb, 
+                           struct smfs_hook_ops *smh_ops);
+
+struct smfs_hook_ops *smfs_unregister_hook_ops(struct super_block *sb, 
+                                               char *name);
 /*super.c*/
 extern int init_smfs(void);
 extern int cleanup_smfs(void);
 /*super.c*/
 extern int init_smfs(void);
 extern int cleanup_smfs(void);
@@ -270,70 +272,53 @@ static inline int get_active_entry(struct inode *dir, __u64 *active_entry)
                 rc = 0;
         RETURN(rc);
 }
                 rc = 0;
         RETURN(rc);
 }
+#define HOOK_CREATE       1
+#define HOOK_LOOKUP       2
+#define HOOK_LINK         3
+#define HOOK_UNLINK       4
+#define HOOK_SYMLINK      5
+#define HOOK_MKDIR        6
+#define HOOK_RMDIR        7
+#define HOOK_MKNOD        8
+#define HOOK_RENAME       9
+#define HOOK_SETATTR      10
+#define HOOK_WRITE        11 
+#define HOOK_MAX          11 
 
 
-#define CACHE_HOOK_CREATE       1
-#define CACHE_HOOK_LOOKUP       2
-#define CACHE_HOOK_LINK         3
-#define CACHE_HOOK_UNLINK       4
-#define CACHE_HOOK_SYMLINK      5
-#define CACHE_HOOK_MKDIR        6
-#define CACHE_HOOK_RMDIR        7
-#define CACHE_HOOK_MKNOD        8
-#define CACHE_HOOK_RENAME       9
-
-#define CACHE_HOOK_MAX          9
-
-#define SMFS_CACHE_HOOK_PRE(op, handle, dir, rc)                                \
-{                                                                               \
-        while (smfs_cache_hook(dir)) {                                          \
-                if (!handle) {                                                  \
-                        handle = smfs_trans_start(dir, KML_CACHE_NOOP, NULL);   \
-                        if (IS_ERR(handle)) {                                   \
-                               rc = -ENOSPC;                                    \
-                               break;                                           \
-                        }                                                       \
-                }                                                               \
-                CDEBUG(D_INODE, "cache hook pre: op %d, dir %lu\n",             \
-                       op, dir->i_ino);                                         \
-                cache_space_pre(dir, op);                                       \
-                break;                                                          \
-        }                                                                       \
-}
-
-#define SMFS_CACHE_HOOK_POST(op, handle, old_dir, old_dentry,           \
-                             new_dir, new_dentry, rc, label)            \
-{                                                                       \
-        if (!rc && smfs_cache_hook(old_dir)) {                          \
-                LASSERT(handle != NULL);                                \
-                CDEBUG(D_INODE, "cache hook post: op %d, dir %lu\n",    \
-                       op, old_dir->i_ino);                             \
-                rc = cache_space_post(op, handle, old_dir, old_dentry,  \
-                                         new_dir, new_dentry);          \
-                if (rc)                                                 \
-                        GOTO(label, rc);                                \
-        }                                                               \
-}
-#if CONFIG_SNAPFS
-/*snap macros*/
-#define SMFS_PRE_COW(dir, dentry, new_dir, new_dentry, op, name, rc, label)    \
+#define PRE_HOOK 0
+#define POST_HOOK 1
+#define SMFS_HOOK(inode, dentry, data1, data2, op, handle, flag, rc, label)    \
 do {                                                                           \
 do {                                                                           \
-        if (smfs_do_cow(dir) && !rc) {                                         \
-                CDEBUG(D_INODE, "Do %s snap post for dir %lu \n",              \
-                              name, dir->i_ino);                               \
-                rc = smfs_cow(dir, dentry, new_dir, new_dentry, op);           \
-                if (op == SNAP_LOOKUP && rc == 1)                              \
-                        GOTO(label, rc = 0);                                   \
-                else if (rc)                                                   \
-                        GOTO(label, rc);                                       \
+        LASSERT(inode->i_sb);                                                  \
+        if (!rc) {                                                             \
+                struct smfs_super_info *smb = S2SMI(inode->i_sb);              \
+                struct list_head *hlist = &smb->smsi_hook_list;                \
+                struct list_head *p;                                           \
+                                                                               \
+                list_for_each(p, hlist) {                                      \
+                       struct smfs_hook_ops *hops;                            \
+                                                                               \
+                        hops = list_entry(p, typeof(*hops), smh_list);         \
+                        if (flag == PRE_HOOK && hops->smh_pre_op)              \
+                                rc = hops->smh_pre_op(inode, dentry, data1,    \
+                                                      data2, op, handle);      \
+                        else if (flag == POST_HOOK && hops->smh_post_op)       \
+                                rc = hops->smh_post_op(inode, dentry, data1,   \
+                                                       data2, op, handle);     \
+                        if (rc)                                                \
+                                break;                                         \
+                }                                                              \
         }                                                                      \
         }                                                                      \
-} while(0)
+        if (rc)                                                                \
+                GOTO(label, rc);                                               \
+} while(0)                                                                     \
 
 
+#if CONFIG_SNAPFS
 extern int smfs_cow_init(struct super_block *sb);
 extern int smfs_cow_cleanup(struct super_block *sb);
 extern int smfs_init_snap_inode_info(struct inode *inode, int flags);
 #else
 #define SMFS_PRE_COW(dir, dentry, new_dir, new_dentry, op, name, rc, label)                 
 #endif 
 extern int smfs_cow_init(struct super_block *sb);
 extern int smfs_cow_cleanup(struct super_block *sb);
 extern int smfs_init_snap_inode_info(struct inode *inode, int flags);
 #else
 #define SMFS_PRE_COW(dir, dentry, new_dir, new_dentry, op, name, rc, label)                 
 #endif 
-
 #endif /*__KERNEL*/
 #endif /* __LINUX_SMFS_H */
 #endif /*__KERNEL*/
 #endif /* __LINUX_SMFS_H */
index 994adbf..7f79438 100644 (file)
@@ -213,6 +213,35 @@ static int sm_umount_cache(struct super_block *sb)
         return 0;
 }
 
         return 0;
 }
 
+static int smfs_init_hook_ops(struct super_block *sb)
+{
+        struct smfs_super_info *smb = S2SMI(sb);
+        ENTRY;
+
+        INIT_LIST_HEAD(&smb->smsi_hook_list);
+
+        RETURN(0); 
+}
+static void smfs_cleanup_hook_ops(struct super_block *sb)
+{
+        struct smfs_super_info *smb = S2SMI(sb);
+        struct list_head *hlist = &smb->smsi_hook_list;
+        ENTRY;
+
+        while (!list_empty(hlist)) {
+                struct smfs_hook_ops *smfs_hops;
+                
+                smfs_hops = list_entry(hlist->next, struct smfs_hook_ops, 
+                                       smh_list);
+                CERROR("Unregister %s hook ops\n", smfs_hops->smh_name);         
+                
+                smfs_unregister_hook_ops(sb, smfs_hops->smh_name);
+                smfs_free_hook_ops(smfs_hops); 
+        } 
+        EXIT;
+        return;        
+}
+
 void smfs_put_super(struct super_block *sb)
 {
         if (SMFS_CACHE_HOOK(S2SMI(sb)))
 void smfs_put_super(struct super_block *sb)
 {
         if (SMFS_CACHE_HOOK(S2SMI(sb)))
@@ -222,12 +251,13 @@ void smfs_put_super(struct super_block *sb)
 #if CONFIG_SNAPFS
         if (SMFS_DO_COW(S2SMI(sb)))
                 smfs_cow_cleanup(sb);
 #if CONFIG_SNAPFS
         if (SMFS_DO_COW(S2SMI(sb)))
                 smfs_cow_cleanup(sb);
-#endif
+#endif  
+        smfs_cleanup_hook_ops(sb);
         if (sb)
                 sm_umount_cache(sb);
         return;
 }
         if (sb)
                 sm_umount_cache(sb);
         return;
 }
-
 static int smfs_fill_super(struct super_block *sb,
                            void *data, int silent)
 {
 static int smfs_fill_super(struct super_block *sb,
                            void *data, int silent)
 {
@@ -264,7 +294,13 @@ static int smfs_fill_super(struct super_block *sb,
                 CERROR("Can not mount %s as %s\n", devstr, typestr);
                 GOTO(out_err, 0);
         }
                 CERROR("Can not mount %s as %s\n", devstr, typestr);
                 GOTO(out_err, 0);
         }
-
+        
+        err = smfs_init_hook_ops(sb);
+        if (err) {
+                CERROR("Can not init super hook ops err %d\n", err);
+                GOTO(out_err, 0);
+        }
+        
         if (do_rec) smfs_rec_init(sb);
         if (cache_hook) cache_space_hook_init(sb);
         
         if (do_rec) smfs_rec_init(sb);
         if (cache_hook) cache_space_hook_init(sb);