Whamcloud - gitweb
1)add .snap namespace to smfs
authorwangdi <wangdi>
Wed, 11 Aug 2004 15:37:42 +0000 (15:37 +0000)
committerwangdi <wangdi>
Wed, 11 Aug 2004 15:37:42 +0000 (15:37 +0000)
2)some cleanup in smfs

22 files changed:
lustre/include/linux/lustre_fsfilt.h
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_lite.h
lustre/include/linux/lustre_smfs.h
lustre/include/linux/lustre_snap.h
lustre/include/linux/obd_class.h
lustre/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/lvfs/fsfilt_smfs.c
lustre/lvfs/fsfilt_snap_ext3.c
lustre/lvfs/fsfilt_snap_smfs.c
lustre/mdc/mdc_locks.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/mds/mds_lib.c
lustre/smfs/dir.c
lustre/smfs/file.c
lustre/smfs/smfs_cow.c
lustre/smfs/smfs_internal.h
lustre/smfs/symlink.c

index 002a3f7..5c3f9c5 100644 (file)
@@ -134,26 +134,36 @@ struct fsfilt_operations {
         int     (* fs_is_indirect)(struct inode *inode);
         
         struct inode * (* fs_create_indirect)(struct inode *pri, int index,
-                                              unsigned int gen, struct inode *parent,
+                                              unsigned int gen, 
+                                              struct inode *parent,
                                               int del);
         struct inode * (* fs_get_indirect)(struct inode *pri, int *table,
                                           int slot);
-        ino_t   (* fs_get_indirect_ino)(struct inode *pri, int index);
+        ino_t   (* fs_get_indirect_ino)(struct super_block *sb, ino_t pri, 
+                                        int index);
         int     (* fs_destroy_indirect)(struct inode *pri, int index,
                                         struct inode *next_ind);
         int     (* fs_restore_indirect)(struct inode *pri, int index);
         int     (* fs_iterate)(struct super_block *sb,
                               int (*repeat)(struct inode *inode, void *priv),
                               struct inode **start, void *priv, int flag);
-        int     (* fs_copy_block)(struct inode *dst, struct inode *src, int blk);
+        int     (* fs_copy_block)(struct inode *dst, struct inode *src, 
+                                  int blk);
         int     (* fs_set_indirect)(struct inode *pri, int index,
                                     ino_t ind_ino, ino_t parent_ino);
-        int     (* fs_snap_feature)(struct super_block *sb, int feature, int op);
-        int     (* fs_set_snap_info)(struct inode *inode, void* key, __u32 keylen, 
-                                     void *val, __u32 *vallen); 
-        int     (* fs_get_snap_info)(struct inode *inode, void* key, __u32 keylen, 
-                                     void *val, __u32 *vallen); 
+        int     (* fs_snap_feature)(struct super_block *sb, int feature, 
+                                    int op);
+        int     (* fs_set_snap_info)(struct inode *inode, void* key, 
+                                     __u32 keylen, void *val, __u32 *vallen); 
+        int     (* fs_get_snap_info)(struct inode *inode, void* key, 
+                                     __u32 keylen, void *val, __u32 *vallen); 
         int     (* fs_set_snap_item)(struct super_block *sb, char *name);
+        int     (* fs_read_dotsnap_dir_page)(struct file *file, char *buf, 
+                                             size_t count, loff_t *ppos);
+        int     (* fs_dir_ent_size)(char *name);
+        int     (* fs_set_dir_ent)(struct super_block *sb, char *name, 
+                                   char *buf, int buf_off, int nlen, 
+                                   size_t count);
 };
 
 extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops);
index 8f5bd37..a2d9215 100644 (file)
@@ -515,7 +515,8 @@ struct ll_fid {
         __u32 generation;
         __u32 f_type;
         __u32 mds;
-        __u32 padding;
+        __u16 snap_index;
+        __u16 padding;
 };
 
 struct mea_old {
index b15e74f..20547ce 100644 (file)
@@ -90,6 +90,9 @@ struct ll_inode_info {
         /* this lock protects s_d_w and p_w_ll */
         spinlock_t              lli_lock;
         int                     lli_send_done_writing;
+        
+        int                     lli_snap_index;
+        
         struct list_head        lli_pending_write_llaps;
 
         struct list_head        lli_close_item;
@@ -153,6 +156,7 @@ static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode)
         mdc_pack_fid(fid, inode->i_ino, inode->i_generation,
                      inode->i_mode & S_IFMT);
         LASSERT(ll_i2info(inode));
+        fid->snap_index = ll_i2info(inode)->lli_snap_index,
         fid->mds = ll_i2info(inode)->lli_mds;
 }
 
index 8ef548e..fd5e7f2 100644 (file)
@@ -27,8 +27,9 @@
 #define __LUSTRE_SMFS_H
 
 struct snap_inode_info {
-       int sn_flags;           /* the flags indicated inode type */
+       int sn_flags;           /*the flags indicated inode type */
        int sn_gen;             /*the inode generation*/
+        int sn_index;           /*the inode snap_index*/
 };
 struct smfs_inode_info {
         struct inode *smi_inode;
@@ -367,13 +368,54 @@ static inline void d_unalloc(struct dentry *dentry)
         dput(dentry); /* this will free the dentry memory */
 }
 
