Skip to content

Commit 1c9df3d

Browse files
committed
fixup! feat: add 'allocated' flag to inode data block
1 parent b9155a1 commit 1c9df3d

2 files changed

Lines changed: 61 additions & 5 deletions

File tree

src/inode.c

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ struct ex_inode *ex_inode_set(struct ex_inode *dir, const char *name,
255255

256256
if (!entry_address) {
257257
info("unable to find space for inode in dirinode");
258+
// XXX: allocate indirect block
258259
return NULL;
259260
}
260261

@@ -644,6 +645,58 @@ int ex_inode_rename(struct ex_inode *from_inode, struct ex_inode *to_inode,
644645
return 0;
645646
}
646647

648+
static inline int ex_indirect_block_is_allocated(struct ex_inode *i, size_t n) {
649+
return i->blocks[n + EX_DIRECT_BLOCKS].address;
650+
}
651+
652+
static inline int ex_indirect_block_out_of_range(size_t n) {
653+
return n > EX_INDIRECT_BLOCKS;
654+
}
655+
656+
static inline int ex_indirect_block_should_be_loaded(struct ex_block_iterator *it,
657+
size_t indirect_block_no) {
658+
return it->indirect_block_no != indirect_block_no || !it->indirect.data;
659+
}
660+
661+
struct ex_inode_block ex_inode_block_iterate_indirect(struct ex_inode *inode,
662+
struct ex_block_iterator *it) {
663+
assert(it->block_number >= EX_DIRECT_BLOCKS);
664+
665+
size_t indirect_block_no = (it->block_number - EX_DIRECT_BLOCKS) / EX_BLOCK_SIZE;
666+
size_t block_idx = (it->block_number - EX_DIRECT_BLOCKS) % EX_BLOCK_SIZE;
667+
668+
if (ex_indirect_block_out_of_range(indirect_block_no) ||
669+
!ex_indirect_block_is_allocated(inode, indirect_block_no)) {
670+
671+
it->last_block.address = EX_BLOCK_INVALID_ADDRESS;
672+
it->last_block.data = NULL;
673+
it->last_block.id = EX_BLOCK_INVALID_ID;
674+
675+
goto done;
676+
}
677+
678+
if (ex_indirect_block_should_be_loaded(it, indirect_block_no)) {
679+
size_t indirect_block_address = inode->blocks[indirect_block_no + EX_DIRECT_BLOCKS].address;
680+
ssize_t readed = 0;
681+
(void)ex_device_read_to_buffer(&readed, it->indirect_buffer,
682+
indirect_block_address, EX_BLOCK_SIZE);
683+
it->indirect.data = it->indirect_buffer;
684+
}
685+
686+
// read the block
687+
size_t block_address = it->indirect.data[block_idx];
688+
// read the blocks data
689+
ssize_t readed = 0;
690+
(void)ex_device_read_to_buffer(&readed, it->buffer, block_address, EX_BLOCK_SIZE);
691+
692+
it->last_block.address = block_address;
693+
it->last_block.id = it->block_number;
694+
it->last_block.data = it->buffer;
695+
696+
done:
697+
return it->last_block;
698+
}
699+
647700
struct ex_inode_block ex_inode_block_iterate(struct ex_inode *inode,
648701
struct ex_block_iterator *it) {
649702

@@ -657,20 +710,18 @@ struct ex_inode_block ex_inode_block_iterate(struct ex_inode *inode,
657710
.address = EX_BLOCK_INVALID_ADDRESS};
658711

659712
if (it->block_number >= EX_DIRECT_BLOCKS) {
660-
goto done;
713+
return ex_inode_block_iterate_indirect(inode, it);
661714
}
662715

663716
block.address = inode->blocks[it->block_number].address;
664717
block.data = it->buffer;
718+
block.id = it->block_number;
665719

666-
// XXX: add buffer into ex_block_iterator and use ex_device_read_to_buffer
667-
// handle read error
668-
ssize_t readed = 0;
669720
// XXX: handle read error
721+
ssize_t readed = 0;
670722
(void)ex_device_read_to_buffer(&readed, it->buffer,
671723
block.address, EX_BLOCK_SIZE);
672724

673-
done:
674725
it->last_block = block;
675726
return block;
676727
}

src/inode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,13 @@ int ex_inode_has_perm(struct ex_inode *ino, ex_permission perm, gid_t gid, uid_t
113113

114114
struct ex_block_iterator {
115115
struct ex_inode_block last_block;
116+
struct ex_inode_block indirect;
117+
116118
size_t block_number;
119+
size_t indirect_block_no;
120+
117121
char buffer[EX_BLOCK_SIZE];
122+
char indirect_buffer[EX_BLOCK_SIZE];
118123
};
119124

120125
struct ex_entry_iterator {

0 commit comments

Comments
 (0)