Whamcloud - gitweb
update .snap on smfs
authorwangdi <wangdi>
Thu, 19 Aug 2004 16:45:48 +0000 (16:45 +0000)
committerwangdi <wangdi>
Thu, 19 Aug 2004 16:45:48 +0000 (16:45 +0000)
13 files changed:
lustre/include/linux/lustre_smfs.h
lustre/lvfs/fsfilt_smfs.c
lustre/lvfs/fsfilt_snap_ext3.c
lustre/lvfs/fsfilt_snap_smfs.c
lustre/smfs/dir.c
lustre/smfs/file.c
lustre/smfs/inode.c
lustre/smfs/ioctl.c
lustre/smfs/kml.c
lustre/smfs/smfs_cow.c
lustre/smfs/smfs_internal.h
lustre/smfs/smfs_lib.c
lustre/smfs/symlink.c

index 710569c..ac5f5f3 100644 (file)
@@ -412,15 +412,11 @@ static inline void smfs_free_dentry_name(struct qstr *str)
 
 static inline struct dentry *pre_smfs_dentry(struct dentry *parent_dentry,
                                              struct inode *cache_inode,
-                                             struct dentry *dentry,
-                                             int           *index)
+                                             struct dentry *dentry)
 {
         struct dentry *cache_dentry = NULL;
-        struct qstr   name; 
         
-        smfs_get_dentry_name_index(dentry, &name, index);       
-        cache_dentry = d_alloc(parent_dentry, &name);
-        smfs_free_dentry_name(&name);
+        cache_dentry = d_alloc(parent_dentry, &dentry->d_name);
         if (!cache_dentry)
                 RETURN(NULL);
         if (!parent_dentry)
index 9661a6a..f986514 100644 (file)
@@ -76,8 +76,7 @@ static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
                 return NULL;
 
         cache_inode = I2CI(fso->fso_dentry->d_inode);
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry, 
-                                       NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
 
         if (!cache_dentry)
                 GOTO(exit, rc = ERR_PTR(-ENOMEM));
@@ -171,7 +170,7 @@ static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
 
         cache_inode = I2CI(dentry->d_inode);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
index 546b44e..e1ef83d 100644 (file)
@@ -176,7 +176,7 @@ static struct inode *fsfilt_ext3_get_indirect(struct inode *primary, int *table,
        struct snap_ea *snaps;
        ino_t ino;
        struct inode *inode = NULL;
-       int rc = 0, index = 0;
+       int rc = 0;
 
         ENTRY;
 
@@ -197,16 +197,14 @@ static struct inode *fsfilt_ext3_get_indirect(struct inode *primary, int *table,
 
        /* if table is NULL and there is a slot */
        if( !table && slot >= 0) {
-               index = slot;
-               ino = le32_to_cpu(snaps->ino[index]);
+               ino = le32_to_cpu(snaps->ino[slot]);
                if(ino) 
                         inode = iget(primary->i_sb, ino);
                GOTO(err_free, rc);
        }
        /* if table is not NULL */
-       while (!inode && slot >= 0 && table) {
-               index = table[slot];
-               ino = le32_to_cpu(snaps->ino[index]);
+       while (!inode && slot >= 0 ) {
+               ino = le32_to_cpu(snaps->ino[slot]);
 
                CDEBUG(D_INODE, "snap inode at slot %d is %lu\n", slot, ino);
                if (!ino) {
@@ -216,7 +214,7 @@ static struct inode *fsfilt_ext3_get_indirect(struct inode *primary, int *table,
                inode = iget(primary->i_sb, ino);
                GOTO(err_free, rc);
        }
-       if( slot == -1 && table ) {
+       if( slot == -1) {
                CDEBUG(D_INODE, "redirector not found, using primary\n");
                inode = iget(primary->i_sb, primary->i_ino);
        }
index ac32239..268db4b 100644 (file)
@@ -371,11 +371,11 @@ static int fsfilt_smfs_get_snap_info(struct inode *inode, void *key,
 static int fsfilt_smfs_read_dotsnap_dir_page(struct file *file, char *buf,
                                              size_t count, loff_t *off)
 {
+#if 0
         struct inode *inode = file->f_dentry->d_inode;
         struct fsfilt_operations *snap_cops = I2SNAPCOPS(inode);
         int    i = 0, size = 0, off_count = 0, buf_off = 0, rc = 0;
         ENTRY;
-#if 0
         /*Get the offset of dir ent*/
         //struct snap_table *stbl = S2SNAPI(inode->i_sb)->sni_table;
         while (size < *off && off_count < stbl->sntbl_count) {
@@ -400,7 +400,7 @@ static int fsfilt_smfs_read_dotsnap_dir_page(struct file *file, char *buf,
 #else
 #warning "still not implement read .snap dir page for fsfilt Wangdi"
 #endif
-        RETURN(rc); 
+        RETURN(0); 
 }
 
 struct fsfilt_operations fsfilt_smfs_snap_ops = {
index d964ba2..a9c2434 100644 (file)
@@ -69,8 +69,8 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
         lock_kernel();
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle, PRE_HOOK, rc, 
                   exit); 
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
         if (!cache_dentry || !cache_parent)
                 GOTO(exit, rc = -ENOMEM);
@@ -88,8 +88,7 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
         if (rc)
                 GOTO(exit, rc);
         
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, 
-                       rc, exit); 
+        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
 
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
@@ -118,7 +117,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         struct dentry *cache_parent = NULL;
         struct dentry *rc = NULL;
         void *handle = NULL;
-        int rc2 = 0, index = 0;
+        int rc2 = 0;
 
         ENTRY;
 
@@ -126,8 +125,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
                 RETURN(ERR_PTR(-ENOENT));
 
         /* preparing artificial backing fs dentries. */
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, &index);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
         if (!cache_dentry || !cache_parent)
                 GOTO(exit, rc = ERR_PTR(-ENOMEM));
@@ -135,7 +134,7 @@ 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_HOOK(dir, dentry, &index, NULL, HOOK_LOOKUP, handle, 
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, 
                   PRE_HOOK, rc2, exit); 
 
         /* perform lookup in backing fs. */
@@ -152,8 +151,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
                         dentry->d_inode = cache_inode;
                         GOTO(exit, rc = NULL);
                 }
-                SMFS_GET_INODE(dir->i_sb, cache_inode, dir, index, inode, rc2,
-                               exit);
+                SMFS_GET_INODE(dir->i_sb, cache_inode, dir, inode, rc2, exit);
         } else {
                 d_add(dentry, NULL);
                 GOTO(exit, rc);
@@ -197,14 +195,13 @@ static int smfs_link(struct dentry * old_dentry,
         SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle, PRE_HOOK, rc, 
                   exit); 
         
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
+        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);
 
-        cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode,
-                                           old_dentry, NULL);
+        cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode, old_dentry);
         if (!cache_old_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -254,8 +251,8 @@ static int smfs_unlink(struct inode * dir,
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc, 
                   exit); 
         
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry, NULL);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
+        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
@@ -299,8 +296,8 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc, 
                   exit); 
 
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
+        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);
@@ -311,8 +308,7 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
 
         post_smfs_inode(dir, cache_dir);
         
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, 
-                       rc, exit); 
+        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
         if (inode)
                 d_instantiate(dentry, inode);
         else
@@ -352,8 +348,8 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc, 
                   exit); 
         
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
+        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);
@@ -366,8 +362,7 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
         if (rc)
                 GOTO(exit, rc);
   
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, 
-                       rc, exit); 
+        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
 
