Browse Source

Indroduce split ext4_blockdev to two separate structures

Preparation for multi partition mode. New ext4_blockdev_iface
will allow to share same interface by multiple block devices.
pull/11/head
gkostka 9 years ago
parent
commit
9e8466622a
  1. 10
      blockdev/linux/ext4_filedev.c
  2. 97
      lwext4/ext4_blockdev.c
  3. 44
      lwext4/ext4_blockdev.h
  4. 2
      lwext4/ext4_mkfs.c

10
blockdev/linux/ext4_filedev.c

@ -74,7 +74,7 @@ static int filedev_open(struct ext4_blockdev *bdev)
if (fseeko(dev_file, 0, SEEK_END))
return EFAULT;
_filedev.ph_bcnt = ftell(dev_file) / _filedev.ph_bsize;
_filedev.bdif->ph_bcnt = ftell(dev_file) / _filedev.bdif->ph_bsize;
return EOK;
}
@ -84,11 +84,11 @@ static int filedev_open(struct ext4_blockdev *bdev)
static int filedev_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
uint32_t blk_cnt)
{
if (fseeko(dev_file, blk_id * bdev->ph_bsize, SEEK_SET))
if (fseeko(dev_file, blk_id * bdev->bdif->ph_bsize, SEEK_SET))
return EIO;
if (!blk_cnt)
return EOK;
if (!fread(buf, bdev->ph_bsize * blk_cnt, 1, dev_file))
if (!fread(buf, bdev->bdif->ph_bsize * blk_cnt, 1, dev_file))
return EIO;
return EOK;
@ -111,11 +111,11 @@ static void drop_cache(void)
static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf,
uint64_t blk_id, uint32_t blk_cnt)
{
if (fseeko(dev_file, blk_id * bdev->ph_bsize, SEEK_SET))
if (fseeko(dev_file, blk_id * bdev->bdif->ph_bsize, SEEK_SET))
return EIO;
if (!blk_cnt)
return EOK;
if (!fwrite(buf, bdev->ph_bsize * blk_cnt, 1, dev_file))
if (!fwrite(buf, bdev->bdif->ph_bsize * blk_cnt, 1, dev_file))
return EIO;
drop_cache();

97
lwext4/ext4_blockdev.c

@ -47,14 +47,17 @@ int ext4_block_init(struct ext4_blockdev *bdev)
int rc;
ext4_assert(bdev);
ext4_assert(bdev->open && bdev->close && bdev->bread && bdev->bwrite);
ext4_assert(bdev->bdif->open &&
bdev->bdif->close &&
bdev->bdif->bread &&
bdev->bdif->bwrite);
/*Low level block init*/
rc = bdev->open(bdev);
rc = bdev->bdif->open(bdev);
if (rc != EOK)
return rc;
bdev->flags |= EXT4_BDEV_INITIALIZED;
bdev->bdif->ph_flags |= EXT4_BDEV_INITIALIZED;
return EOK;
}
@ -70,20 +73,20 @@ int ext4_block_bind_bcache(struct ext4_blockdev *bdev, struct ext4_bcache *bc)
void ext4_block_set_lb_size(struct ext4_blockdev *bdev, uint64_t lb_bsize)
{
/*Logical block size has to be multiply of physical */
ext4_assert(!(lb_bsize % bdev->ph_bsize));
ext4_assert(!(lb_bsize % bdev->bdif->ph_bsize));
bdev->lg_bsize = lb_bsize;
bdev->lg_bcnt = (bdev->ph_bcnt * bdev->ph_bsize) / lb_bsize;
bdev->lg_bcnt = (bdev->bdif->ph_bcnt * bdev->bdif->ph_bsize) / lb_bsize;
}
int ext4_block_fini(struct ext4_blockdev *bdev)
{
ext4_assert(bdev);
bdev->flags &= ~(EXT4_BDEV_INITIALIZED);
bdev->bdif->ph_flags &= ~(EXT4_BDEV_INITIALIZED);
/*Low level block fini*/
return bdev->close(bdev);
return bdev->bdif->close(bdev);
}
int ext4_block_flush_buf(struct ext4_blockdev *bdev, struct ext4_buf *buf)
@ -140,7 +143,7 @@ int ext4_block_get_noread(struct ext4_blockdev *bdev, struct ext4_block *b,
ext4_assert(bdev && b);
if (!(bdev->flags & EXT4_BDEV_INITIALIZED))
if (!(bdev->bdif->ph_flags & EXT4_BDEV_INITIALIZED))
return EIO;
if (!(lba < bdev->lg_bcnt))
@ -194,7 +197,7 @@ int ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b)
ext4_assert(bdev && b);
ext4_assert(b->buf);
if (!(bdev->flags & EXT4_BDEV_INITIALIZED))
if (!(bdev->bdif->ph_flags & EXT4_BDEV_INITIALIZED))
return EIO;
return ext4_bcache_free(bdev->bc, b);
@ -208,11 +211,11 @@ int ext4_blocks_get_direct(struct ext4_blockdev *bdev, void *buf, uint64_t lba,
ext4_assert(bdev && buf);
pba = (lba * bdev->lg_bsize) / bdev->ph_bsize;
pb_cnt = bdev->lg_bsize / bdev->ph_bsize;
pba = (lba * bdev->lg_bsize) / bdev->bdif->ph_bsize;
pb_cnt = bdev->lg_bsize / bdev->bdif->ph_bsize;
bdev->bread_ctr++;
return bdev->bread(bdev, buf, pba, pb_cnt * cnt);
return bdev->bdif->bread(bdev, buf, pba, pb_cnt * cnt);
}
int ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf,
@ -223,12 +226,12 @@ int ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf,
ext4_assert(bdev && buf);
pba = (lba * bdev->lg_bsize) / bdev->ph_bsize;
pb_cnt = bdev->lg_bsize / bdev->ph_bsize;
pba = (lba * bdev->lg_bsize) / bdev->bdif->ph_bsize;
pb_cnt = bdev->lg_bsize / bdev->bdif->ph_bsize;
bdev->bwrite_ctr++;
return bdev->bwrite(bdev, buf, pba, pb_cnt * cnt);
return bdev->bdif->bwrite(bdev, buf, pba, pb_cnt * cnt);
}
int ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off,
@ -244,30 +247,30 @@ int ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off,
ext4_assert(bdev && buf);
if (!(bdev->flags & EXT4_BDEV_INITIALIZED))
if (!(bdev->bdif->ph_flags & EXT4_BDEV_INITIALIZED))
return EIO;
block_idx = off / bdev->ph_bsize;
block_end = block_idx + len / bdev->ph_bsize;
block_idx = off / bdev->bdif->ph_bsize;
block_end = block_idx + len / bdev->bdif->ph_bsize;
if (!(block_end < bdev->ph_bcnt))
if (!(block_end < bdev->bdif->ph_bcnt))
return EINVAL; /*Ups. Out of range operation*/
/*OK lets deal with the first possible unaligned block*/
unalg = (off & (bdev->ph_bsize - 1));
unalg = (off & (bdev->bdif->ph_bsize - 1));
if (unalg) {
uint32_t wlen = (bdev->ph_bsize - unalg) > len
uint32_t wlen = (bdev->bdif->ph_bsize - unalg) > len
? len
: (bdev->ph_bsize - unalg);
: (bdev->bdif->ph_bsize - unalg);
r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
r = bdev->bdif->bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);
if (r != EOK)
return r;
memcpy(bdev->ph_bbuf + unalg, p, wlen);
memcpy(bdev->bdif->ph_bbuf + unalg, p, wlen);
r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1);
r = bdev->bdif->bwrite(bdev, bdev->bdif->ph_bbuf, block_idx, 1);
if (r != EOK)
return r;
@ -277,25 +280,25 @@ int ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off,
}
/*Aligned data*/
blen = len / bdev->ph_bsize;
r = bdev->bwrite(bdev, p, block_idx, blen);
blen = len / bdev->bdif->ph_bsize;
r = bdev->bdif->bwrite(bdev, p, block_idx, blen);
if (r != EOK)
return r;
p += bdev->ph_bsize * blen;
len -= bdev->ph_bsize * blen;
p += bdev->bdif->ph_bsize * blen;
len -= bdev->bdif->ph_bsize * blen;
block_idx += blen;
/*Rest of the data*/
if (len) {
r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
r = bdev->bdif->bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);
if (r != EOK)
return r;
memcpy(bdev->ph_bbuf, p, len);
memcpy(bdev->bdif->ph_bbuf, p, len);
r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1);
r = bdev->bdif->bwrite(bdev, bdev->bdif->ph_bbuf, block_idx, 1);
if (r != EOK)
return r;
}
@ -316,28 +319,28 @@ int ext4_block_readbytes(struct ext4_blockdev *bdev, uint64_t off, void *buf,
ext4_assert(bdev && buf);
if (!(bdev->flags & EXT4_BDEV_INITIALIZED))
if (!(bdev->bdif->ph_flags & EXT4_BDEV_INITIALIZED))
return EIO;
block_idx = off / bdev->ph_bsize;
block_end = block_idx + len / bdev->ph_bsize;
block_idx = off / bdev->bdif->ph_bsize;
block_end = block_idx + len / bdev->bdif->ph_bsize;
if (!(block_end < bdev->ph_bcnt))
if (!(block_end < bdev->bdif->ph_bcnt))
return EINVAL; /*Ups. Out of range operation*/
/*OK lets deal with the first possible unaligned block*/
unalg = (off & (bdev->ph_bsize - 1));
unalg = (off & (bdev->bdif->ph_bsize - 1));
if (unalg) {
uint32_t rlen = (bdev->ph_bsize - unalg) > len
uint32_t rlen = (bdev->bdif->ph_bsize - unalg) > len
? len
: (bdev->ph_bsize - unalg);
: (bdev->bdif->ph_bsize - unalg);
r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
r = bdev->bdif->bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);
if (r != EOK)
return r;
memcpy(p, bdev->ph_bbuf + unalg, rlen);
memcpy(p, bdev->bdif->ph_bbuf + unalg, rlen);
p += rlen;
len -= rlen;
@ -345,24 +348,24 @@ int ext4_block_readbytes(struct ext4_blockdev *bdev, uint64_t off, void *buf,
}
/*Aligned data*/
blen = len / bdev->ph_bsize;
blen = len / bdev->bdif->ph_bsize;
r = bdev->bread(bdev, p, block_idx, blen);
r = bdev->bdif->bread(bdev, p, block_idx, blen);
if (r != EOK)
return r;
p += bdev->ph_bsize * blen;
len -= bdev->ph_bsize * blen;
p += bdev->bdif->ph_bsize * blen;
len -= bdev->bdif->ph_bsize * blen;
block_idx += blen;
/*Rest of the data*/
if (len) {
r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
r = bdev->bdif->bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);
if (r != EOK)
return r;
memcpy(p, bdev->ph_bbuf, len);
memcpy(p, bdev->bdif->ph_bbuf, len);
}
return r;