+static inline int smfs_get_dentry_name_index(struct dentry *dentry,
+                                             struct qstr  *str,
+                                             int *index)
+{
+        char *name = (char *)dentry->d_name.name;
+        unsigned long hash;
+        unsigned char c;
+        char *str_name;
+        int len = 0, name_len = 0;
+
+        name_len = dentry->d_name.len;
+        if (!name_len)
+                return 0;
+        hash = init_name_hash();
+        while (name_len--) {
+                c = *(const unsigned char *)name++;
+                if (c == ':' || c == '\0')
+                        break;
+                hash = partial_name_hash(c, hash);
+                len ++;
+        }
+        str->hash = end_name_hash(hash);
+        OBD_ALLOC(str_name, len + 1);
+        memcpy(str_name, dentry->d_name.name, len);
+        str->len = len; 
+        str->name = str_name;
+        if (index && c == ':') {
+                *index = simple_strtoul(name, 0, 0);         
+        }
+        return 0;
+}
+
+static inline void smfs_free_dentry_name(struct qstr *str)
+{
+        OBD_FREE(str->name, str->len + 1);
+}
+
 static inline struct dentry *pre_smfs_dentry(struct dentry *parent_dentry,
                                              struct inode *cache_inode,
-                                             struct dentry *dentry)
+                                             struct dentry *dentry,
+                                             int           *index)
 {
         struct dentry *cache_dentry = NULL;
-
-        cache_dentry = d_alloc(parent_dentry, &dentry->d_name);
+        struct qstr   name; 
+        
+        smfs_get_dentry_name_index(dentry, &name, index);       
+        cache_dentry = d_alloc(parent_dentry, &name);
+        smfs_free_dentry_name(&name);
         if (!cache_dentry)
                 RETURN(NULL);
         if (!parent_dentry)
@@ -451,6 +493,7 @@ static inline int smfs_do_cow(struct inode *inode)
         return 0;
 }
 