@@ -404,8 +399,8 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc, 
                   exit); 
 
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry, NULL);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
+        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
@@ -456,8 +451,8 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry,
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc, 
                   exit); 
         
-        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent, NULL);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -471,8 +466,7 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry,
                                          mode, rdev)))
                 GOTO(exit, rc);
 
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, 
-                       rc, exit); 
+        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
 
         d_instantiate(dentry, inode);
 
@@ -521,15 +515,15 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
         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, NULL);
+        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, NULL);
+                                           old_dentry);
         if (!cache_old_parent || !cache_old_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
-        cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry, NULL);
+        cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry);
         cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
-                                           new_dentry, NULL);
+                                           new_dentry);
         if (!cache_new_parent || !cache_new_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
index 37e9d63..45602dd 100644 (file)
@@ -242,7 +242,7 @@ static int smfs_init_cache_file(struct inode *inode, struct file *filp)
 
         sfi->magic = SMFS_FILE_MAGIC;
 
-        cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry);
         if (!cache_dentry)
                 GOTO(err_exit, rc = -ENOMEM);
 
@@ -350,7 +350,7 @@ int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
         if (!cache_inode)
                 RETURN(-ENOENT);
         
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
@@ -418,7 +418,7 @@ int smfs_setattr(struct dentry *dentry, struct iattr *attr)
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
@@ -454,7 +454,7 @@ int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
@@ -481,7 +481,7 @@ int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
@@ -507,7 +507,7 @@ ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
@@ -532,7 +532,7 @@ int smfs_removexattr(struct dentry *dentry, const char *name)
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
index 8ed305c..59badd4 100644 (file)
@@ -42,10 +42,7 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque)
         struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque;
         struct inode *cache_inode = NULL;
         