44
lwext4/ext4_blockdev.h

@ -50,9 +50,7 @@ extern "C" {
/**@brief Initialization status flag*/
#define EXT4_BDEV_INITIALIZED (1 << 0)
/**@brief Definition of the simple block device.*/
struct ext4_blockdev {
struct ext4_blockdev_iface {
/**@brief Open device function
* @param bdev block device.*/
int (*open)(struct ext4_blockdev *bdev);
@ -76,9 +74,6 @@ struct ext4_blockdev {
* @param bdev block device.*/
int (*close)(struct ext4_blockdev *bdev);
/**@brief Block cache.*/
struct ext4_bcache *bc;
/**@brief Block size (bytes): physical*/
uint32_t ph_bsize;
@ -88,15 +83,27 @@ struct ext4_blockdev {
/**@brief Block size buffer: physical*/
uint8_t *ph_bbuf;
/**@brief Flags of block device*/
uint32_t ph_flags;
};
/**@brief Definition of the simple block device.*/
struct ext4_blockdev {
/**@brief Block device interface*/
struct ext4_blockdev_iface *bdif;
/**@brief Offset in bdif. For multi partition mode.*/
uint64_t ph_blk_offset;
/**@brief Block cache.*/
struct ext4_bcache *bc;
/**@brief Block size (bytes) logical*/
uint32_t lg_bsize;
/**@brief Block count: physical*/
/**@brief Block count: logical*/
uint64_t lg_bcnt;
/**@brief Flags of block device*/
uint32_t flags;
/**@brief Cache write back mode reference counter*/
uint32_t cache_write_back;
@ -111,14 +118,17 @@ struct ext4_blockdev {
#define EXT4_BLOCKDEV_STATIC_INSTANCE(__name, __bsize, __bcnt, __open, \
__bread, __bwrite, __close) \
static uint8_t __name##_ph_bbuf[(__bsize)]; \
static struct ext4_blockdev_iface __name##_iface = { \
.open = __open, \
.bread = __bread, \
.bwrite = __bwrite, \
.close = __close, \
.ph_bsize = __bsize, \
.ph_bcnt = __bcnt, \
.ph_bbuf = __name##_ph_bbuf, \
}; \
static struct ext4_blockdev __name = { \
.open = __open, \
.bread = __bread, \
.bwrite = __bwrite, \
.close = __close, \
.ph_bsize = __bsize, \
.ph_bcnt = __bcnt, \
.ph_bbuf = __name##_ph_bbuf, \
.bdif = &__name##_iface, \
}
/**@brief Block device initialization.

2
lwext4/ext4_mkfs.c

@ -627,7 +627,7 @@ int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd,
return r;
if (info->len == 0)
info->len = bd->ph_bcnt * bd->ph_bsize;
info->len = bd->bdif->ph_bcnt * bd->bdif->ph_bsize;
if (info->block_size == 0)
info->block_size = 4096; /*Set block size to default value*/

Loading…
Cancel
Save