+
 /* XXX BUG 3188 -- must return to one set of opcodes */
 #define SMFS_TRANS_OP(inode, op)                \
 {                                               \
@@ -474,4 +517,8 @@ extern int smfs_rec_unpack(struct smfs_proc_args *args, char *record,
 
 extern int smfs_post_setup(struct super_block *sb, struct vfsmount *mnt);
 extern int smfs_post_cleanup(struct super_block *sb);
+extern struct inode *smfs_get_inode (struct super_block *sb, ino_t hash,
+                                     struct inode *dir, int index);
+
+extern int is_smfs_sb(struct super_block *sb);
 #endif /* _LUSTRE_SMFS_H */
index c253979..22169a7 100644 (file)
@@ -165,10 +165,11 @@ struct snap_table {
        struct  snap    sntbl_items[0];
 };
 
+#define DOT_NAME_MAX_LEN 32 
 struct snap_dot_info {
-         char *dot_name;
-         int   dot_name_len;
-         int   dot_snap_enable;
+        char    *dot_name;
+        int     dot_name_len;
+        int     dot_snap_enable; 
 };
 
 struct snap_info {
@@ -180,7 +181,6 @@ struct snap_info {
         struct snap_table        *sntbl;
         struct dentry            *sn_cowed_dentry;
         struct snap_dot_info     *sn_dot_info;
-
 };
 
 extern int smfs_add_snap_item(struct super_block *sb, char *name);
@@ -196,4 +196,35 @@ int smfs_cow(struct inode *dir, struct dentry *dentry,
 int smfs_cow_write(struct inode *inode, struct dentry *dentry, void *data1,
                    void *data2);
 struct inode* smfs_cow_get_ind(struct inode *inode, int index);
+
+
+#define DOT_SNAP_NAME          ".snap"
+#define DOT_SNAP_INDEX         0xffff
+static inline int smfs_primary_inode(struct inode *inode)
+{
+        struct snap_inode_info *sn_info = &I2SMI(inode)->sm_sninfo;
+
+        if (sn_info->sn_index == 0)
+                return 1; 
+        return 0; 
+}
+static inline int smfs_dotsnap_inode(struct inode *inode)
+{
+        struct snap_inode_info *sn_info = &I2SMI(inode)->sm_sninfo;
+
+        if (sn_info->sn_index == DOT_SNAP_INDEX)
+                return 1; 
+        return 0; 
+}
+static inline int smfs_under_dotsnap_inode(struct inode *inode)
+{
+        struct snap_inode_info *sn_info = &I2SMI(inode)->sm_sninfo;
+        
+        if (sn_info->sn_index > 0 && sn_info->sn_index != DOT_SNAP_INDEX)
+                return 1;
+        return 0; 
+}
+
+
+
 #endif /*_LUSTRE_SNAP_H*/
index 6b617e0..88f16ff 100644 (file)
@@ -1154,7 +1154,6 @@ static inline int obd_init_ea_size(struct obd_export *exp, int size, int size2)
         rc = OBP(exp->exp_obd, init_ea_size)(exp, size, size2);
         RETURN(rc);
 }
-
 static inline int md_getstatus(struct obd_export *exp, struct ll_fid *fid)
 {
         int rc;
index 0943c38..2afe0a6 100644 (file)
@@ -50,6 +50,8 @@
 #include <linux/lustre_mds.h>
 #include <linux/lustre_lite.h>
 #include <linux/lustre_dlm.h>
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
 #include "llite_internal.h"
 
 typedef struct ext2_dir_entry_2 ext2_dirent;
@@ -347,12 +349,27 @@ int ll_readdir(struct file * filp, void * dirent, filldir_t filldir)
                         if (de->inode) {
                                 int over;
                                 unsigned char d_type = DT_UNKNOWN;
-
+                                
+                                
                                 rc = 0; /* no error if we return something */
                                 if (types && de->file_type < EXT2_FT_MAX)
                                         d_type = types[de->file_type];
 
                                 offset = (char *)de - kaddr;
+#ifdef CONFIG_SNAPFS                               
+                                /*FIXME-WANGDI will get dot info from MDS*/ 
+                                if ((n << PAGE_CACHE_SHIFT | offset)  == 0) {
+                                        int off =n << PAGE_CACHE_SHIFT | offset;
+                                        over = filldir(dirent, DOT_SNAP_NAME,
+                                                       strlen(DOT_SNAP_NAME), 
+                                                       off, -1, 0); 
+                                        if (over) {
+                                                ext2_put_page(page);
+                                                GOTO(done, rc);        
+                                        }
+                                }  
+                                offset+=EXT2_DIR_REC_LEN(strlen(DOT_SNAP_NAME));     
+#endif                   
                                 over = filldir(dirent, de->name, de->name_len,
                                                (n<<PAGE_CACHE_SHIFT) | offset,
                                                le32_to_cpu(de->inode), d_type);
index da6bb98..dc21e21 100644 (file)
@@ -52,6 +52,7 @@ struct ll_sb_info {
         int                       ll_gns_state;
         struct timer_list         ll_gns_timer;
         struct list_head          ll_gns_sbi_head;
+        void                     *ll_dot_snap_info; 
 };
 
 #define LL_GNS_STATE_IDLE     1100
index 906e978..00b305a 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/lustre_ha.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lprocfs_status.h>
+#include <linux/lustre_smfs.h>
 #include <linux/lustre_snap.h>
 #include "llite_internal.h"
 
@@ -180,7 +181,6 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc)
         sbi->ll_osc_exp = class_conn2export(&osc_conn);
 
         lustre_init_ea_size(sbi);
-
         err = md_getstatus(sbi->ll_mdc_exp, &rootfid);
         if (err) {
                 CERROR("cannot mds_connect: rc = %d\n", err);
@@ -1256,7 +1256,8 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
 
         if (body->valid & OBD_MD_FLSIZE)
                 set_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags);
-
+        
+        lli->lli_snap_index = body->fid1.snap_index;
         lli->lli_mds = body->mds;
         inode->i_dev = (kdev_t) body->mds;
         LASSERT(body->mds < 1000);
index 6761a83..a16814b 100644 (file)
@@ -87,7 +87,10 @@ static int ll_test_inode(struct inode *inode, void *opaque)
 
         if (ll_i2info(inode)->lli_mds != md->body->mds)
                 return 0;
-
+#ifdef CONFIG_SNAPFS
+        if (ll_i2info(inode)->lli_snap_index != md->body->fid1.snap_index)
+                return 0;
+#endif
         /* Apply the attributes in 'opaque' to this inode */
         ll_update_inode(inode, md);
         return 1;
index 7e4e96b..23267a8 100644 (file)
@@ -76,7 +76,8 @@ 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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry, 
+                                       NULL);
 
         if (!cache_dentry)
                 GOTO(exit, rc = ERR_PTR(-ENOMEM));
@@ -170,7 +171,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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         if (!cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -395,11 +396,28 @@ static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
         *cache_ppos = *off;
 
         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
-
+#if CONFIG_SNAPFS
+        /*readdir page*/
+        if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
+                struct fsfilt_operations *snapops = 
+                                        I2SNAPOPS(file->f_dentry->d_inode);
+                
+                LASSERT(S_ISDIR(file->f_dentry->d_inode->i_mode));
+                
+                rc = snapops->fs_read_dotsnap_dir_page(sfi->c_file, buf, count, 
+                                                       cache_ppos); 
+                
+        } else {
+                if (cache_fsfilt->fs_readpage)
+                        rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
+                                                       cache_ppos);
+        }
+#else
         if (cache_fsfilt->fs_readpage)
                 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
                                                cache_ppos);
 
+#endif
         *off = *cache_ppos;
         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
         duplicate_file(file, sfi->c_file);
index 29f7c0d..fdb3ec5 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/iobuf.h>
 #endif
+#include <linux/lustre_smfs.h>
 #include <linux/lustre_snap.h>
 
 /* For snapfs in EXT3 flags --- FIXME will find other ways to store it*/
@@ -857,16 +858,24 @@ static int fsfilt_ext3_is_indirect(struct inode *inode)
  * return value:        postive:        indirect ino number
  *                      negative or 0:  error
  */
-static ino_t fsfilt_ext3_get_indirect_ino(struct inode *primary, int index)
+static ino_t fsfilt_ext3_get_indirect_ino(struct super_block *sb, 
+                                          ino_t primary_ino, int index)
 {
         char buf[EXT3_MAX_SNAP_DATA];
+        struct inode *primary = NULL;
         struct snap_ea *snaps;
         ino_t ino = 0;
         int err;
         ENTRY;                                                                                                                                                                                             
         if (index < 0 || index > EXT3_MAX_SNAPS || !primary)
                 RETURN(0);
-                                                                                                                                                                                                     
+        primary = iget(sb, primary_ino);   
+       
+        if (!primary) {
+                err = -EIO;
+                CERROR("attribute read error=%d", err);
+                GOTO (err_free, ino = err); 
+        }                                                                                                                                                                                              
         err = ext3_xattr_get(primary, EXT3_SNAP_INDEX, EXT3_SNAP_ATTR,
                              buf, EXT3_MAX_SNAP_DATA);
         if (err == -ENOATTR) {
@@ -880,6 +889,8 @@ static ino_t fsfilt_ext3_get_indirect_ino(struct inode *primary, int index)
         CDEBUG(D_INODE, "snap ino for %ld at index %d is %lu\n",
                primary->i_ino, index, ino);
 err_free:
+        if (primary)
+                iput(primary); 
         RETURN(ino);
 }
                                                                                                                                                                                                      
@@ -1555,7 +1566,44 @@ static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key,
         }
         RETURN(-EINVAL);
 }