-        if (sargs) 
-                cache_inode = iget(S2CSB(inode->i_sb), sargs->s_ino);
-        else
-                cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino);
+        cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino);
                  
         OBD_ALLOC(I2SMI(inode), sizeof(struct smfs_inode_info));
         LASSERT(I2SMI(inode));
@@ -60,11 +57,6 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque)
                
                 if (dir)
                         I2SMI(inode)->smi_flags = I2SMI(dir)->smi_flags;
-#if CONFIG_SNAPFS
-                if (SMFS_DO_COW(S2SMI(inode->i_sb))) {
-                        smfs_init_snap_inode_info(inode, sargs);
-                }
-#endif
           }
 }
 
@@ -101,8 +93,15 @@ static int smfs_test_inode(struct inode *inode, unsigned long ino,
 static int smfs_test_inode(struct inode *inode, void *opaque)
 #endif
 {
-        if (!opaque)
+        struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque;
+
+        LASSERT(sargs);
+        if (!sargs)
                 return 1;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+        if (inode->i_ino != sargs->s_ino)
+                return 0; 
+#endif       
 #ifdef CONFIG_SNAPFS        
         if (SMFS_DO_COW(S2SMI(inode->i_sb)) && 
             !smfs_snap_test_inode(inode, opaque))
@@ -131,8 +130,6 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash,
                         unlock_new_inode(inode);
                 CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
                        inode->i_generation, inode);
-                
-                inode->i_ino = hash;
         }
         return inode;
 }
index 0a3019a..82413c3 100644 (file)
@@ -50,7 +50,6 @@ static struct super_block *smfs_get_sb_by_path(char *path, int len)
 {
         struct super_block *sb;
         struct nameidata nd;
-        int error = 0;
 
         ENTRY;
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
index 8275ba2..242c0e2 100644 (file)
@@ -68,31 +68,29 @@ int smfs_rec_init(struct super_block *sb)
 
         SMFS_SET_REC(smfs_info);
 
-        ost_rec_pack_init(sb);
-        mds_rec_pack_init(sb);
+        ost_rec_pack_init(smfs_info);
+        mds_rec_pack_init(smfs_info);
 
         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);      
-
+        rc = smfs_register_hook_ops(smfs_info, rec_hops);
         if (rc && rec_hops) {
-                smfs_unregister_hook_ops(sb, rec_hops->smh_name);
+                smfs_unregister_hook_ops(smfs_info, rec_hops->smh_name);
                 smfs_free_hook_ops(rec_hops);
         } 
         RETURN(rc);
 }
 
-int smfs_rec_cleanup(struct super_block *sb)
+int smfs_rec_cleanup(struct smfs_super_info *smfs_info)
 {
         struct smfs_hook_ops *rec_hops; 
         int rc = 0;
 
-        rec_hops = smfs_unregister_hook_ops(sb, KML_HOOK);
+        rec_hops = smfs_unregister_hook_ops(smfs_info, KML_HOOK);
         smfs_free_hook_ops(rec_hops);
-        SMFS_CLEAN_REC(S2SMI(sb));
+        SMFS_CLEAN_REC(smfs_info);
         
         RETURN(rc);
 }
index 84c30c0..8505482 100644 (file)
@@ -128,6 +128,95 @@ out_up:
         return dchild;
 
 }
