#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"); \
struct snap_ea *snaps;
ino_t ino;
struct inode *inode = NULL;
- int rc = 0, index = 0;
+ int rc = 0;
ENTRY;
/* 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) {
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);
}
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);
} 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);
}
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,
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)
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->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);
}