+static int fsfilt_ext3_dir_ent_size(char *name)
+{
+        if (name) {
+                return EXT3_DIR_REC_LEN(strlen(name));
+        }
+        return 0;
+}
 
+static int fsfilt_ext3_set_dir_ent(struct super_block *sb, char *name, 
+                                   char *buf, int buf_off, int nlen, size_t count)
+{
+        int rc = 0; 
+        ENTRY;
+        if (buf_off == 0 && nlen == 0) {
+                struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *)buf;  
+                LASSERT(count == PAGE_CACHE_SIZE);
+                de->rec_len = count;
+                de->inode = 0;
+                RETURN(rc);
+        } else {
+                struct ext3_dir_entry_2 *de, *de1; 
+                de = (struct ext3_dir_entry_2 *)(buf + buf_off - nlen); 
+                de1 = (struct ext3_dir_entry_2 *)(buf + buf_off); 
+                int rlen, nlen;
+                LASSERT(nlen == EXT3_DIR_REC_LEN_DE(de));
+                
+                rlen = le16_to_cpu(de->rec_len);
+                de->rec_len = cpu_to_le16(nlen);
+                
+                de1->rec_len = cpu_to_le16(rlen - nlen);
+                de1->name_len = strlen(name);
+                memcpy (de1->name, name, de->name_len);
+                nlen = EXT3_DIR_REC_LEN_DE(de1); 
+                RETURN(nlen);
+        }        
+
+}
 struct fsfilt_operations fsfilt_ext3_snap_ops = {
         .fs_type                = "ext3_snap",
         .fs_owner               = THIS_MODULE,
@@ -1572,8 +1620,11 @@ struct fsfilt_operations fsfilt_ext3_snap_ops = {
         .fs_copy_block          = fsfilt_ext3_copy_block,
         .fs_set_snap_info       = fsfilt_ext3_set_snap_info,
         .fs_get_snap_info       = fsfilt_ext3_get_snap_info,
+        .fs_dir_ent_size        = fsfilt_ext3_dir_ent_size,
+        .fs_set_dir_ent         = fsfilt_ext3_set_dir_ent,
 };
 
+
 static int __init fsfilt_ext3_snap_init(void)
 {
         int rc;
index 9f5b75e..640d288 100644 (file)
@@ -105,7 +105,8 @@ static struct inode*  fsfilt_smfs_get_indirect(struct inode *inode,
       
         if (cache_ind_inode && !IS_ERR(cache_ind_inode)){ 
                 /*FIXME: get indirect inode set_cow flags*/ 
-                ind_inode = iget4(inode->i_sb, cache_ind_inode->i_ino, NULL, 0);
+                ind_inode = smfs_get_inode(inode->i_sb, cache_ind_inode->i_ino,
+                                           inode, slot);
         }    
         RETURN(ind_inode);
 }
@@ -194,25 +195,20 @@ static int fsfilt_smfs_is_indirect(struct inode *inode)
         
         RETURN(rc);
 }
-static ino_t fsfilt_smfs_get_indirect_ino(struct inode *inode, int index)
+static ino_t fsfilt_smfs_get_indirect_ino(struct super_block *sb, ino_t ino, 
+                                          int index)
 {
-        struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
-        struct inode *cache_inode = NULL;
+        struct fsfilt_operations *snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt;
+        struct super_block       *csb = S2CSB(sb);
         int    rc = -EIO;
         ENTRY;
 
         if (snap_fsfilt == NULL)
                 RETURN(rc);
 
-        cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(rc);
-
-        pre_smfs_inode(inode, cache_inode);
         if (snap_fsfilt->fs_get_indirect_ino)
-                rc = snap_fsfilt->fs_get_indirect_ino(cache_inode, index);
-        post_smfs_inode(inode, cache_inode);
-        
+                rc = snap_fsfilt->fs_get_indirect_ino(csb, ino, index);
+         
         RETURN(rc);
 }
 
@@ -368,6 +364,40 @@ static int fsfilt_smfs_get_snap_info(struct inode *inode, void *key,
         
         RETURN(rc);
 }
+
+static int fsfilt_smfs_read_dotsnap_dir_page(struct file *file, char *buf,
+                                             size_t count, loff_t *off)
+{
+        struct inode *inode = file->f_dentry->d_inode;
+        struct fsfilt_operations *snap_cops = I2SNAPCOPS(inode);
+        struct snap_table *stbl = S2SNAPI(inode->i_sb)->sntbl;
+        int    i = 0, size = 0, off_count = 0, buf_off = 0, rc = 0;
+        ENTRY;
+
+        /*Get the offset of dir ent*/
+        while (size < *off && off_count < stbl->sntbl_count) {
+                char *name = stbl->sntbl_items[i].sn_name;
+                size +=snap_cops->fs_dir_ent_size(name);
+                off_count ++;
+        }
+        for (i = off_count; i < stbl->sntbl_count; i++) {
+                char *name = stbl->sntbl_items[i].sn_name;
+                rc = snap_cops->fs_set_dir_ent(inode->i_sb, name, buf, buf_off, 
+                                               rc, count);
+                if (rc < 0)
+                        break;
+
+                buf_off += rc;
+
+                if (buf_off >= count) 
+                        break;
+        }
+        if (rc > 0) 
+                rc = 0; 
+
+        RETURN(rc); 
+}
+
 struct fsfilt_operations fsfilt_smfs_snap_ops = {
         .fs_type                = "smfs_snap",
         .fs_owner               = THIS_MODULE,
@@ -384,6 +414,7 @@ struct fsfilt_operations fsfilt_smfs_snap_ops = {
         .fs_copy_block          = fsfilt_smfs_copy_block,
         .fs_set_snap_info       = fsfilt_smfs_set_snap_info,
         .fs_get_snap_info       = fsfilt_smfs_get_snap_info,
+        .fs_read_dotsnap_dir_page = fsfilt_smfs_read_dotsnap_dir_page,
 };
 
 
index ae07c91..09a709c 100644 (file)
@@ -36,7 +36,8 @@
 #include <linux/obd_class.h>
 #include <linux/lustre_mds.h>
 #include <linux/lustre_dlm.h>
-#include <linux/lustre_snap.h>
+//#include <linux/lustre_smfs.h>
+//#include <linux/lustre_snap.h>
 #include <linux/lprocfs_status.h>
 #include "mdc_internal.h"
 
@@ -174,23 +175,6 @@ int mdc_change_cbdata(struct obd_export *exp, struct ll_fid *fid,
         return 0;
 }
 
-#if CONFIG_SNAPFS
-int mdc_set_clone_info(struct obd_export *exp, struct lustre_msg *msg, 
-                       int offset)
-{
-        struct client_obd *cli_obd = &exp->exp_obd->u.cli;
-        struct clonefs_info *cl_info;
-        ENTRY;
-        
-        if (cli_obd->cl_clone_info) { 
-                cl_info = (struct clonefs_info *)lustre_msg_buf(msg, offset, 
-                                                                 sizeof (*cl_info));
-                memcpy(cl_info, cli_obd->cl_clone_info, sizeof(*cl_info));
-        }
-        RETURN(0);        
-} 
-#endif
-
 /* We always reserve enough space in the reply packet for a stripe MD, because
  * we don't know in advance the file type. */
 int mdc_enqueue(struct obd_export *exp,
@@ -260,15 +244,9 @@ int mdc_enqueue(struct obd_export *exp,
 
                 if (it->it_op & IT_GETATTR)
                         policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
-#if CONFIG_SNAPFS                
-                size[4] = sizeof(struct clonefs_info); 
-                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 5,
-                                      size, NULL);
-#else
                 req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 4,
                                       size, NULL);
 
-#endif
                 if (!req)
                         RETURN(-ENOMEM);
 
@@ -278,9 +256,6 @@ int mdc_enqueue(struct obd_export *exp,
 
                 /* pack the intended request */
                 mdc_getattr_pack(req->rq_reqmsg, valid, 2, it->it_flags, data);
-#if CONFIG_SNAPFS               
-                mdc_set_clone_info(exp, req->rq_reqmsg, 4); 
-#endif                 
                 /* get ready for the reply */
                 reply_buffers = 3;
                 req->rq_replen = lustre_msg_size(3, repsize);
index 55ec795..7c29799 100644 (file)
@@ -1244,7 +1244,6 @@ struct obd_ops mdc_obd_ops = {
         .o_connect       = client_connect_import,
         .o_disconnect    = client_disconnect_export,
         .o_iocontrol     = mdc_iocontrol,
-        .o_set_info      = mdc_set_info,
         .o_statfs        = mdc_statfs,
         .o_pin           = mdc_pin,
         .o_unpin         = mdc_unpin,
index 27bb918..5bd0496 100644 (file)
 #include <linux/obd_ost.h>
 #include <linux/lustre_mds.h>
 #include <linux/lustre_fsfilt.h>
-#include <linux/lustre_snap.h>
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_commit_confd.h>
 
+#ifdef CONFIG_SNAPFS
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
+#endif
 #include "mds_internal.h"
 
 static int mds_intent_policy(struct ldlm_namespace *ns,
@@ -295,8 +298,17 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid,
 
         if (ino == 0)
                 RETURN(ERR_PTR(-ESTALE));
-
+       
+#ifdef CONFIG_SNAPFS
+        if (is_smfs_sb(mds->mds_sb)) {
+                snprintf(fid_name, sizeof(fid_name), "0x%lx:%lx", ino, 
+                         fid->snap_index);
+        } else {
+                snprintf(fid_name, sizeof(fid_name), "0x%lx", ino);
+        }
+#else
         snprintf(fid_name, sizeof(fid_name), "0x%lx", ino);
+#endif 
 
         CDEBUG(D_DENTRY, "--> mds_fid2dentry: ino/gen %lu/%u, sb %p\n",
                ino, generation, mds->mds_sb);
@@ -883,14 +895,6 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
                 CERROR("Can't unpack name\n");
                 GOTO(cleanup, rc = -EFAULT);
         }
-#if CONFIG_SNAPFS
-        clone_info = lustre_swab_reqbuf(req, offset + 2, sizeof(*clone_info), 
-                                        lustre_swab_clonefs_info);
-        if (clone_info) {
-                CDEBUG(D_INFO,"getattr name %s clone_info index %d \n", name,
-                       clone_info->clone_index);
-        }
-#endif
         namesize = req->rq_reqmsg->buflens[offset + 1];
 
         LASSERT (offset == 0 || offset == 2);
index ced2a70..81107a1 100644 (file)
@@ -49,6 +49,9 @@
 #include <linux/lustre_lib.h>
 #include <linux/lustre_mds.h>
 
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
+
 void mds_pack_dentry2fid(struct ll_fid *fid, struct dentry *dentry)
 {
         fid->id = dentry->d_inum;
@@ -67,6 +70,12 @@ void mds_pack_dentry2body(struct mds_body *b, struct dentry *dentry)
 void mds_pack_inode2fid(struct obd_device *obd, struct ll_fid *fid,
                                 struct inode *inode)
 {
+#ifdef CONFIG_SNAPFS
+        if (is_smfs_sb(inode->i_sb)) {
+                struct smfs_inode_info *sm_info = I2SMI(inode);
+                fid->snap_index = sm_info->sm_sninfo.sn_index;
+        }
+#endif
         fid->id = inode->i_ino;
         fid->generation = inode->i_generation;
         fid->f_type = (S_IFMT & inode->i_mode);
index 0c07e7c..f954063 100644 (file)
@@ -34,8 +34,8 @@
 #include <linux/lustre_lib.h>
 #include <linux/lustre_idl.h>
 #include <linux/lustre_fsfilt.h>
-#include <linux/lustre_snap.h>
 #include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
 
 #include "smfs_internal.h"
 
@@ -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);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
 
         if (!cache_dentry || !cache_parent)
                 GOTO(exit, rc = -ENOMEM);
@@ -87,9 +87,8 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
 #endif
         if (rc)
                 GOTO(exit, rc);
-
-        inode = iget4(dir->i_sb, cache_dentry->d_inode->i_ino, NULL,
-                      &I2SMI(dir)->smi_flags);
+        
+        inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino, dir, 0);
         if (!inode)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -120,21 +119,16 @@ 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;
+        int rc2 = 0, index = 0;
 
         ENTRY;
 
         if (!(cache_dir = I2CI(dir)))
                 RETURN(ERR_PTR(-ENOENT));
 
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, PRE_HOOK, rc2, 
-                  exit); 
-        if (rc2)
-                RETURN(ERR_PTR(rc2));
-
         /* preparing artificial backing fs dentries. */
-        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, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, &index);
 
         if (!cache_dentry || !cache_parent)
                 GOTO(exit, rc = ERR_PTR(-ENOMEM));
@@ -142,13 +136,15 @@ 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, 
+                  PRE_HOOK, 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);
 #else
         rc = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
 #endif
-
         if (rc && IS_ERR(rc))
                 GOTO(exit, rc);
         
@@ -157,8 +153,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
                         dentry->d_inode = cache_inode;
                         GOTO(exit, rc = NULL);
                 }