+static struct snap_info *smfs_find_snap_info(struct inode *inode)
+{
+        struct snap_inode_info *snap_iinfo = I2SNAPI(inode);
+        struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
+        struct snap_info *snap_info = NULL, *tmp; 
+
+        ENTRY;
+        list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list, 
+                                 sni_list) {
+               if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino)
+                        RETURN(snap_info); 
+        }
+        RETURN(NULL);
+}
+
+static int smfs_dotsnap_dir_size(struct inode *inode)
+{
+        struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
+        struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt; 
+        int size = 0, dir_size = 0, blocks, i = 0;
+        struct snap_table *snap_table = NULL; 
+        struct snap_info *snap_info = NULL;
+        ENTRY;
+       
+        snap_info = smfs_find_snap_info(inode);
+        
+        if (!snap_info) {
+                CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
+                RETURN(0);                
+        }
+        snap_table = snap_info->sni_table;
+        for (i = 0; i < snap_table->sntbl_count; i++) {
+                char *name = snap_table->sntbl_items[i].sn_name;
+                size += snapops->fs_dir_ent_size(name);
+        }
+        /*FIXME this is only for ext3 dir format, may need fix for other FS*/ 
+        blocks = (size + inode->i_sb->s_blocksize - 1) >> 
+                                inode->i_sb->s_blocksize_bits; 
+        
+        dir_size = blocks * inode->i_sb->s_blocksize; 
+        RETURN(dir_size); 
+
+} 
+
+static int smfs_init_snap_inode_info(struct inode *inode, struct inode *dir, int index) 
+{
+        int rc = 0;
+        ENTRY;
+
+        if (dir) {
+                I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags;
+                I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen;
+                I2SNAPI(inode)->sn_root_ino = I2SNAPI(dir)->sn_root_ino;
+                I2SNAPI(inode)->sn_index = I2SNAPI(inode)->sn_index; 
+        } else {
+                I2SNAPI(inode)->sn_flags = 0;
+                I2SNAPI(inode)->sn_gen = 0;
+        }
+        
+        I2SNAPI(inode)->sn_index = index;
+        if (smfs_dotsnap_inode(inode)) {
+                struct snap_info *snap_info;
+
+                snap_info = smfs_find_snap_info(inode);
+                if (!snap_info) {
+                        RETURN(-EIO);
+                }
+                /*init dot_snap inode info*/
+                inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode);
+                inode->i_nlink = snap_info->sni_table->sntbl_count + 2;
+                inode->i_uid = 0;
+                inode->i_gid = 0;
+        } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) && 
+                   (I2SMI(inode)->smi_flags & SM_DO_COW) &&
+                   smfs_primary_inode(inode)) {
+                struct snap_inode_info *sni_info = I2SNAPI(inode);
+                struct fsfilt_operations *sops = I2SNAPCOPS(inode);
+                int vallen = 0;
+                vallen = sizeof(sni_info->sn_gen);
+                
+                rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION,
+                                            strlen(SNAP_GENERATION),
+                                            &sni_info->sn_gen, &vallen);               
+        } 
+        RETURN(rc);                                              
+}
+
 #define COWED_NAME_LEN       (7 + 8 + 1) 
 static int smfs_init_cowed_dir(struct snap_info *snap_info, struct dentry* dir)  
 {
@@ -265,13 +354,19 @@ static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo,
                 GOTO(exit, snap_info = ERR_PTR(rc));
        
         /*set cow flags for the snap root inode*/ 
-        I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW; 
+        I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW;
+        I2SNAPI(dentry->d_inode)->sn_root_ino = dentry->d_inode->i_ino; 
 exit:
         if (rc)
                 OBD_FREE(snap_info, sizeof(struct snap_info));
         RETURN(snap_info);
 }
 
+static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, 
+                        void *new_dentry, int op);
+
+static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir, 
+                         void *new_dentry, int op);
 #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)
@@ -279,11 +374,29 @@ static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry,
         int rc = 0;
         ENTRY;
  
-        if (smfs_do_cow(inode)) {                                              
-                rc = smfs_cow(inode, dentry, data1, data2, op);           
+        if (smfs_do_cow(inode)) {
+                /*FIXME:WANGDI, get index from the dentry*/
+                #if 0
+                int index = 0;
+                smfs_get_dentry_name_index(dentry, &name, index);       
+                smfs_free_dentry_name(&name);
+                #endif
+                rc = smfs_cow_pre(inode, dentry, data1, data2, op);           
         }
         RETURN(rc);                                                                     
 }
+static int smfs_cow_post_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_post(inode, dentry, data1, data2, op);           
+        }
+        RETURN(rc);                                                                     
+}
+
 int smfs_cow_init(struct super_block *sb)
 {
         struct smfs_super_info *smfs_info = S2SMI(sb);
@@ -296,7 +409,8 @@ int smfs_cow_init(struct super_block *sb)
 
         SMFS_SET_COW(smfs_info);
       
-        cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook, NULL);
+        cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook, 
+                                       smfs_cow_post_hook);
         if (!cow_hops) {
                 RETURN(-ENOMEM);
         }
