Whamcloud - gitweb
Branch b1_4
[fs/lustre-release.git] / lustre / lvfs / fsfilt_snap_ext3.c
index e1ef83d..a4accc7 100644 (file)
@@ -43,7 +43,7 @@
 #include <ext3/xattr.h>
 #endif
 
-#include <linux/kp30.h>
+#include <libcfs/kp30.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/obd.h>
 #include <linux/obd_class.h>
@@ -60,7 +60,7 @@
 #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_FEATURE_COMPAT(sb)  (EXT3_SB(sb)->s_es->s_feature_compat)
                                                                                                                                                                                                      
 #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;                                     \
@@ -214,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) {
+       if(slot == -1 && table) {
                CDEBUG(D_INODE, "redirector not found, using primary\n");
                inode = iget(primary->i_sb, primary->i_ino);
        }
@@ -350,7 +376,6 @@ static void ext3_copy_meta(handle_t *handle, struct inode *dst, struct inode *sr
                        if (attrlen < 0)
                                continue;
                        OBD_ALLOC(buf, attrlen);
-                               break;
                        if (!buf) {
                                 CERROR("No MEM\n");
                                 break;
@@ -922,7 +947,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);   
        
@@ -1571,6 +1596,10 @@ static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key,
                         *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) {
@@ -1581,9 +1610,22 @@ static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key,
                         *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);
 } 
 
@@ -1631,10 +1673,16 @@ static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key,
                 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);
@@ -1664,8 +1712,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);
                 
@@ -1673,6 +1719,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);
         }