-                inode = iget4(dir->i_sb, cache_inode->i_ino, NULL,
-                                    &I2SMI(dir)->smi_flags);
+                inode = smfs_get_inode(dir->i_sb, cache_inode->i_ino, dir, index);
         } else {
                 d_add(dentry, NULL);
                 GOTO(exit, rc);
@@ -170,7 +165,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, POST_HOOK, rc2, 
                   exit); 
 exit:
-        if (rc2)
+        if (rc2 < 0)
                 rc = ERR_PTR(rc2);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
@@ -202,14 +197,14 @@ 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);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
         cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode,
-                                           old_dentry);
+                                           old_dentry, NULL);
         if (!cache_old_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -260,8 +255,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);
-        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry, NULL);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
@@ -305,8 +300,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);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
@@ -315,8 +310,8 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
         if (cache_dir->i_op->symlink)
                 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
 
-        inode = iget4(dir->i_sb, cache_dentry->d_inode->i_ino, NULL,
-                      &I2SMI(dir)->smi_flags);
+
+        inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino, dir, 0);
         post_smfs_inode(dir, cache_dir);
         if (inode)
                 d_instantiate(dentry, inode);
@@ -357,8 +352,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);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
@@ -370,9 +365,9 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
 
         if (rc)
                 GOTO(exit, rc);