@@ -345,15 +459,16 @@ int smfs_cow_init(struct super_block *sb)
                         struct dentry *dentry;                        
  
                         root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
-                        dentry = pre_smfs_dentry(NULL, root_inode, tmp, 
-                                                 NULL); 
+                        smfs_init_snap_inode_info(root_inode, NULL, 0);
+                        dentry = pre_smfs_dentry(NULL, root_inode, tmp); 
                         snap_info = smfs_create_snap_info(S2SMI(sb), dentry);
                         post_smfs_dentry(dentry);
                         if (IS_ERR(snap_info)) {
                                 OBD_FREE(snap_root, sizeof(int) * snap_count);
                                 GOTO(exit, rc = PTR_ERR(snap_info));
                         }                
-                        list_add(&snap_info->sni_list, &(S2SNAPI(sb)->snap_list));        
+                        list_add(&snap_info->sni_list, 
+                                 &(S2SNAPI(sb)->snap_list));        
                 }
         }       
 exit:
@@ -432,48 +547,6 @@ int smfs_cow_cleanup(struct smfs_super_info *smb)
         RETURN(rc);
 }
 
-static struct snap_info *smfs_find_snap_info(struct inode *inode)
-{
-        struct snap_inode_info *snap_iinfo = I2SNAPI(inode);
-        struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
-        struct snap_info *snap_info = NULL, *tmp; 
-
-        ENTRY;
-        list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list, 
-                                 sni_list) {
-               if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino)
-                        RETURN(snap_info); 
-        }
-        RETURN(NULL);
-}
-static int smfs_dotsnap_dir_size(struct inode *inode)
-{
-        struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
-        struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt; 
-        int size = 0, dir_size = 0, blocks, i = 0;
-        struct snap_table *snap_table = NULL; 
-        struct snap_info *snap_info = NULL;
-        ENTRY;
-       
-        snap_info = smfs_find_snap_info(inode);
-        
-        if (!snap_info) {
-                CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
-                RETURN(0);                
-        }
-        snap_table = snap_info->sni_table;
-        for (i = 0; i < snap_table->sntbl_count; i++) {
-                char *name = snap_table->sntbl_items[i].sn_name;
-                size += snapops->fs_dir_ent_size(name);
-        }
-        /*FIXME this is only for ext3 dir format, may need fix for other FS*/ 
-        blocks = (size + inode->i_sb->s_blocksize - 1) >> 
-                                inode->i_sb->s_blocksize_bits; 
-        
-        dir_size = blocks * inode->i_sb->s_blocksize; 
-        RETURN(dir_size); 
-
-} 
 int smfs_snap_test_inode(struct inode *inode, void *args)
 { 
         struct smfs_iget_args *sargs = (struct smfs_iget_args*)args;
@@ -483,63 +556,15 @@ int smfs_snap_test_inode(struct inode *inode, void *args)
         
         dir = sargs->s_inode;
         
-        if (dir){
-                if (I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index)
-                        return 0;
-        } else { 
+        if (sargs->s_index > 0) { 
                 if (I2SNAPI(inode)->sn_index != sargs->s_index)
-                        return 0; 
+                        return 0;
+        }else {
+                if (dir && I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index)
+                        return 0;
         }
         return 1;
 }
-
-/*FIXME Note indirect and primary inode 
-* should be recorgnized here*/
-int smfs_init_snap_inode_info(struct inode *inode, struct smfs_iget_args *args) 
-{
-        struct inode *dir;
-        int vallen, rc = 0;
-        ENTRY;
-
-        LASSERT(args);
-
-        I2SNAPI(inode)->sn_index = args->s_index; 
-        
-        dir = args->s_inode;
-        if (dir) {
-                I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags;
-                I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen;
-        } else {
-                I2SNAPI(inode)->sn_flags = 0;
-                I2SNAPI(inode)->sn_gen = 0;
-        }
-        
-        if (smfs_dotsnap_inode(inode)) {
-                struct snap_info *snap_info;
-
-                snap_info = smfs_find_snap_info(inode);
-                if (!snap_info) {
-                        RETURN(-EIO);
-                }
-                /*init dot_snap inode info*/
-                inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode);
-                inode->i_nlink = snap_info->sni_table->sntbl_count + 2;
-                inode->i_uid = 0;
-                inode->i_gid = 0;
-        } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) && 
-                   (I2SMI(inode)->smi_flags & SM_DO_COW) &&
-                   smfs_primary_inode(inode)) {
-                struct snap_inode_info *sni_info = I2SNAPI(inode);
-                struct fsfilt_operations *sops = I2SNAPCOPS(inode);
-                
-                vallen = sizeof(sni_info->sn_gen);
-                
-                rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION,
-                                            strlen(SNAP_GENERATION),
-                                            &sni_info->sn_gen, &vallen);               
-        } 
-        RETURN(rc);                                              
-}
 /* latest snap: returns 
    -  the index of the latest snapshot before NOW
    -  hence it returns 0 in case all the volume snapshots lie in the future
@@ -799,7 +824,7 @@ static int link_cowed_inode(struct inode *inode)
                 LASSERT(dchild->d_inode == inode);
                 GOTO(out_dput, rc = 0);
         }
-        tmp = pre_smfs_dentry(NULL, inode, cowed_dir, NULL);
+        tmp = pre_smfs_dentry(NULL, inode, cowed_dir);
         /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG
          * for linking and return real mode back then -bzzz */
         mode = inode->i_mode;
