Whamcloud - gitweb
- fixes in fsfilt interface about 2.6/2.4 versions of kernel. Fixes in ext3 implement...
[fs/lustre-release.git] / lustre / lvfs / fsfilt_snap_ext3.c
index cbecc3d..4a8e006 100644 (file)
 
 #define EXT3_SNAP_ATTR "@snap"
 #define EXT3_SNAP_GENERATION "@snap_generation"
-#define EXT3_MAX_SNAPS 20
+#define EXT3_MAX_SNAPS 10
 #define EXT3_MAX_SNAP_DATA (sizeof(struct snap_ea))
 #define EXT3_SNAP_INDEX EXT3_XATTR_INDEX_LUSTRE
+#define EXT3_SNAP_COUNT "@snapcount"
+#define EXT3_SNAP_ROOT_INO "@snap_rootino"
 
-#define SB_SNAPTABLE_INO(sb)   (EXT3_SB(sb)->s_es->s_snaptable_ino)
 #define SB_FEATURE_COMPAT(sb)  (EXT3_SB(sb)->s_es->s_feature_compat)
                                                                                                                                                                                                      
 #define SNAP_HAS_COMPAT_FEATURE(sb,mask)        \
 #define SNAP_EA_INO_BLOCK_SIZE(size)   (((size)-sizeof(ino_t)*2)/2)
 #define SNAP_EA_PARENT_OFFSET(size)    (sizeof(ino_t)*2 + SNAP_EA_INO_BLOCK_SIZE((size)))
 
+#define EXT3_EA_TRANS_BLOCKS            EXT3_DATA_TRANS_BLOCKS
+#define EXT3_SETMETA_TRANS_BLOCKS       EXT3_DATA_TRANS_BLOCKS
+#define EXT3_NEWINODE_TRANS_BLOCKS      10
+
+#define SNAP_COPYBLOCK_TRANS_BLOCKS    (EXT3_DATA_TRANS_BLOCKS)
+#define SNAP_INSERTLIST_TRANS_BLOCKS    (2 * EXT3_EA_TRANS_BLOCKS + 1)
+#define SNAP_DELETELIST_TRANS_BLOCKS    (2 * EXT3_EA_TRANS_BLOCKS + 2)
+#define SNAP_MIGRATEDATA_TRANS_BLOCKS   2
+#define SNAP_SETIND_TRANS_BLOCKS        (SNAP_INSERTLIST_TRANS_BLOCKS + 1)
+#define SNAP_ADDORPHAN_TRANS_BLOCKS     2
+#define SNAP_REMOVEORPHAN_TRANS_BLOCKS  1
+#define SNAP_RESTOREORPHAN_TRANS_BLOCKS (EXT3_EA_TRANS_BLOCKS + \
+                                         SNAP_DELETELIST_TRANS_BLOCKS + \
+                                         EXT3_NEWINODE_TRANS_BLOCKS + \
+                                         2 * SNAP_MIGRATEDATA_TRANS_BLOCKS)
+#define SNAP_BIGCOPY_TRANS_BLOCKS       (2 * EXT3_DATA_TRANS_BLOCKS)
+#define SNAP_CREATEIND_TRANS_BLOCKS     (EXT3_NEWINODE_TRANS_BLOCKS + \
+                                         SNAP_MIGRATEDATA_TRANS_BLOCKS + \
+                                         SNAP_SETIND_TRANS_BLOCKS + \
+                                         SNAP_BIGCOPY_TRANS_BLOCKS + 3)
+#define SNAP_MIGRATEBLK_TRANS_BLOCKS    2
+#define SNAP_DESTROY_TRANS_BLOCKS       (SNAP_DELETELIST_TRANS_BLOCKS + \
+                                         EXT3_EA_TRANS_BLOCKS + 2)
+#define SNAP_RESTORE_TRANS_BLOCKS       (EXT3_NEWINODE_TRANS_BLOCKS + \
+                                         2 * SNAP_MIGRATEDATA_TRANS_BLOCKS + 1)
+
 #define EXT3_JOURNAL_START(sb, handle, blocks, rc)              \
 do {                                                            \
         journal_t *journal;                                     \
         journal = EXT3_SB(sb)->s_journal;                       \
         lock_kernel();                                          \
-        handle = journal_start(journal, 1);                     \
+        handle = journal_start(journal, blocks);                \
         unlock_kernel();                                        \
         if(IS_ERR(handle)) {                                    \
                 CERROR("can't start transaction\n");            \
@@ -175,7 +202,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;
 
@@ -196,16 +223,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) {
@@ -215,7 +240,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 && table) {
                CDEBUG(D_INODE, "redirector not found, using primary\n");
                inode = iget(primary->i_sb, primary->i_ino);
        }
@@ -923,7 +948,7 @@ static ino_t fsfilt_ext3_get_indirect_ino(struct super_block *sb,
         ino_t ino = 0;
         int err;
         ENTRY;                                                                                                                                                                                             
-        if (index < 0 || index > EXT3_MAX_SNAPS || !primary)
+        if (index < 0 || index > EXT3_MAX_SNAPS)
                 RETURN(0);
         primary = iget(sb, primary_ino);   
        
@@ -1565,15 +1590,43 @@ static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key,
         } else if (keylen >= strlen(SNAP_GENERATION) 
                    && strcmp(key, SNAP_GENERATION) == 0) {
                 
-                rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX,EXT3_SNAP_GENERATION,
-                                    (char *)val, *vallen);
+                rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX,
+                                    EXT3_SNAP_GENERATION, (char *)val, *vallen);
                 if (rc == -ENODATA) {
                         *((__u32 *)val) = 0; 
                         *vallen = sizeof(int);
                         rc = 0;
                 }