+  
+        inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino, dir, 0);
 
-        inode = iget4(dir->i_sb, cache_dentry->d_inode->i_ino, NULL,
-                      &I2SMI(dir)->smi_flags);
         if (!inode)
                 GOTO(exit, rc = -ENOENT);
 
@@ -412,8 +407,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);
-        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry, NULL);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
@@ -464,8 +459,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);
-        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+        cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent, NULL);
+        cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL);
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -479,8 +474,8 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry,
                                          mode, rdev)))
                 GOTO(exit, rc);
 
-        inode = iget4(dir->i_sb, cache_dentry->d_inode->i_ino, NULL,
-                      &I2SMI(dir)->smi_flags);
+        inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino, dir, 0);
+
         d_instantiate(dentry, inode);
 
         pre_smfs_inode(dir, cache_dir);
@@ -528,15 +523,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);
+        cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry, NULL);
         cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
-                                           old_dentry);
+                                           old_dentry, NULL);
         if (!cache_old_parent || !cache_old_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
-        cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry);
+        cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry, NULL);
         cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
-                                           new_dentry);
+                                           new_dentry, NULL);
         if (!cache_new_parent || !cache_new_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
index 45602dd..37e9d63 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);
+        cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
 
index f6655bc..8282a82 100644 (file)
@@ -36,8 +36,8 @@
 #include <linux/lustre_idl.h>
 #include <linux/lustre_fsfilt.h>
 