@@ -830,8 +855,7 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
 {
        struct fsfilt_operations *snapops = I2SNAPCOPS(inode);
         struct snap snap;
-       struct inode *ind = NULL, *cache_ind = NULL;
-       ino_t  ind_ino;
+       struct inode *cache_ind = NULL;
         ENTRY;
 
        if (!snapops || !snapops->fs_create_indirect) 
@@ -845,24 +869,13 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
                 CERROR("Create ind inode %lu index %d gen %d del %d rc%lu\n",
                         inode->i_ino, snap.sn_index, snap.sn_gen, del,
                         PTR_ERR(cache_ind));
-               RETURN(PTR_ERR(ind));
+               RETURN(PTR_ERR(cache_ind));
         }
-        ind_ino = cache_ind->i_ino;
         iput(cache_ind);
-        /*FIXME: get indirect inode set_cow flags*/ 
-        ind = smfs_get_inode(inode->i_sb, ind_ino, inode, 0);
-        if (ind) { 
-                if (!SMFS_DO_INODE_COWED(inode)) {
-                        /*insert the inode to cowed inode*/
-                        SMFS_SET_INODE_COWED(inode); 
-                        link_cowed_inode(inode); 
-                }
-                
-                I2SMI(ind)->sm_sninfo.sn_flags = 0;
-                I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen;
-                I2SMI(ind)->sm_sninfo.sn_index = snap.sn_index;
-                
-                iput(ind);
+        if (!SMFS_DO_INODE_COWED(inode)) {
+                /*insert the inode to cowed inode*/
+                SMFS_SET_INODE_COWED(inode); 
+                link_cowed_inode(inode); 
         }
         RETURN(0);
 }
@@ -1123,6 +1136,7 @@ static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry,
                         CERROR("Can not find cino %lu inode\n", cino);
                         RETURN(-ENOENT); 
                 } 
+                smfs_init_snap_inode_info(inode, dir, index);
                 d_add(dentry, inode);
         } 
         RETURN(0);
@@ -1156,6 +1170,7 @@ int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1,
                 
                 dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode,
                                            DOT_SNAP_INDEX);
+                smfs_init_snap_inode_info(dot_inode, inode, DOT_SNAP_INDEX);
                 d_add(dentry, dot_inode);
                 rc = 1;
                 RETURN(rc);
