From e6f6828c31626e3f727050742b6782ea65b5d605 Mon Sep 17 00:00:00 2001 From: wangdi Date: Mon, 2 Aug 2004 14:58:13 +0000 Subject: [PATCH] 1)reorganize the smfs hook ops to make smfs walk a list of hooks ops in hook macro 2)remove clonefs in llite, we do not need them now 3)add snap_dot_info in snap_super_info --- lustre/include/linux/lustre_smfs.h | 17 ++++- lustre/include/linux/lustre_snap.h | 14 ++-- lustre/llite/llite_lib.c | 94 ----------------------- lustre/smfs/cache.c | 75 +++++++++++++++++++ lustre/smfs/cache_space.c | 87 ++++++++++++++++++---- lustre/smfs/dir.c | 148 +++++++++++++++---------------------- lustre/smfs/file.c | 14 ++-- lustre/smfs/journal.c | 28 ++++--- lustre/smfs/kml.c | 28 +++++++ lustre/smfs/smfs_cow.c | 133 +++++++++++++++++++++++++++++---- lustre/smfs/smfs_internal.h | 115 +++++++++++++--------------- lustre/smfs/super.c | 42 ++++++++++- 12 files changed, 486 insertions(+), 309 deletions(-) diff --git a/lustre/include/linux/lustre_smfs.h b/lustre/include/linux/lustre_smfs.h index 7bb62cb..8ef548e 100644 --- a/lustre/include/linux/lustre_smfs.h +++ b/lustre/include/linux/lustre_smfs.h @@ -70,7 +70,14 @@ struct mds_kml_pack_info { 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 */ @@ -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 */ - 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 */ - __u32 smsi_flags; /* flags */ + __u32 smsi_flags; /* flags */ __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 { diff --git a/lustre/include/linux/lustre_snap.h b/lustre/include/linux/lustre_snap.h index 6421423..c253979 100644 --- a/lustre/include/linux/lustre_snap.h +++ b/lustre/include/linux/lustre_snap.h @@ -165,6 +165,12 @@ struct snap_table { 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; @@ -173,13 +179,9 @@ struct snap_info { 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); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index d8ae8e8..2cab4c8 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -106,74 +106,6 @@ int lustre_init_ea_size(struct ll_sb_info *sbi) 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) { @@ -471,16 +403,6 @@ int ll_fill_super(struct super_block *sb, void *data, int silent) } 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); @@ -712,15 +634,6 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) 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) @@ -754,9 +667,6 @@ out_free: } 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; @@ -804,10 +714,6 @@ void lustre_put_super(struct super_block *sb) 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; diff --git a/lustre/smfs/cache.c b/lustre/smfs/cache.c index 17b40dd..717e3af 100644 --- a/lustre/smfs/cache.c +++ b/lustre/smfs/cache.c @@ -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; } +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); +} + diff --git a/lustre/smfs/cache_space.c b/lustre/smfs/cache_space.c index 45bcf40..3f88fc7 100644 --- a/lustre/smfs/cache_space.c +++ b/lustre/smfs/cache_space.c @@ -43,16 +43,69 @@ struct cache_purge_param { 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); + 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); - return 0; + + RETURN(0); } + 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; @@ -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); -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 rc; + int rc = 0; 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); } diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index ccb130b..0c07e7c 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -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); - - 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); - lock_kernel(); 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) @@ -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); - - /*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); @@ -135,8 +127,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, 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)); @@ -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)); - 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); @@ -177,8 +167,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, 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); @@ -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); - - SMFS_CACHE_HOOK_PRE(CACHE_HOOK_LINK, handle, dir, rc); 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); @@ -239,11 +227,9 @@ static int smfs_link(struct dentry * old_dentry, 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); @@ -271,9 +257,8 @@ static int smfs_unlink(struct inode * dir, 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); @@ -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(); - 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); @@ -314,23 +297,21 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry, 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); + + 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); - lock_kernel(); 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; - 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); @@ -373,14 +352,14 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry, 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); - lock_kernel(); 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); - 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); @@ -431,14 +407,14 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry) 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); - lock_kernel(); 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(); - 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); @@ -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); } - 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); - lock_kernel(); 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); - 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); @@ -552,10 +524,10 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry, } 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); @@ -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); - 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); - - 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); diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c index d7f325e..45602dd 100644 --- a/lustre/smfs/file.c +++ b/lustre/smfs/file.c @@ -68,9 +68,8 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count, 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; @@ -86,8 +85,8 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count, 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; @@ -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); - 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); diff --git a/lustre/smfs/journal.c b/lustre/smfs/journal.c index d23fcd5..ab62e7a 100644 --- a/lustre/smfs/journal.c +++ b/lustre/smfs/journal.c @@ -518,19 +518,27 @@ exit: } 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) { - 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; } diff --git a/lustre/smfs/kml.c b/lustre/smfs/kml.c index 310e4da..8275ba2 100644 --- a/lustre/smfs/kml.c +++ b/lustre/smfs/kml.c @@ -47,10 +47,23 @@ smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb) 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); + struct smfs_hook_ops *rec_hops = NULL; 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); + 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) { + struct smfs_hook_ops *rec_hops; int rc = 0; + rec_hops = smfs_unregister_hook_ops(sb, KML_HOOK); + smfs_free_hook_ops(rec_hops); SMFS_CLEAN_REC(S2SMI(sb)); + RETURN(rc); } diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c index a041bf9..f6655bc 100644 --- a/lustre/smfs/smfs_cow.c +++ b/lustre/smfs/smfs_cow.c @@ -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); } +#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; @@ -163,6 +216,12 @@ int smfs_start_cow(struct super_block *sb) 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*/ @@ -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); } - + smfs_cleanup_dotinfo(sb); + 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); + struct smfs_hook_ops *cow_hops = NULL; int rc = 0; + ENTRY; + 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) - 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) { - struct snap_info *snap_info = S2SNAPI(sb); - + struct snap_info *snap_info = S2SNAPI(sb); + struct smfs_hook_ops *cow_hops; 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)); @@ -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)) { - 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)); @@ -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); - -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) { - 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; } diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h index c3ef77e..51f593b 100644 --- a/lustre/smfs/smfs_internal.h +++ b/lustre/smfs/smfs_internal.h @@ -59,16 +59,6 @@ struct smfs_control_device { #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{ \ @@ -77,6 +67,7 @@ do{ \ buffer += sizeof(opcode); \ } while (0) + 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; } + +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); @@ -270,70 +272,53 @@ static inline int get_active_entry(struct inode *dir, __u64 *active_entry) 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 { \ - 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 - #endif /*__KERNEL*/ #endif /* __LINUX_SMFS_H */ diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c index 994adbf..7f79438 100644 --- a/lustre/smfs/super.c +++ b/lustre/smfs/super.c @@ -213,6 +213,35 @@ static int sm_umount_cache(struct super_block *sb) 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))) @@ -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); -#endif +#endif + smfs_cleanup_hook_ops(sb); + if (sb) sm_umount_cache(sb); return; } - 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); } - + + 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); -- 1.8.3.1