+                if (rc > 0) {
+                        rc = 0;
+                        *vallen = rc;
+                }
+                RETURN(rc);
+        } else if (keylen >= strlen(SNAP_COUNT) && 
+                   strcmp(key, SNAP_COUNT) == 0) {
+                rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX,
+                                    EXT3_SNAP_COUNT, val, *vallen);
+                if (rc == -ENODATA) {
+                        *((__u32 *)val) = 0; 
+                        *vallen = sizeof(int);
+                        rc = 0;
+                }
+                if (rc > 0) {
+                        rc = 0;
+                        *vallen = rc;
+                }
                 RETURN(rc);
-        } 
+        } else if (keylen >= strlen(SNAP_ROOT_INO) && 
+                   (strcmp(key, SNAP_ROOT_INO) == 0)) {
+                
+                rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX,
+                                    EXT3_SNAP_ROOT_INO, val, *vallen);
+                if (rc > 0) {
+                        rc = 0;
+                        *vallen = rc;
+                }
+                RETURN(rc);
+        }
         RETURN(-EINVAL);
 } 
 
@@ -1592,8 +1645,8 @@ static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key,
         if (keylen >= strlen(SNAPTABLE_INFO) 
             && strcmp(key, SNAPTABLE_INFO) == 0) {
                 handle_t *handle;
-                EXT3_JOURNAL_START(inode->i_sb, handle, 
-                                   EXT3_XATTR_TRANS_BLOCKS, rc); 
+                EXT3_JOURNAL_START(inode->i_sb, handle, EXT3_XATTR_TRANS_BLOCKS,
+                                    rc); 
                 if(rc)
                         RETURN(rc);
                 rc = ext3_xattr_set_handle(handle, inode, EXT3_SNAP_INDEX, 
@@ -1607,7 +1660,32 @@ static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key,
                 rc = ext3_set_generation(inode, *(int*)val);
                 
                 RETURN(rc); 
-        }
+        } else if (keylen >= strlen(SNAP_COUNT) && 
+                   (strcmp(key, SNAP_COUNT) == 0)) {
+                handle_t *handle;
+                EXT3_JOURNAL_START(inode->i_sb, handle, 
+                                   EXT3_XATTR_TRANS_BLOCKS, rc); 
+                if(rc)
+                        RETURN(rc);
+                rc = ext3_xattr_set_handle(handle, inode, EXT3_SNAP_INDEX, 
+                                           EXT3_SNAP_COUNT, val, *vallen, 0); 
+               journal_stop(handle);
+                
+                RETURN(rc);
+        } else if (keylen >= strlen(SNAP_ROOT_INO) && 
+                   (strcmp(key, SNAP_ROOT_INO) == 0)) {
+                handle_t *handle;
+                EXT3_JOURNAL_START(inode->i_sb, handle, 
+                                   EXT3_XATTR_TRANS_BLOCKS, rc); 
+                if(rc)
+                        RETURN(rc);
+                rc = ext3_xattr_set_handle(handle, inode, EXT3_SNAP_INDEX, 
+                                           EXT3_SNAP_ROOT_INO, val, *vallen, 0); 
+               journal_stop(handle);
+                
+                RETURN(rc);
+        }       
         RETURN(-EINVAL);
 }
 static int fsfilt_ext3_dir_ent_size(char *name)
@@ -1635,8 +1713,6 @@ static int fsfilt_ext3_set_dir_ent(struct super_block *sb, char *name,
                 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);
                 
@@ -1644,6 +1720,7 @@ static int fsfilt_ext3_set_dir_ent(struct super_block *sb, char *name,
                 de1->name_len = strlen(name);
                 memcpy (de1->name, name, de->name_len);
                 nlen = EXT3_DIR_REC_LEN_DE(de1); 
+                LASSERT(nlen == EXT3_DIR_REC_LEN_DE(de));
                 RETURN(nlen);
         }