Skip to content
Browse files

Fix VMFS 5 small file support

In the end, it looks like the ZLA used for new VMFS 5 features doesn't match
the block_id pattern, but looks like 4301 + type, where type is pointer block
or file descriptor. Implementing this way makes future support for up to 2TB
files more natural, and avoids crashing when accessing files bigger than
256GB because their ZLA had the same flag as small files.
  • Loading branch information...
1 parent 071e0d5 commit 129a24011e12951959189acca12c319274f30b95 @glandium committed Sep 10, 2011
Showing with 32 additions and 23 deletions.
  1. +1 −8 debugvmfs/variables.c
  2. +0 −3 libvmfs/vmfs_block.h
  3. +10 −6 libvmfs/vmfs_file.c
  4. +18 −6 libvmfs/vmfs_inode.c
  5. +3 −0 libvmfs/vmfs_inode.h
View
9 debugvmfs/variables.c
@@ -587,14 +587,7 @@ static char *get_value_blkid_flags(char *buf, void *value, short len)
more_than_one = 1;
}
- if (info->flags & VMFS_BLK_FB_INLINE_FLAG) {
- if (more_than_one)
- strcat(buf, ", ");
- strcat(buf, "inline");
- more_than_one = 1;
- }
-
- if (info->flags & ~(VMFS_BLK_FB_INLINE_FLAG | VMFS_BLK_FB_TBZ_FLAG)) {
+ if (info->flags & ~VMFS_BLK_FB_TBZ_FLAG) {
if (more_than_one)
strcat(buf, ", ");
strcat(buf, "unknown");
View
3 libvmfs/vmfs_block.h
@@ -42,9 +42,6 @@ enum vmfs_block_type {
#define VMFS_BLK_FB_ITEM_SHIFT 6
#define VMFS_BLK_FB_TBZ_FLAG 4
-/* Block is inlined in the inode */
-#define VMFS_BLK_FB_INLINE_FLAG 2
-
#define VMFS_BLK_FB_ITEM(blk_id) ((blk_id) >> VMFS_BLK_FB_ITEM_SHIFT)
#define VMFS_BLK_FB_TBZ(blk_id) \
(VMFS_BLK_FLAGS(blk_id) & VMFS_BLK_FB_TBZ_FLAG)
View
16 libvmfs/vmfs_file.c
@@ -170,12 +170,7 @@ ssize_t vmfs_file_pread(vmfs_file_t *f,u_char *buf,size_t len,off_t pos)
/* File-Block */
case VMFS_BLK_TYPE_FB:
exp_len = m_min(len,file_size - pos);
- if (VMFS_BLK_FLAGS(blk_id) & VMFS_BLK_FB_INLINE_FLAG) {
- memcpy(buf, f->inode->content + pos, exp_len);
- res = exp_len;
- } else {
- res = vmfs_block_read_fb(fs,blk_id,pos,buf,exp_len);
- }
+ res = vmfs_block_read_fb(fs,blk_id,pos,buf,exp_len);
break;
/* Sub-Block */
@@ -185,6 +180,15 @@ ssize_t vmfs_file_pread(vmfs_file_t *f,u_char *buf,size_t len,off_t pos)
break;
}
+ /* Inline in the inode */
+ case VMFS_BLK_TYPE_FD:
+ if (blk_id == f->inode->id) {
+ exp_len = m_min(len,file_size - pos);
+ memcpy(buf, f->inode->content + pos, exp_len);
+ res = exp_len;
+ break;
+ }
+
default:
fprintf(stderr,"VMFS: unknown block type 0x%2.2x\n",blk_type);
return(-EIO);
View
24 libvmfs/vmfs_inode.c
@@ -70,7 +70,7 @@ static int vmfs_inode_read(vmfs_inode_t *inode,const u_char *buf)
if (inode->type == VMFS_FILE_TYPE_RDM) {
inode->rdm_id = read_le32(buf,VMFS_INODE_OFS_RDM_ID);
- } else if (VMFS_BLK_FLAGS(inode->zla) & VMFS_BLK_FB_INLINE_FLAG) {
+ } else if (inode->zla == VMFS5_ZLA_BASE + VMFS_BLK_TYPE_FD) {
memcpy(inode->content, buf + VMFS_INODE_OFS_CONTENT, inode->size);
} else {
for(i=0;i<VMFS_INODE_BLK_COUNT;i++)
@@ -281,18 +281,25 @@ int vmfs_inode_get_block(const vmfs_inode_t *inode,off_t pos,uint32_t *blk_id)
{
const vmfs_fs_t *fs = inode->fs;
u_int blk_index;
+ uint32_t zla;
+ int vmfs5_extension;
*blk_id = 0;
if (!inode->blk_size)
return(-EIO);
- switch(VMFS_BLK_TYPE(inode->zla)) {
+ /* This doesn't make much sense but looks like how it's being coded. At
+ * least, the result has some sense. */
+ zla = inode->zla;
+ if (zla >= VMFS5_ZLA_BASE) {
+ vmfs5_extension = 1;
+ zla -= VMFS5_ZLA_BASE;
+ } else
+ vmfs5_extension = 0;
+
+ switch(zla) {
case VMFS_BLK_TYPE_FB:
- if (VMFS_BLK_FLAGS(inode->zla) & VMFS_BLK_FB_INLINE_FLAG) {
- *blk_id = inode->zla;
- break;
- }
case VMFS_BLK_TYPE_SB:
blk_index = pos / inode->blk_size;
@@ -334,6 +341,11 @@ int vmfs_inode_get_block(const vmfs_inode_t *inode,off_t pos,uint32_t *blk_id)
break;
}
+ case VMFS_BLK_TYPE_FD:
+ if (vmfs5_extension) {
+ *blk_id = inode->id;
+ break;
+ }
default:
/* Unexpected ZLA type */
return(-EIO);
View
3 libvmfs/vmfs_inode.h
@@ -80,6 +80,9 @@ struct vmfs_inode_raw {
#define VMFS_INODE_SYNC_BLK 0x02
#define VMFS_INODE_SYNC_ALL (VMFS_INODE_SYNC_META | VMFS_INODE_SYNC_BLK)
+/* Some VMFS 5 features use a weird ZLA */
+#define VMFS5_ZLA_BASE 4301
+
struct vmfs_inode {
vmfs_metadata_hdr_t mdh;
uint32_t id,id2;

0 comments on commit 129a240

Please sign in to comment.
Something went wrong with that request. Please try again.