@@ -1231,7 +1246,7 @@ 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[HOOK_MAX + 1] = {
+static cow_funcs smfs_cow_pre_funcs[HOOK_MAX + 1] = {
         [HOOK_CREATE]   smfs_cow_create,
         [HOOK_LOOKUP]   smfs_cow_lookup,
         [HOOK_LINK]     smfs_cow_link,
@@ -1244,12 +1259,66 @@ static cow_funcs smfs_cow_funcs[HOOK_MAX + 1] = {
         [HOOK_SETATTR]  smfs_cow_setattr,
         [HOOK_WRITE]    smfs_cow_write,
 };
+int smfs_cow_lookup_post(struct inode *dir, struct dentry *dentry, void *data1,
+                         void *data2)
+{
+        struct inode *inode = dentry->d_inode; 
+        struct fsfilt_operations *sops = I2SNAPCOPS(inode); 
+        int index = I2SNAPI(dir)->sn_index;
+        ENTRY;
+
+        LASSERT(inode);
+      
+        if (index > 0) {
+                struct inode *cache_ind = NULL;
+
+                cache_ind = sops->fs_get_indirect(I2CI(inode), NULL, index);
+                if (cache_ind->i_ino != I2CI(inode)->i_ino) {
+                        struct inode *ind_inode = NULL;
+                        
+                        ind_inode = smfs_get_inode(dir->i_sb, cache_ind->i_ino,
+                                                   dir, index);
+                        /*replace the ind_inode here*/ 
+                        list_del_init(&dentry->d_alias);
+                        iput(inode);
+                        d_instantiate(dentry, ind_inode); 
+                }
+        }
+        inode = dentry->d_inode;
+        smfs_init_snap_inode_info(inode, dir, index);
+        
+        RETURN(0);
+}
+
+static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = {
+        [HOOK_CREATE]   NULL,
+        [HOOK_LOOKUP]   smfs_cow_lookup_post,
+        [HOOK_LINK]     NULL,
+        [HOOK_UNLINK]   NULL,
+        [HOOK_SYMLINK]  NULL,
+        [HOOK_MKDIR]    NULL,
+        [HOOK_RMDIR]    NULL, 
+        [HOOK_MKNOD]    NULL,
+        [HOOK_RENAME]   NULL,
+        [HOOK_SETATTR]  NULL,
+        [HOOK_WRITE]    NULL,
+};
+
+static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, 
+                        void *new_dentry, int op)
+{
+        if (smfs_cow_pre_funcs[op]) {
+                return smfs_cow_pre_funcs[op](dir, dentry, new_dir, new_dentry);
+        }
+        return 0;
+}
 
-int smfs_cow(struct inode *dir, struct dentry *dentry, void *new_dir, 
-             void *new_dentry, int op)
+static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir, 
+                         void *new_dentry, int op)
 {
-        if (smfs_cow_funcs[op]) {
-                return smfs_cow_funcs[op](dir, dentry, new_dir, new_dentry);
+        if (smfs_cow_post_funcs[op]) {
+                return smfs_cow_post_funcs[op](dir, dentry, new_dir, new_dentry);
         }
         return 0;
 }
index a9ead26..dfc6446 100644 (file)
@@ -322,10 +322,10 @@ do {                                                                           \
                 GOTO(label, rc);                                               \
 } while(0)                                                                     \
 
-#define SMFS_GET_INODE(sb, cache_inode, dir, index, inode, rc, label)   \
+#define SMFS_GET_INODE(sb, cache_inode, dir, inode, rc, label)          \
 do {                                                                    \
         LASSERT(cache_inode);                                           \
-        inode = smfs_get_inode(sb, cache_inode->i_ino, dir, index);     \
+        inode = smfs_get_inode(sb, cache_inode->i_ino, dir, 0);         \
         iput(cache_inode);                                              \
         if (!inode)                                                     \
                 GOTO(label, rc = -ENOENT);                              \
@@ -335,7 +335,6 @@ do {                                                                    \
 #if CONFIG_SNAPFS
 int smfs_cow_init(struct super_block *sb);
 int smfs_cow_cleanup(struct smfs_super_info *smb);
-int smfs_init_snap_inode_info(struct inode *inode, struct smfs_iget_args *args); 
 int smfs_snap_test_inode(struct inode *inode, void *args);
 #else
 #define SMFS_PRE_COW(dir, dentry, new_dir, new_dentry, op, name, rc, label)                 
index dc4809c..f0a23b5 100644 (file)
@@ -50,7 +50,6 @@ static char *smfs_options(char *data, char **devstr, char **namestr,
 {
         struct option *opt_value = NULL;
         char   *pos;
-        int    opt_len = 0;
         
         LASSERT(opts && flags);
 
index b8388f8..99e839f 100644 (file)
@@ -48,7 +48,7 @@ static int smfs_readlink(struct dentry *dentry, char *buffer, int buflen)
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
         if (cache_inode->i_op && cache_inode->i_op->readlink)
@@ -69,7 +69,7 @@ static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd)
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 GOTO(exit, rc = -ENOMEM);