-#include <linux/lustre_snap.h>
 #include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
 
 #include "smfs_internal.h"
 #define SNAPTABLE_SIZE(size) (sizeof(struct snap_table) + size * sizeof(struct snap)) 
@@ -123,7 +123,6 @@ 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);
@@ -315,27 +314,62 @@ int smfs_cow_cleanup(struct super_block *sb)
         RETURN(0);
 }
 
+static int smfs_dotsnap_dir_size(struct inode *inode)
+{
+        struct snap_info *snap_info = S2SNAPI(inode->i_sb);
+        struct fsfilt_operations *snapops = snap_info->snap_cache_fsfilt; 
+        struct snap_table *stbl = snap_info->sntbl;
+        int size = 0, dir_size = 0, blocks;
+        int i = 0;
+        ENTRY;
+
+        for (i = 0; i < stbl->sntbl_count; i++) {
+                size += snapops->fs_dir_ent_size(stbl->sntbl_items[i].sn_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); 
+
+} 
 /*FIXME Note indirect and primary inode 
 * should be recorgnized here*/
-int smfs_init_snap_inode_info(struct inode *inode, int flags)
+int smfs_init_snap_inode_info(struct inode *inode, 
+                              struct snap_inode_info *sn_info) 
 {
+        struct smfs_inode_info *smi = I2SMI(inode);
         int vallen, rc = 0;
         ENTRY;
 
-        if (SMFS_DO_COW(S2SMI(inode->i_sb)) &&
-            (flags & SM_DO_COW)) {
+        LASSERT(sn_info && smi);
+        smi->sm_sninfo.sn_flags = sn_info->sn_flags;
+        smi->sm_sninfo.sn_gen = sn_info->sn_gen;
+        smi->sm_sninfo.sn_index = sn_info->sn_index; 
+
+        if (smfs_dotsnap_inode(inode)) {
+                struct snap_table *stbl= S2SNAPI(inode->i_sb)->sntbl;
+                int size = 0;
+                /*init dot_snap inode info*/
+                size = smfs_dotsnap_dir_size(inode); 
+                inode->i_size = (loff_t)size;                   
+                inode->i_nlink = stbl->sntbl_count + 2;
+                inode->i_uid = 0;
+                inode->i_gid = 0;
+        } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) && 
+                   (smi->smi_flags & SM_DO_COW) &&
+                   smfs_primary_inode(inode)) {
                 struct snap_inode_info *sni_info = I2SNAPI(inode);
                 struct fsfilt_operations *snapops = I2SNAPOPS(inode);
                 
-                sni_info->sn_flags = flags;
                 vallen = sizeof(sni_info->sn_gen);
-
+                
                 rc = snapops->fs_get_snap_info(inode, SNAP_GENERATION,
                                                strlen(SNAP_GENERATION),
                                                &sni_info->sn_gen, &vallen);               
         } 
         RETURN(rc);                                              
-         
 }
 /* latest snap: returns 
    -  the index of the latest snapshot before NOW
@@ -490,7 +524,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);
+        tmp = pre_smfs_dentry(NULL, inode, cowed_dir, NULL);
         /* 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;
@@ -533,7 +567,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%u\n",
+                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(ind));
                RETURN(PTR_ERR(ind));
@@ -547,6 +581,7 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
                 
                 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);
         }
@@ -751,58 +786,103 @@ exit:
         RETURN(rc);
 }
 EXPORT_SYMBOL(smfs_cow_write);
-
+/*lookup inode in dotsnap inode */
+static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry)
+{ 
+        if (dentry->d_name.len == 1 && 
+            !strcmp(dentry->d_name.name, ".")) {
+                d_add(dentry, iget(dir->i_sb, dir->i_ino));
+        } else if (dentry->d_name.len == 2 && 
+                   !strcmp(dentry->d_name.name, "..")) {
+                struct inode *inode;
+                struct dentry *dparent = dentry->d_parent;                                                                                                                                                                                       
+                if (dparent->d_inode) {
+                        inode = iget(dir->i_sb, dparent->d_inode->i_ino);
+                        if (inode) {
+                                if (!is_bad_inode(inode))
+                                        d_add(dentry, inode);
+                                else
+                                        iput(inode);
+                        }
+                }
+        } else {
+                /*find the name from the snaptable*/
+                struct fsfilt_operations *snapops = I2SNAPOPS(dir);
+                struct snap_table *table = S2SNAPI(dir->i_sb)->sntbl; 
+                struct inode *inode;
+                int i = 0, index = -1;
+                for (i = 0; i < table->sntbl_count; i++) {
+                        char *name = table->sntbl_items[i].sn_name;
+                        if ((dentry->d_name.len == strlen(name)) &&
+                            (memcmp(dentry->d_name.name, name,
+                                    dentry->d_name.len) == 0)) {
+                                index = table->sntbl_items[i].sn_index;
+                                break;
+                        }
+                }
+                if (index != -1) {
+                       CERROR("No such %s in this .snap dir \n", 
+                               dentry->d_name.name);
+                       RETURN(-ENOENT);
+                }
+                inode = snapops->fs_get_indirect(dir, NULL, index);
+                d_add(dentry, inode);
+        } 
+        RETURN(0);
+}
 int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1,
                     void *data2)
 {
         struct snap_info *snap_info = S2SNAPI(inode->i_sb);
-        struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
-        struct dentry *dparent = dentry->d_parent;
-        struct clonefs_info *clone_info=(struct clonefs_info*)dparent->d_fsdata;
-        int rc = 0;
-        if (clone_info && clone_info->clone_flags && SM_CLONE_FS) {
-                struct inode *ind_inode = NULL;
-                struct inode *cache_ind = NULL;
-                struct dentry *cache_dentry = NULL;
-                struct dentry *cache_parent = NULL;
-                struct inode *cache_inode;
-                struct dentry *tmp;
-                rc = 1;
-                ind_inode = snapops->fs_get_indirect(inode, NULL, clone_info->clone_index);
-                if (!ind_inode) 
-                        RETURN(-ENOENT);
-                
-                if (!(cache_ind = I2CI(ind_inode)))
-                        GOTO(exit, rc = -ENOENT);
-
-                cache_parent=pre_smfs_dentry(NULL, cache_ind, dentry->d_parent);
-                cache_dentry=pre_smfs_dentry(cache_parent, NULL, dentry);
+        struct snap_dot_info *dot_info = snap_info->sn_dot_info;
+        int rc = 0, index = 0;
+        ENTRY;
 
-                tmp = cache_ind->i_op->lookup(cache_ind, cache_dentry);
+        LASSERT(dot_info != NULL); 
+        LASSERT(data1 != NULL); 
         
-                if (IS_ERR(tmp))
-                        GOTO(exit, rc = -ENOENT);
-
-                if ((cache_inode = tmp ? tmp->d_inode : cache_dentry->d_inode)) {
-                        if (IS_ERR(cache_inode)) {
-                                dentry->d_inode = cache_inode;
-                                GOTO(exit, rc = -ENOENT);
-                        }
-                        inode = iget4(inode->i_sb, cache_inode->i_ino, NULL,
-                                      &I2SMI(inode)->smi_flags);
-                } else {
-                        d_add(dentry, NULL);
-                        GOTO(exit, rc = -ENOENT);
-                }
-                d_add(dentry, inode);
-exit:
-                iput(ind_inode);
-                post_smfs_dentry(cache_dentry);
-                post_smfs_dentry(cache_parent);
+        index = *(int *)data1; 
+        if (smfs_primary_inode(inode) && 
+            dentry->d_name.len == dot_info->dot_name_len &&
+            memcmp(dentry->d_name.name, dot_info->dot_name, 
+                   strlen(dot_info->dot_name)) == 0) {
+                struct inode *dot_inode = NULL; 
+                
+                dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode,
+                                           DOT_SNAP_INDEX);
+                d_add(dentry, dot_inode);
+                rc = 1;
                 RETURN(rc);
+        }
+        if (smfs_dotsnap_inode(inode)) {
+                rc = smfs_dotsnap_lookup(inode, dentry);
+                if (rc == 0)
+                        rc = 1;
+                RETURN(rc);                
         } 
+        if (index > 0) {
+                /*HERE: will replace ino in dentry->d_name according to index*/ 
+                struct fsfilt_operations *snapops = I2SNAPOPS(inode);
+                char *name = (char *)dentry->d_name.name;
+                unsigned long ino, hash, ind_ino; 
+                int len = sizeof(ind_ino);
+                 
+                ino = simple_strtoul(name, 0, 0);         
+
+                ind_ino = snapops->fs_get_indirect_ino(inode->i_sb, ino, index);
+                
+                snprintf(name, strlen(name), "0x%lx", ind_ino);                 
+                
+                hash = init_name_hash();
+                while (len--) {
+                        unsigned char c; 
+                        c = *(const unsigned char *)name++;
+                        if (c == '\0') break;
+                        hash = partial_name_hash(c, hash);
+                }
+                dentry->d_name.hash = end_name_hash(hash);
+        }        
         RETURN(rc);         
 }
 
index 51f593b..7efefbd 100644 (file)
@@ -157,6 +157,8 @@ extern int smfs_removexattr(struct dentry *dentry, const char *name);
 extern int smfs_open(struct inode * inode, struct file * filp);
 extern int smfs_release(struct inode * inode, struct file * filp);
 /*inode.c*/
+struct inode *smfs_get_inode(struct super_block *sb, ino_t hash, 
+                             struct inode *dir, int index);
 extern struct super_operations smfs_super_ops;
 /*symlink.c*/
 extern struct inode_operations smfs_sym_iops;
@@ -316,7 +318,8 @@ do {                                                                           \
 #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);
+extern int smfs_init_snap_inode_info(struct inode *inode, 
+                                     struct snap_inode_info *sn_info); 
 #else
 #define SMFS_PRE_COW(dir, dentry, new_dir, new_dentry, op, name, rc, label)                 
 #endif 
index 99e839f..b8388f8 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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         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);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL);
         if (!cache_dentry)
                 GOTO(exit, rc = -ENOMEM);