diff options
| author | gkostka <kostka.grzegorz@gmail.com> | 2015-09-16 23:23:38 +0200 |
|---|---|---|
| committer | gkostka <kostka.grzegorz@gmail.com> | 2015-09-16 23:29:12 +0200 |
| commit | 2651b659e1ad76ad7b5980573643b513b571be9e (patch) | |
| tree | 8d83ae1ee3212803f47015e03b8775f8c0226db7 | |
| parent | 2a1d5f53b73e5626183a02d2a2af9567bd3e012e (diff) | |
Linux codestyle format (tabs indenation)
43 files changed, 8639 insertions, 8399 deletions
diff --git a/.clang-format b/.clang-format index 5eb2b67..bb6914d 100644 --- a/.clang-format +++ b/.clang-format @@ -1,8 +1,8 @@ #clang-format-3.7 -style=file -i lwext4/* BasedOnStyle: LLVM -IndentWidth: 4 -UseTab: Never +IndentWidth: 8 +UseTab: Always BreakBeforeBraces: Linux AllowShortIfStatementsOnASingleLine: false IndentCaseLabels: false diff --git a/blockdev/filedev/ext4_filedev.c b/blockdev/filedev/ext4_filedev.c index 3a21995..14fae75 100644 --- a/blockdev/filedev/ext4_filedev.c +++ b/blockdev/filedev/ext4_filedev.c @@ -50,79 +50,79 @@ static FILE *dev_file; /**********************BLOCKDEV INTERFACE**************************************/ 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); + uint32_t blk_cnt); static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf, - uint64_t blk_id, uint32_t blk_cnt); + uint64_t blk_id, uint32_t blk_cnt); static int filedev_close(struct ext4_blockdev *bdev); /******************************************************************************/ EXT4_BLOCKDEV_STATIC_INSTANCE(_filedev, EXT4_FILEDEV_BSIZE, 0, filedev_open, - filedev_bread, filedev_bwrite, filedev_close); + filedev_bread, filedev_bwrite, filedev_close); /******************************************************************************/ static int filedev_open(struct ext4_blockdev *bdev) { - dev_file = fopen(fname, "r+b"); + dev_file = fopen(fname, "r+b"); - if (!dev_file) - return EIO; + if (!dev_file) + return EIO; - /*No buffering at file.*/ - setbuf(dev_file, 0); + /*No buffering at file.*/ + setbuf(dev_file, 0); - if (fseek(dev_file, 0, SEEK_END)) - return EFAULT; + if (fseek(dev_file, 0, SEEK_END)) + return EFAULT; - _filedev.ph_bcnt = ftell(dev_file) / _filedev.ph_bsize; + _filedev.ph_bcnt = ftell(dev_file) / _filedev.ph_bsize; - return EOK; + return EOK; } /******************************************************************************/ static int filedev_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id, - uint32_t blk_cnt) + uint32_t blk_cnt) { - if (fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET)) - return EIO; + if (fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET)) + return EIO; - if (!fread(buf, bdev->ph_bsize * blk_cnt, 1, dev_file)) - return EIO; + if (!fread(buf, bdev->ph_bsize * blk_cnt, 1, dev_file)) + return EIO; - return EOK; + return EOK; } static void drop_cache(void) { #if defined(__linux__) && DROP_LINUXCACHE_BUFFERS - int fd; - char *data = "3"; + int fd; + char *data = "3"; - sync(); - fd = open("/proc/sys/vm/drop_caches", O_WRONLY); - write(fd, data, sizeof(char)); - close(fd); + sync(); + fd = open("/proc/sys/vm/drop_caches", O_WRONLY); + write(fd, data, sizeof(char)); + close(fd); #endif } /******************************************************************************/ static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf, - uint64_t blk_id, uint32_t blk_cnt) + uint64_t blk_id, uint32_t blk_cnt) { - if (fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET)) - return EIO; + if (fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET)) + return EIO; - if (!fwrite(buf, bdev->ph_bsize * blk_cnt, 1, dev_file)) - return EIO; + if (!fwrite(buf, bdev->ph_bsize * blk_cnt, 1, dev_file)) + return EIO; - drop_cache(); - return EOK; + drop_cache(); + return EOK; } /******************************************************************************/ static int filedev_close(struct ext4_blockdev *bdev) { - fclose(dev_file); - return EOK; + fclose(dev_file); + return EOK; } /******************************************************************************/ diff --git a/blockdev/filedev_win/io_raw.c b/blockdev/filedev_win/io_raw.c index c85fe1d..902cd4f 100644 --- a/blockdev/filedev_win/io_raw.c +++ b/blockdev/filedev_win/io_raw.c @@ -49,106 +49,107 @@ static HANDLE dev_file; /**********************BLOCKDEV INTERFACE**************************************/
static int io_raw_open(struct ext4_blockdev *bdev);
static int io_raw_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
- uint32_t blk_cnt);
+ uint32_t blk_cnt);
static int io_raw_bwrite(struct ext4_blockdev *bdev, const void *buf,
- uint64_t blk_id, uint32_t blk_cnt);
+ uint64_t blk_id, uint32_t blk_cnt);
static int io_raw_close(struct ext4_blockdev *bdev);
/******************************************************************************/
EXT4_BLOCKDEV_STATIC_INSTANCE(_filedev, EXT4_IORAW_BSIZE, 0, io_raw_open,
- io_raw_bread, io_raw_bwrite, io_raw_close);
+ io_raw_bread, io_raw_bwrite, io_raw_close);
/******************************************************************************/
static int io_raw_open(struct ext4_blockdev *bdev)
{
- char path[64];
- DISK_GEOMETRY pdg;
- uint64_t disk_size;
- BOOL bResult = FALSE;
- DWORD junk;
+ char path[64];
+ DISK_GEOMETRY pdg;
+ uint64_t disk_size;
+ BOOL bResult = FALSE;
+ DWORD junk;
- sprintf(path, "\\\\.\\%s", fname);
+ sprintf(path, "\\\\.\\%s", fname);
- dev_file =
- CreateFile(path, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);
+ dev_file =
+ CreateFile(path, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);
- if (dev_file == INVALID_HANDLE_VALUE) {
- return EIO;
- }
+ if (dev_file == INVALID_HANDLE_VALUE) {
+ return EIO;
+ }
- bResult = DeviceIoControl(dev_file, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
- &pdg, sizeof(pdg), &junk, (LPOVERLAPPED)NULL);
+ bResult =
+ DeviceIoControl(dev_file, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
+ &pdg, sizeof(pdg), &junk, (LPOVERLAPPED)NULL);
- if (bResult == FALSE) {
- CloseHandle(dev_file);
- return EIO;
- }
+ if (bResult == FALSE) {
+ CloseHandle(dev_file);
+ return EIO;
+ }
- disk_size = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
- (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
+ disk_size = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
+ (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
- _filedev.ph_bsize = pdg.BytesPerSector;
- _filedev.ph_bcnt = disk_size / pdg.BytesPerSector;
+ _filedev.ph_bsize = pdg.BytesPerSector;
+ _filedev.ph_bcnt = disk_size / pdg.BytesPerSector;
- return EOK;
+ return EOK;
}
/******************************************************************************/
static int io_raw_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
- uint32_t blk_cnt)
+ uint32_t blk_cnt)
{
- long hipart = blk_id >> (32 - 9);
- long lopart = blk_id << 9;
- long err;
+ long hipart = blk_id >> (32 - 9);
+ long lopart = blk_id << 9;
+ long err;
- SetLastError(0);
- lopart = SetFilePointer(dev_file, lopart, &hipart, FILE_BEGIN);
+ SetLastError(0);
+ lopart = SetFilePointer(dev_file, lopart, &hipart, FILE_BEGIN);
- if (lopart == -1 && NO_ERROR != (err = GetLastError())) {
- return EIO;
- }
+ if (lopart == -1 && NO_ERROR != (err = GetLastError())) {
+ return EIO;
+ }
- DWORD n;
+ DWORD n;
- if (!ReadFile(dev_file, buf, blk_cnt * 512, &n, NULL)) {
- err = GetLastError();
- return EIO;
- }
- return EOK;
+ if (!ReadFile(dev_file, buf, blk_cnt * 512, &n, NULL)) {
+ err = GetLastError();
+ return EIO;
+ }
+ return EOK;
}
/******************************************************************************/
static int io_raw_bwrite(struct ext4_blockdev *bdev, const void *buf,
- uint64_t blk_id, uint32_t blk_cnt)
+ uint64_t blk_id, uint32_t blk_cnt)
{
- long hipart = blk_id >> (32 - 9);
- long lopart = blk_id << 9;
- long err;
+ long hipart = blk_id >> (32 - 9);
+ long lopart = blk_id << 9;
+ long err;
- SetLastError(0);
- lopart = SetFilePointer(dev_file, lopart, &hipart, FILE_BEGIN);
+ SetLastError(0);
+ lopart = SetFilePointer(dev_file, lopart, &hipart, FILE_BEGIN);
- if (lopart == -1 && NO_ERROR != (err = GetLastError())) {
- return EIO;
- }
+ if (lopart == -1 && NO_ERROR != (err = GetLastError())) {
+ return EIO;
+ }
- DWORD n;
+ DWORD n;
- if (!WriteFile(dev_file, buf, blk_cnt * 512, &n, NULL)) {
- err = GetLastError();
- return EIO;
- }
- return EOK;
+ if (!WriteFile(dev_file, buf, blk_cnt * 512, &n, NULL)) {
+ err = GetLastError();
+ return EIO;
+ }
+ return EOK;
}
/******************************************************************************/
static int io_raw_close(struct ext4_blockdev *bdev)
{
- CloseHandle(dev_file);
- return EOK;
+ CloseHandle(dev_file);
+ return EOK;
}
/******************************************************************************/
diff --git a/demos/chibios/common/sdc_lwext4.c b/demos/chibios/common/sdc_lwext4.c index 9a7f961..9c2902c 100644 --- a/demos/chibios/common/sdc_lwext4.c +++ b/demos/chibios/common/sdc_lwext4.c @@ -48,135 +48,133 @@ #define MBR_BLOCK_ID 0
#define MBR_PART_TABLE_OFF 446
-struct part_tab_entry
-{
- uint8_t status;
- uint8_t chs1[3];
- uint8_t type;
- uint8_t chs2[3];
- uint32_t first_lba;
- uint32_t sectors;
+struct part_tab_entry {
+ uint8_t status;
+ uint8_t chs1[3];
+ uint8_t type;
+ uint8_t chs2[3];
+ uint32_t first_lba;
+ uint32_t sectors;
} __attribute__((packed));
/**@brief Partition block offset*/
static uint32_t part_offset;
/**@brief IO timings*/
-struct sdc_io_timings
-{
- uint64_t acc_bread;
- uint64_t acc_bwrite;
+struct sdc_io_timings {
+ uint64_t acc_bread;
+ uint64_t acc_bwrite;
- uint32_t cnt_bread;
- uint32_t cnt_bwrite;
+ uint32_t cnt_bread;
+ uint32_t cnt_bwrite;
- uint32_t av_bread;
- uint32_t av_bwrite;
+ uint32_t av_bread;
+ uint32_t av_bwrite;
};
static struct sdc_io_timings io_timings;
void io_timings_clear(void)
{
- memset(&io_timings, 0, sizeof(struct sdc_io_timings));
+ memset(&io_timings, 0, sizeof(struct sdc_io_timings));
}
const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms)
{
- static struct ext4_io_stats s;
+ static struct ext4_io_stats s;
- s.io_read = (((float)io_timings.acc_bread * 100.0) / time_sum_ms);
- s.io_read /= 1000.0;
+ s.io_read = (((float)io_timings.acc_bread * 100.0) / time_sum_ms);
+ s.io_read /= 1000.0;
- s.io_write = (((float)io_timings.acc_bwrite * 100.0) / time_sum_ms);
- s.io_write /= 1000.0;
+ s.io_write = (((float)io_timings.acc_bwrite * 100.0) / time_sum_ms);
+ s.io_write /= 1000.0;
- s.cpu = 100.0 - s.io_read - s.io_write;
+ s.cpu = 100.0 - s.io_read - s.io_write;
- return &s;
+ return &s;
}
/**********************BLOCKDEV INTERFACE**************************************/
static int sdc_open(struct ext4_blockdev *bdev);
static int sdc_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
- uint32_t blk_cnt);
+ uint32_t blk_cnt);
static int sdc_bwrite(struct ext4_blockdev *bdev, const void *buf,
- uint64_t blk_id, uint32_t blk_cnt);
+ uint64_t blk_id, uint32_t blk_cnt);
static int sdc_close(struct ext4_blockdev *bdev);
/******************************************************************************/
EXT4_BLOCKDEV_STATIC_INSTANCE(_sdc, SDC_BLOCK_SIZE, 0, sdc_open, sdc_bread,
- sdc_bwrite, sdc_close);
+ sdc_bwrite, sdc_close);
/******************************************************************************/
EXT4_BCACHE_STATIC_INSTANCE(_sdc_cache, CONFIG_BLOCK_DEV_CACHE_SIZE,
- EXT_LOGICAL_BLOCK_SIZE);
+ EXT_LOGICAL_BLOCK_SIZE);
/******************************************************************************/
static int sdc_open(struct ext4_blockdev *bdev)
{
- (void)bdev;
+ (void)bdev;
- static uint8_t mbr[512];
- struct part_tab_entry *part0;
+ static uint8_t mbr[512];
+ struct part_tab_entry *part0;
- sdcStart(&SDCD1, NULL);
+ sdcStart(&SDCD1, NULL);
- if (sdcConnect(&SDCD1) != HAL_SUCCESS)
- return EIO;
+ if (sdcConnect(&SDCD1) != HAL_SUCCESS)
+ return EIO;
- if (sdcRead(&SDCD1, 0, mbr, 1) != HAL_SUCCESS)
- return EIO;
+ if (sdcRead(&SDCD1, 0, mbr, 1) != HAL_SUCCESS)
+ return EIO;
- part0 = (struct part_tab_entry *)(mbr + MBR_PART_TABLE_OFF);
+ part0 = (struct part_tab_entry *)(mbr + MBR_PART_TABLE_OFF);
- part_offset = part0->first_lba;
- _sdc.ph_bcnt = SDCD1.capacity * SDC_BLOCK_SIZE;
+ part_offset = part0->first_lba;
+ _sdc.ph_bcnt = SDCD1.capacity * SDC_BLOCK_SIZE;
- return EOK;
+ return EOK;
}
static int sdc_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
- uint32_t blk_cnt)
+ uint32_t blk_cnt)
{
- (void)bdev;
- bool status;
- uint64_t v = tim_get_us();
+ (void)bdev;
+ bool status;
+ uint64_t v = tim_get_us();
- status = sdcRead(&SDCD1, blk_id, buf, blk_cnt);
- if (status != HAL_SUCCESS)
- return EIO;
+ status = sdcRead(&SDCD1, blk_id, buf, blk_cnt);
+ if (status != HAL_SUCCESS)
+ return EIO;
- io_timings.acc_bread += tim_get_us() - v;
- io_timings.cnt_bread++;
- io_timings.av_bread = io_timings.acc_bread / io_timings.cnt_bread;
+ io_timings.acc_bread += tim_get_us() - v;
+ io_timings.cnt_bread++;
+ io_timings.av_bread = io_timings.acc_bread / io_timings.cnt_bread;
- return EOK;
+ return EOK;
}
static int sdc_bwrite(struct ext4_blockdev *bdev, const void *buf,
- uint64_t blk_id, uint32_t blk_cnt)
+ uint64_t blk_id, uint32_t blk_cnt)
{
- (void)bdev;
- bool status;
- uint64_t v = tim_get_us();
+ (void)bdev;
+ bool status;
+ uint64_t v = tim_get_us();
- status = sdcWrite(&SDCD1, blk_id, buf, blk_cnt);
- if (status != HAL_SUCCESS)
- return EIO;
+ status = sdcWrite(&SDCD1, blk_id, buf, blk_cnt);
+ if (status != HAL_SUCCESS)
+ return EIO;
- io_timings.acc_bwrite += tim_get_us() - v;
- io_timings.cnt_bwrite++;
- io_timings.av_bwrite = io_timings.acc_bwrite / io_timings.cnt_bwrite;
+ io_timings.acc_bwrite += tim_get_us() - v;
+ io_timings.cnt_bwrite++;
+ io_timings.av_bwrite = io_timings.acc_bwrite / io_timings.cnt_bwrite;
- return EOK;
+ return EOK;
}
static int sdc_close(struct ext4_blockdev *bdev)
{
- (void)bdev;
- return EOK;
+ (void)bdev;
+ return EOK;
}
/******************************************************************************/
diff --git a/demos/chibios/common/sdc_lwext4.h b/demos/chibios/common/sdc_lwext4.h index bb9474f..a9e5d5e 100644 --- a/demos/chibios/common/sdc_lwext4.h +++ b/demos/chibios/common/sdc_lwext4.h @@ -41,11 +41,10 @@ struct ext4_bcache *sdc_cache_get(void); /**@brief SDC blockdev get.*/
struct ext4_blockdev *sdc_bdev_get(void);
-struct ext4_io_stats
-{
- float io_read;
- float io_write;
- float cpu;
+struct ext4_io_stats {
+ float io_read;
+ float io_write;
+ float cpu;
};
void io_timings_clear(void);
diff --git a/demos/chibios/common/spi_lwext4.c b/demos/chibios/common/spi_lwext4.c index 273fec3..955fefb 100644 --- a/demos/chibios/common/spi_lwext4.c +++ b/demos/chibios/common/spi_lwext4.c @@ -52,158 +52,156 @@ extern MMCDriver MMCD1; #define MBR_BLOCK_ID 0 #define MBR_PART_TABLE_OFF 446 -struct part_tab_entry -{ - uint8_t status; - uint8_t chs1[3]; - uint8_t type; - uint8_t chs2[3]; - uint32_t first_lba; - uint32_t sectors; +struct part_tab_entry { + uint8_t status; + uint8_t chs1[3]; + uint8_t type; + uint8_t chs2[3]; + uint32_t first_lba; + uint32_t sectors; } __attribute__((packed)); /**@brief Partition block offset*/ static uint32_t part_offset; /**@brief IO timings*/ -struct spi_io_timings -{ - uint64_t acc_bread; - uint64_t acc_bwrite; +struct spi_io_timings { + uint64_t acc_bread; + uint64_t acc_bwrite; - uint32_t cnt_bread; - uint32_t cnt_bwrite; + uint32_t cnt_bread; + uint32_t cnt_bwrite; - uint32_t av_bread; - uint32_t av_bwrite; + uint32_t av_bread; + uint32_t av_bwrite; }; static struct spi_io_timings io_timings; void io_timings_clear(void) { - memset(&io_timings, 0, sizeof(struct spi_io_timings)); + memset(&io_timings, 0, sizeof(struct spi_io_timings)); } const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms) { - static struct ext4_io_stats s; + static struct ext4_io_stats s; - s.io_read = (((float)io_timings.acc_bread * 100.0) / time_sum_ms); - s.io_read /= 1000.0; + s.io_read = (((float)io_timings.acc_bread * 100.0) / time_sum_ms); + s.io_read /= 1000.0; - s.io_write = (((float)io_timings.acc_bwrite * 100.0) / time_sum_ms); - s.io_write /= 1000.0; + s.io_write = (((float)io_timings.acc_bwrite * 100.0) / time_sum_ms); + s.io_write /= 1000.0; - s.cpu = 100.0 - s.io_read - s.io_write; + s.cpu = 100.0 - s.io_read - s.io_write; - return &s; + return &s; } /**********************BLOCKDEV INTERFACE**************************************/ static int spi_open(struct ext4_blockdev *bdev); static int spi_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id, - uint32_t blk_cnt); + uint32_t blk_cnt); static int spi_bwrite(struct ext4_blockdev *bdev, const void *buf, - uint64_t blk_id, uint32_t blk_cnt); + uint64_t blk_id, uint32_t blk_cnt); static int spi_close(struct ext4_blockdev *bdev); /******************************************************************************/ EXT4_BLOCKDEV_STATIC_INSTANCE(_spi, SPI_BLOCK_SIZE, 0, spi_open, spi_bread, - spi_bwrite, spi_close); + spi_bwrite, spi_close); /******************************************************************************/ EXT4_BCACHE_STATIC_INSTANCE(_spi_cache, CONFIG_BLOCK_DEV_CACHE_SIZE, - EXT_LOGICAL_BLOCK_SIZE); + EXT_LOGICAL_BLOCK_SIZE); /******************************************************************************/ static int spi_open(struct ext4_blockdev *bdev) { - (void)bdev; + (void)bdev; - static uint8_t mbr[512]; - struct part_tab_entry *part0; + static uint8_t mbr[512]; + struct part_tab_entry *part0; - if (mmcConnect(&MMCD1) != HAL_SUCCESS) - return EIO; + if (mmcConnect(&MMCD1) != HAL_SUCCESS) + return EIO; - if (mmcStartSequentialRead(&MMCD1, 0) != HAL_SUCCESS) - return EIO; + if (mmcStartSequentialRead(&MMCD1, 0) != HAL_SUCCESS) + return EIO; - if (mmcSequentialRead(&MMCD1, mbr) != HAL_SUCCESS) - return EIO; + if (mmcSequentialRead(&MMCD1, mbr) != HAL_SUCCESS) + return EIO; - if (mmcStopSequentialRead(&MMCD1) != HAL_SUCCESS) - return EIO; + if (mmcStopSequentialRead(&MMCD1) != HAL_SUCCESS) + return EIO; - part0 = (struct part_tab_entry *)(mbr + MBR_PART_TABLE_OFF); + part0 = (struct part_tab_entry *)(mbr + MBR_PART_TABLE_OFF); - part_offset = part0->first_lba; - _spi.ph_bcnt = MMCD1.capacity * SPI_BLOCK_SIZE; + part_offset = part0->first_lba; + _spi.ph_bcnt = MMCD1.capacity * SPI_BLOCK_SIZE; - return EOK; + return EOK; } static int spi_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id, - uint32_t blk_cnt) + uint32_t blk_cnt) { - (void)bdev; - uint64_t v = tim_get_us(); + (void)bdev; + uint64_t v = tim_get_us(); - if (mmcStartSequentialRead(&MMCD1, blk_id) != HAL_SUCCESS) - return EIO; + if (mmcStartSequentialRead(&MMCD1, blk_id) != HAL_SUCCESS) + return EIO; - while (blk_cnt) { - if (mmcSequentialRead(&MMCD1, buf) != HAL_SUCCESS) - return EIO; + while (blk_cnt) { + if (mmcSequentialRead(&MMCD1, buf) != HAL_SUCCESS) + return EIO; - buf += SPI_BLOCK_SIZE; - blk_cnt--; - } + buf += SPI_BLOCK_SIZE; + blk_cnt--; + } - if (mmcStopSequentialRead(&MMCD1) != HAL_SUCCESS) - return EIO; + if (mmcStopSequentialRead(&MMCD1) != HAL_SUCCESS) + return EIO; - io_timings.acc_bread += tim_get_us() - v; - io_timings.cnt_bread++; - io_timings.av_bread = io_timings.acc_bread / io_timings.cnt_bread; + io_timings.acc_bread += tim_get_us() - v; + io_timings.cnt_bread++; + io_timings.av_bread = io_timings.acc_bread / io_timings.cnt_bread; - return EOK; + return EOK; } static int spi_bwrite(struct ext4_blockdev *bdev, const void *buf, - uint64_t blk_id, uint32_t blk_cnt) + uint64_t blk_id, uint32_t blk_cnt) { - (void)bdev; - uint64_t v = tim_get_us(); + (void)bdev; + uint64_t v = tim_get_us(); - if (mmcStartSequentialWrite(&MMCD1, blk_id) != HAL_SUCCESS) - return EIO; + if (mmcStartSequentialWrite(&MMCD1, blk_id) != HAL_SUCCESS) + return EIO; - while (blk_cnt) { - if (mmcSequentialWrite(&MMCD1, buf) != HAL_SUCCESS) - return EIO; + while (blk_cnt) { + if (mmcSequentialWrite(&MMCD1, buf) != HAL_SUCCESS) + return EIO; - buf += SPI_BLOCK_SIZE; - blk_cnt--; - } + buf += SPI_BLOCK_SIZE; + blk_cnt--; + } - if (mmcStopSequentialWrite(&MMCD1) != HAL_SUCCESS) - return EIO; + if (mmcStopSequentialWrite(&MMCD1) != HAL_SUCCESS) + return EIO; - io_timings.acc_bwrite += tim_get_us() - v; - io_timings.cnt_bwrite++; - io_timings.av_bwrite = io_timings.acc_bwrite / io_timings.cnt_bwrite; + io_timings.acc_bwrite += tim_get_us() - v; + io_timings.cnt_bwrite++; + io_timings.av_bwrite = io_timings.acc_bwrite / io_timings.cnt_bwrite; - return EOK; + return EOK; } static int spi_close(struct ext4_blockdev *bdev) { - (void)bdev; - return EOK; + (void)bdev; + return EOK; } /******************************************************************************/ diff --git a/demos/chibios/common/spi_lwext4.h b/demos/chibios/common/spi_lwext4.h index 1759198..ef88508 100644 --- a/demos/chibios/common/spi_lwext4.h +++ b/demos/chibios/common/spi_lwext4.h @@ -21,11 +21,10 @@ struct ext4_bcache *spi_cache_get(void); /**@brief SPI blockdev get.*/ struct ext4_blockdev *spi_bdev_get(void); -struct ext4_io_stats -{ - float io_read; - float io_write; - float cpu; +struct ext4_io_stats { + float io_read; + float io_write; + float cpu; }; void io_timings_clear(void); diff --git a/demos/chibios/common/test_lwext4.c b/demos/chibios/common/test_lwext4.c index 72d6e3e..8a0adcf 100644 --- a/demos/chibios/common/test_lwext4.c +++ b/demos/chibios/common/test_lwext4.c @@ -51,323 +51,327 @@ static struct ext4_bcache *bc; static char *entry_to_str(uint8_t type) { - switch (type) { - case EXT4_DIRENTRY_UNKNOWN: - return "[unk] "; - case EXT4_DIRENTRY_REG_FILE: - return "[fil] "; - case EXT4_DIRENTRY_DIR: - return "[dir] "; - case EXT4_DIRENTRY_CHRDEV: - return "[cha] "; - case EXT4_DIRENTRY_BLKDEV: - return "[blk] "; - case EXT4_DIRENTRY_FIFO: - return "[fif] "; - case EXT4_DIRENTRY_SOCK: - return "[soc] "; - case EXT4_DIRENTRY_SYMLINK: - return "[sym] "; - default: - break; - } - return "[???]"; + switch (type) { + case EXT4_DIRENTRY_UNKNOWN: + return "[unk] "; + case EXT4_DIRENTRY_REG_FILE: + return "[fil] "; + case EXT4_DIRENTRY_DIR: + return "[dir] "; + case EXT4_DIRENTRY_CHRDEV: + return "[cha] "; + case EXT4_DIRENTRY_BLKDEV: + return "[blk] "; + case EXT4_DIRENTRY_FIFO: + return "[fif] "; + case EXT4_DIRENTRY_SOCK: + return "[soc] "; + case EXT4_DIRENTRY_SYMLINK: + return "[sym] "; + default: + break; + } + return "[???]"; } static clock_t get_ms(void) { return tim_get_ms(); } static void printf_io_timings(clock_t diff) { - const struct ext4_io_stats *stats = io_timings_get(diff); - printf("io_timings:\n"); - printf(" io_read: %.3f%%\n", stats->io_read); - printf(" io_write: %.3f%%\n", stats->io_write); - printf(" io_cpu: %.3f%%\n", stats->cpu); + const struct ext4_io_stats *stats = io_timings_get(diff); + printf("io_timings:\n"); + printf(" io_read: %.3f%%\n", stats->io_read); + printf(" io_write: %.3f%%\n", stats->io_write); + printf(" io_cpu: %.3f%%\n", stats->cpu); } void test_lwext4_dir_ls(const char *path) { - char sss[255]; - ext4_dir d; - const ext4_direntry *de; - - printf("ls %s\n", path); - - ext4_dir_open(&d, path); - de = ext4_dir_entry_next(&d); - - while (de) { - memcpy(sss, de->name, de->name_length); - sss[de->name_length] = 0; - printf(" %s%s\n", entry_to_str(de->inode_type), sss); - de = ext4_dir_entry_next(&d); - } - ext4_dir_close(&d); + char sss[255]; + ext4_dir d; + const ext4_direntry *de; + + printf("ls %s\n", path); + + ext4_dir_open(&d, path); + de = ext4_dir_entry_next(&d); + + while (de) { + memcpy(sss, de->name, de->name_length); + sss[de->name_length] = 0; + printf(" %s%s\n", entry_to_str(de->inode_type), sss); + de = ext4_dir_entry_next(&d); + } + ext4_dir_close(&d); } void test_lwext4_mp_stats(void) { - struct ext4_mount_stats stats; - ext4_mount_point_stats("/mp/", &stats); - - printf("********************\n"); - printf("ext4_mount_point_stats\n"); - printf("inodes_count = %" PRIu32 "\n", stats.inodes_count); - printf("free_inodes_count = %" PRIu32 "\n", stats.free_inodes_count); - printf("blocks_count = %" PRIu32 "\n", (uint32_t)stats.blocks_count); - printf("free_blocks_count = %" PRIu32 "\n", - (uint32_t)stats.free_blocks_count); - printf("block_size = %" PRIu32 "\n", stats.block_size); - printf("block_group_count = %" PRIu32 "\n", stats.block_group_count); - printf("blocks_per_group= %" PRIu32 "\n", stats.blocks_per_group); - printf("inodes_per_group = %" PRIu32 "\n", stats.inodes_per_group); - printf("volume_name = %s\n", stats.volume_name); - printf("********************\n"); + struct ext4_mount_stats stats; + ext4_mount_point_stats("/mp/", &stats); + + printf("********************\n"); + printf("ext4_mount_point_stats\n"); + printf("inodes_count = %" PRIu32 "\n", stats.inodes_count); + printf("free_inodes_count = %" PRIu32 "\n", stats.free_inodes_count); + printf("blocks_count = %" PRIu32 "\n", (uint32_t)stats.blocks_count); + printf("free_blocks_count = %" PRIu32 "\n", + (uint32_t)stats.free_blocks_count); + printf("block_size = %" PRIu32 "\n", stats.block_size); + printf("block_group_count = %" PRIu32 "\n", stats.block_group_count); + printf("blocks_per_group= %" PRIu32 "\n", stats.blocks_per_group); + printf("inodes_per_group = %" PRIu32 "\n", stats.inodes_per_group); + printf("volume_name = %s\n", stats.volume_name); + printf("********************\n"); } void test_lwext4_block_stats(void) { - if (!bd) - return; - - printf("********************\n"); - printf("ext4 blockdev stats\n"); - printf("bdev->bread_ctr = %" PRIu32 "\n", bd->bread_ctr); - printf("bdev->bwrite_ctr = %" PRIu32 "\n", bd->bwrite_ctr); - - printf("bcache->ref_blocks = %" PRIu32 "\n", bc->ref_blocks); - printf("bcache->max_ref_blocks = %" PRIu32 "\n", bc->max_ref_blocks); - printf("bcache->lru_ctr = %" PRIu32 "\n", bc->lru_ctr); - - printf("\n"); - - uint32_t i; - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->refctr[%" PRIu32 "]= %" PRIu32 "\n", i, bc->refctr[i]); - } - - printf("\n"); - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->lru_id[%" PRIu32 "] = %" PRIu32 "\n", i, bc->lru_id[i]); - } - - printf("\n"); - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->free_delay[%" PRIu32 "] = %d\n", i, bc->free_delay[i]); - } - - printf("\n"); - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->lba[%" PRIu32 "] = %" PRIu32 "\n", i, - (uint32_t)bc->lba[i]); - } - - printf("********************\n"); + if (!bd) + return; + + printf("********************\n"); + printf("ext4 blockdev stats\n"); + printf("bdev->bread_ctr = %" PRIu32 "\n", bd->bread_ctr); + printf("bdev->bwrite_ctr = %" PRIu32 "\n", bd->bwrite_ctr); + + printf("bcache->ref_blocks = %" PRIu32 "\n", bc->ref_blocks); + printf("bcache->max_ref_blocks = %" PRIu32 "\n", bc->max_ref_blocks); + printf("bcache->lru_ctr = %" PRIu32 "\n", bc->lru_ctr); + + printf("\n"); + + uint32_t i; + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->refctr[%" PRIu32 "]= %" PRIu32 "\n", i, + bc->refctr[i]); + } + + printf("\n"); + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->lru_id[%" PRIu32 "] = %" PRIu32 "\n", i, + bc->lru_id[i]); + } + + printf("\n"); + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->free_delay[%" PRIu32 "] = %d\n", i, + bc->free_delay[i]); + } + + printf("\n"); + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->lba[%" PRIu32 "] = %" PRIu32 "\n", i, + (uint32_t)bc->lba[i]); + } + + printf("********************\n"); } bool test_lwext4_dir_test(int len) { - ext4_file f; - int r; - int i; - char path[64]; - clock_t diff; - clock_t stop; - clock_t start; - - printf("test_lwext4_dir_test: %d\n", len); - io_timings_clear(); - start = get_ms(); - - printf("directory create: /mp/dir1\n"); - r = ext4_dir_mk("/mp/dir1"); - if (r != EOK) { - printf("ext4_dir_mk: rc = %d\n", r); - return false; - } - - printf("add files to: /mp/dir1\n"); - for (i = 0; i < len; ++i) { - sprintf(path, "/mp/dir1/f%d", i); - r = ext4_fopen(&f, path, "wb"); - if (r != EOK) { - printf("ext4_fopen: rc = %d\n", r); - return false; - } - } - - stop = get_ms(); - diff = stop - start; - test_lwext4_dir_ls("/mp/dir1"); - printf("test_lwext4_dir_test: time: %d ms\n", (int)diff); - printf("test_lwext4_dir_test: av: %d ms/entry\n", (int)diff / len); - printf_io_timings(diff); - return true; + ext4_file f; + int r; + int i; + char path[64]; + clock_t diff; + clock_t stop; + clock_t start; + + printf("test_lwext4_dir_test: %d\n", len); + io_timings_clear(); + start = get_ms(); + + printf("directory create: /mp/dir1\n"); + r = ext4_dir_mk("/mp/dir1"); + if (r != EOK) { + printf("ext4_dir_mk: rc = %d\n", r); + return false; + } + + printf("add files to: /mp/dir1\n"); + for (i = 0; i < len; ++i) { + sprintf(path, "/mp/dir1/f%d", i); + r = ext4_fopen(&f, path, "wb"); + if (r != EOK) { + printf("ext4_fopen: rc = %d\n", r); + return false; + } + } + + stop = get_ms(); + diff = stop - start; + test_lwext4_dir_ls("/mp/dir1"); + printf("test_lwext4_dir_test: time: %d ms\n", (int)diff); + printf("test_lwext4_dir_test: av: %d ms/entry\n", (int)diff / len); + printf_io_timings(diff); + return true; } static int verify_buf(const unsigned char *b, size_t len, unsigned char c) { - size_t i; - for (i = 0; i < len; ++i) { - if (b[i] != c) - return c - b[i]; - } + size_t i; + for (i = 0; i < len; ++i) { + if (b[i] != c) + return c - b[i]; + } - return 0; + return 0; } bool test_lwext4_file_test(uint32_t rw_szie, uint32_t rw_count) { - int r; - uint32_t size; - uint32_t i; - clock_t start; - clock_t stop; - clock_t diff; - uint32_t kbps; - uint64_t size_bytes; - - ext4_file f; - - printf("file_test:\n"); - printf(" rw size: %" PRIu32 "\n", rw_szie); - printf(" rw count: %" PRIu32 "\n", rw_count); - - /*Add hello world file.*/ - r = ext4_fopen(&f, "/mp/hello.txt", "wb"); - r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0); - r = ext4_fclose(&f); - - io_timings_clear(); - start = get_ms(); - r = ext4_fopen(&f, "/mp/test1", "wb"); - if (r != EOK) { - printf("ext4_fopen ERROR = %d\n", r); - return false; - } - - printf("ext4_write: %" PRIu32 " * %" PRIu32 " ...\n", rw_szie, rw_count); - for (i = 0; i < rw_count; ++i) { - - memset(rw_buff, i % 10 + '0', rw_szie); - - r = ext4_fwrite(&f, rw_buff, rw_szie, &size); - - if ((r != EOK) || (size != rw_szie)) - break; - } - - if (i != rw_count) { - printf(" file_test: rw_count = %" PRIu32 "\n", i); - return false; - } - - stop = get_ms(); - diff = stop - start; - size_bytes = rw_szie * rw_count; - size_bytes = (size_bytes * 1000) / 1024; - kbps = (size_bytes) / (diff + 1); - printf(" write time: %d ms\n", (int)diff); - printf(" write speed: %" PRIu32 " KB/s\n", kbps); - printf_io_timings(diff); - r = ext4_fclose(&f); - - io_timings_clear(); - start = get_ms(); - r = ext4_fopen(&f, "/mp/test1", "r+"); - if (r != EOK) { - printf("ext4_fopen ERROR = %d\n", r); - return false; - } - - printf("ext4_read: %" PRIu32 " * %" PRIu32 " ...\n", rw_szie, rw_count); - - for (i = 0; i < rw_count; ++i) { - r = ext4_fread(&f, rw_buff, rw_szie, &size); - - if ((r != EOK) || (size != rw_szie)) - break; - - if (verify_buf(rw_buff, rw_szie, i % 10 + '0')) - break; - } - - if (i != rw_count) { - printf(" file_test: rw_count = %" PRIu32 "\n", i); - return false; - } - - stop = get_ms(); - diff = stop - start; - size_bytes = rw_szie * rw_count; - size_bytes = (size_bytes * 1000) / 1024; - kbps = (size_bytes) / (diff + 1); - printf(" read time: %d ms\n", (int)diff); - printf(" read speed: %d KB/s\n", (int)kbps); - printf_io_timings(diff); - - r = ext4_fclose(&f); - return true; + int r; + uint32_t size; + uint32_t i; + clock_t start; + clock_t stop; + clock_t diff; + uint32_t kbps; + uint64_t size_bytes; + + ext4_file f; + + printf("file_test:\n"); + printf(" rw size: %" PRIu32 "\n", rw_szie); + printf(" rw count: %" PRIu32 "\n", rw_count); + + /*Add hello world file.*/ + r = ext4_fopen(&f, "/mp/hello.txt", "wb"); + r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0); + r = ext4_fclose(&f); + + io_timings_clear(); + start = get_ms(); + r = ext4_fopen(&f, "/mp/test1", "wb"); + if (r != EOK) { + printf("ext4_fopen ERROR = %d\n", r); + return false; + } + + printf("ext4_write: %" PRIu32 " * %" PRIu32 " ...\n", rw_szie, + rw_count); + for (i = 0; i < rw_count; ++i) { + + memset(rw_buff, i % 10 + '0', rw_szie); + + r = ext4_fwrite(&f, rw_buff, rw_szie, &size); + + if ((r != EOK) || (size != rw_szie)) + break; + } + + if (i != rw_count) { + printf(" file_test: rw_count = %" PRIu32 "\n", i); + return false; + } + + stop = get_ms(); + diff = stop - start; + size_bytes = rw_szie * rw_count; + size_bytes = (size_bytes * 1000) / 1024; + kbps = (size_bytes) / (diff + 1); + printf(" write time: %d ms\n", (int)diff); + printf(" write speed: %" PRIu32 " KB/s\n", kbps); + printf_io_timings(diff); + r = ext4_fclose(&f); + + io_timings_clear(); + start = get_ms(); + r = ext4_fopen(&f, "/mp/test1", "r+"); + if (r != EOK) { + printf("ext4_fopen ERROR = %d\n", r); + return false; + } + + printf("ext4_read: %" PRIu32 " * %" PRIu32 " ...\n", rw_szie, rw_count); + + for (i = 0; i < rw_count; ++i) { + r = ext4_fread(&f, rw_buff, rw_szie, &size); + + if ((r != EOK) || (size != rw_szie)) + break; + + if (verify_buf(rw_buff, rw_szie, i % 10 + '0')) + break; + } + + if (i != rw_count) { + printf(" file_test: rw_count = %" PRIu32 "\n", i); + return false; + } + + stop = get_ms(); + diff = stop - start; + size_bytes = rw_szie * rw_count; + size_bytes = (size_bytes * 1000) / 1024; + kbps = (size_bytes) / (diff + 1); + printf(" read time: %d ms\n", (int)diff); + printf(" read speed: %d KB/s\n", (int)kbps); + printf_io_timings(diff); + + r = ext4_fclose(&f); + return true; } void test_lwext4_cleanup(void) { - clock_t start; - clock_t stop; - clock_t diff; - - printf("\ncleanup:\n"); - ext4_fremove("/mp/hello.txt"); - - printf("remove /mp/test1\n"); - ext4_fremove("/mp/test1"); - - printf("remove /mp/dir1\n"); - io_timings_clear(); - start = get_ms(); - ext4_dir_rm("/mp/dir1"); - stop = get_ms(); - diff = stop - start; - printf("cleanup: time: %d ms\n", (int)diff); - printf_io_timings(diff); + clock_t start; + clock_t stop; + clock_t diff; + + printf("\ncleanup:\n"); + ext4_fremove("/mp/hello.txt"); + + printf("remove /mp/test1\n"); + ext4_fremove("/mp/test1"); + + printf("remove /mp/dir1\n"); + io_timings_clear(); + start = get_ms(); + ext4_dir_rm("/mp/dir1"); + stop = get_ms(); + diff = stop - start; + printf("cleanup: time: %d ms\n", (int)diff); + printf_io_timings(diff); } bool test_lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache) { - int r; + int r; - bc = bcache; - bd = bdev; + bc = bcache; + bd = bdev; - if (!bd) { - printf("test_lwext4_mount: no block device\n"); - return false; - } + if (!bd) { + printf("test_lwext4_mount: no block device\n"); + return false; + } - ext4_dmask_set(EXT4_DEBUG_ALL); + ext4_dmask_set(EXT4_DEBUG_ALL); - r = ext4_device_register(bd, bc ? bc : 0, "ext4_fs"); - if (r != EOK) { - printf("ext4_device_register: rc = %d\n", r); - return false; - } + r = ext4_device_register(bd, bc ? bc : 0, "ext4_fs"); + if (r != EOK) { + printf("ext4_device_register: rc = %d\n", r); + return false; + } - r = ext4_mount("ext4_fs", "/mp/"); - if (r != EOK) { - printf("ext4_mount: rc = %d\n", r); - return false; - } + r = ext4_mount("ext4_fs", "/mp/"); + if (r != EOK) { + printf("ext4_mount: rc = %d\n", r); + return false; + } - ext4_cache_write_back("/mp/", 1); - return true; + ext4_cache_write_back("/mp/", 1); + return true; } bool test_lwext4_umount(void) { - ext4_cache_write_back("/mp/", 0); - int r = ext4_umount("/mp/"); - if (r != EOK) { - printf("ext4_umount: fail %d", r); - return false; - } - return true; + ext4_cache_write_back("/mp/", 0); + int r = ext4_umount("/mp/"); + if (r != EOK) { + printf("ext4_umount: fail %d", r); + return false; + } + return true; } diff --git a/demos/chibios/common/timings.c b/demos/chibios/common/timings.c index 06f18aa..d0bcc0f 100644 --- a/demos/chibios/common/timings.c +++ b/demos/chibios/common/timings.c @@ -37,12 +37,12 @@ void tim_wait_ms(uint32_t v) { chThdSleepMilliseconds(v); } uint64_t tim_get_us(void) { - uint64_t v = chVTGetSystemTimeX(); - return ST2US(v); + uint64_t v = chVTGetSystemTimeX(); + return ST2US(v); } uint32_t tim_get_ms(void) { - uint32_t v = chVTGetSystemTimeX(); - return ST2MS(v); + uint32_t v = chVTGetSystemTimeX(); + return ST2MS(v); } diff --git a/demos/generic/main.c b/demos/generic/main.c index e0dc1c4..f77823e 100644 --- a/demos/generic/main.c +++ b/demos/generic/main.c @@ -104,428 +104,432 @@ Usage: \n\ static char *entry_to_str(uint8_t type)
{
- switch (type) {
- case EXT4_DIRENTRY_UNKNOWN:
- return "[UNK] ";
- case EXT4_DIRENTRY_REG_FILE:
- return "[FIL] ";
- case EXT4_DIRENTRY_DIR:
- return "[DIR] ";
- case EXT4_DIRENTRY_CHRDEV:
- return "[CHA] ";
- case EXT4_DIRENTRY_BLKDEV:
- return "[BLK] ";
- case EXT4_DIRENTRY_FIFO:
- return "[FIF] ";
- case EXT4_DIRENTRY_SOCK:
- return "[SOC] ";
- case EXT4_DIRENTRY_SYMLINK:
- return "[SYM] ";
- default:
- break;
- }
- return "[???]";
+ switch (type) {
+ case EXT4_DIRENTRY_UNKNOWN:
+ return "[UNK] ";
+ case EXT4_DIRENTRY_REG_FILE:
+ return "[FIL] ";
+ case EXT4_DIRENTRY_DIR:
+ return "[DIR] ";
+ case EXT4_DIRENTRY_CHRDEV:
+ return "[CHA] ";
+ case EXT4_DIRENTRY_BLKDEV:
+ return "[BLK] ";
+ case EXT4_DIRENTRY_FIFO:
+ return "[FIF] ";
+ case EXT4_DIRENTRY_SOCK:
+ return "[SOC] ";
+ case EXT4_DIRENTRY_SYMLINK:
+ return "[SYM] ";
+ default:
+ break;
+ }
+ return "[???]";
}
static void dir_ls(const char *path)
{
- char sss[255];
- ext4_dir d;
- const ext4_direntry *de;
-
- printf("ls %s:\n", path);
-
- ext4_dir_open(&d, path);
- de = ext4_dir_entry_next(&d);
-
- while (de) {
- memcpy(sss, de->name, de->name_length);
- sss[de->name_length] = 0;
- printf("\t%s", entry_to_str(de->inode_type));
- printf("%s", sss);
- printf("\n");
- de = ext4_dir_entry_next(&d);
- }
- ext4_dir_close(&d);
+ char sss[255];
+ ext4_dir d;
+ const ext4_direntry *de;
+
+ printf("ls %s:\n", path);
+
+ ext4_dir_open(&d, path);
+ de = ext4_dir_entry_next(&d);
+
+ while (de) {
+ memcpy(sss, de->name, de->name_length);
+ sss[de->name_length] = 0;
+ printf("\t%s", entry_to_str(de->inode_type));
+ printf("%s", sss);
+ printf("\n");
+ de = ext4_dir_entry_next(&d);
+ }
+ ext4_dir_close(&d);
}
static void mp_stats(void)
{
- struct ext4_mount_stats stats;
- ext4_mount_point_stats("/mp/", &stats);
-
- printf("ext4_mount_point_stats:\n");
- printf("\tinodes_count = %" PRIu32 "\n", stats.inodes_count);
- printf("\tfree_inodes_count = %" PRIu32 "\n", stats.free_inodes_count);
- printf("\tblocks_count = %" PRIu32 "\n",
- (uint32_t)stats.blocks_count);
- printf("\tfree_blocks_count = %" PRIu32 "\n",
- (uint32_t)stats.free_blocks_count);
- printf("\tblock_size = %" PRIu32 "\n", stats.block_size);
- printf("\tblock_group_count = %" PRIu32 "\n", stats.block_group_count);
- printf("\tblocks_per_group = %" PRIu32 "\n", stats.blocks_per_group);
- printf("\tinodes_per_group = %" PRIu32 "\n", stats.inodes_per_group);
- printf("\tvolume_name = %s\n", stats.volume_name);
+ struct ext4_mount_stats stats;
+ ext4_mount_point_stats("/mp/", &stats);
+
+ printf("ext4_mount_point_stats:\n");
+ printf("\tinodes_count = %" PRIu32 "\n", stats.inodes_count);
+ printf("\tfree_inodes_count = %" PRIu32 "\n",
+ stats.free_inodes_count);
+ printf("\tblocks_count = %" PRIu32 "\n",
+ (uint32_t)stats.blocks_count);
+ printf("\tfree_blocks_count = %" PRIu32 "\n",
+ (uint32_t)stats.free_blocks_count);
+ printf("\tblock_size = %" PRIu32 "\n", stats.block_size);
+ printf("\tblock_group_count = %" PRIu32 "\n",
+ stats.block_group_count);
+ printf("\tblocks_per_group = %" PRIu32 "\n", stats.blocks_per_group);
+ printf("\tinodes_per_group = %" PRIu32 "\n", stats.inodes_per_group);
+ printf("\tvolume_name = %s\n", stats.volume_name);
}
static void block_stats(void)
{
- uint32_t i;
-
- printf("ext4 blockdev stats\n");
- printf("\tbdev->bread_ctr = %" PRIu32 "\n", bd->bread_ctr);
- printf("\tbdev->bwrite_ctr = %" PRIu32 "\n", bd->bwrite_ctr);
-
- printf("\tbcache->ref_blocks = %" PRIu32 "\n", bc->ref_blocks);
- printf("\tbcache->max_ref_blocks = %" PRIu32 "\n", bc->max_ref_blocks);
- printf("\tbcache->lru_ctr = %" PRIu32 "\n", bc->lru_ctr);
-
- printf("\n");
- for (i = 0; i < bc->cnt; ++i) {
- printf("\tbcache->refctr[%" PRIu32 "] = %" PRIu32 "\n", i,
- bc->refctr[i]);
- }
-
- printf("\n");
- for (i = 0; i < bc->cnt; ++i) {
- printf("\tbcache->lru_id[%" PRIu32 "] = %" PRIu32 "\n", i,
- bc->lru_id[i]);
- }
-
- printf("\n");
- for (i = 0; i < bc->cnt; ++i) {
- printf("\tbcache->free_delay[%" PRIu32 "] = %d\n", i,
- bc->free_delay[i]);
- }
-
- printf("\n");
- for (i = 0; i < bc->cnt; ++i) {
- printf("\tbcache->lba[%" PRIu32 "] = %" PRIu32 "\n", i,
- (uint32_t)bc->lba[i]);
- }
+ uint32_t i;
+
+ printf("ext4 blockdev stats\n");
+ printf("\tbdev->bread_ctr = %" PRIu32 "\n", bd->bread_ctr);
+ printf("\tbdev->bwrite_ctr = %" PRIu32 "\n", bd->bwrite_ctr);
+
+ printf("\tbcache->ref_blocks = %" PRIu32 "\n", bc->ref_blocks);
+ printf("\tbcache->max_ref_blocks = %" PRIu32 "\n",
+ bc->max_ref_blocks);
+ printf("\tbcache->lru_ctr = %" PRIu32 "\n", bc->lru_ctr);
+
+ printf("\n");
+ for (i = 0; i < bc->cnt; ++i) {
+ printf("\tbcache->refctr[%" PRIu32 "] = %" PRIu32 "\n", i,
+ bc->refctr[i]);
+ }
+
+ printf("\n");
+ for (i = 0; i < bc->cnt; ++i) {
+ printf("\tbcache->lru_id[%" PRIu32 "] = %" PRIu32 "\n", i,
+ bc->lru_id[i]);
+ }
+
+ printf("\n");
+ for (i = 0; i < bc->cnt; ++i) {
+ printf("\tbcache->free_delay[%" PRIu32 "] = %d\n", i,
+ bc->free_delay[i]);
+ }
+
+ printf("\n");
+ for (i = 0; i < bc->cnt; ++i) {
+ printf("\tbcache->lba[%" PRIu32 "] = %" PRIu32 "\n", i,
+ (uint32_t)bc->lba[i]);
+ }
}
static clock_t get_ms(void)
{
- struct timeval t;
- gettimeofday(&t, NULL);
- return (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ return (t.tv_sec * 1000) + (t.tv_usec / 1000);
}
static bool dir_test(int len)
{
- ext4_file f;
- int r;
- int i;
- char path[64];
- clock_t diff;
- clock_t stop;
- clock_t start;
-
- printf("\ndir_test: %d\n", len);
- printf("directory create: /mp/dir1\n");
- start = get_ms();
- r = ext4_dir_mk("/mp/dir1");
- if (r != EOK) {
- printf("\text4_dir_mk: rc = %d\n", r);
- return false;
- }
-
- ext4_cache_write_back("/mp/", 1);
- printf("add files to: /mp/dir1\n");
- for (i = 0; i < len; ++i) {
- sprintf(path, "/mp/dir1/f%d", i);
- r = ext4_fopen(&f, path, "wb");
- if (r != EOK) {
- printf("\text4_fopen: rc = %d\n", r);
- return false;
- }
- }
- ext4_cache_write_back("/mp/", 0);
-
- stop = get_ms();
- diff = stop - start;
- dir_ls("/mp/dir1");
- printf("dir_test: time: %d ms\n", (int)diff);
- return true;
+ ext4_file f;
+ int r;
+ int i;
+ char path[64];
+ clock_t diff;
+ clock_t stop;
+ clock_t start;
+
+ printf("\ndir_test: %d\n", len);
+ printf("directory create: /mp/dir1\n");
+ start = get_ms();
+ r = ext4_dir_mk("/mp/dir1");
+ if (r != EOK) {
+ printf("\text4_dir_mk: rc = %d\n", r);
+ return false;
+ }
+
+ ext4_cache_write_back("/mp/", 1);
+ printf("add files to: /mp/dir1\n");
+ for (i = 0; i < len; ++i) {
+ sprintf(path, "/mp/dir1/f%d", i);
+ r = ext4_fopen(&f, path, "wb");
+ if (r != EOK) {
+ printf("\text4_fopen: rc = %d\n", r);
+ return false;
+ }
+ }
+ ext4_cache_write_back("/mp/", 0);
+
+ stop = get_ms();
+ diff = stop - start;
+ dir_ls("/mp/dir1");
+ printf("dir_test: time: %d ms\n", (int)diff);
+ return true;
}
static bool file_test(void)
{
- int r;
- uint32_t size;
- ext4_file f;
- int i;
- clock_t start;
- clock_t stop;
- clock_t diff;
- uint32_t kbps;
- uint64_t size_bytes;
-
- printf("\nfile_test:\n");
- /*Add hello world file.*/
- r = ext4_fopen(&f, "/mp/hello.txt", "wb");
- r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0);
- r = ext4_fclose(&f);
-
- printf("ext4_fopen: write test\n");
- start = get_ms();
- r = ext4_fopen(&f, "/mp/test1", "wb");
- if (r != EOK) {
- printf("\text4_fopen rc = %d\n", r);
- return false;
- }
-
- printf("ext4_write: %d * %d ...\n", rw_szie, rw_count);
- for (i = 0; i < rw_count; ++i) {
-
- memset(wr_buff, i % 10 + '0', rw_szie);
-
- r = ext4_fwrite(&f, wr_buff, rw_szie, &size);
-
- if ((r != EOK) || (size != rw_szie))
- break;
- }
-
- if (i != rw_count) {
- printf("\tfile_test: rw_count = %d\n", i);
- return false;
- }
-
- stop = get_ms();
- diff = stop - start;
- size_bytes = rw_szie * rw_count;
- size_bytes = (size_bytes * 1000) / 1024;
- kbps = (size_bytes) / (diff + 1);
- printf("\twrite time: %d ms\n", (int)diff);
- printf("\twrite speed: %" PRIu32 " KB/s\n", kbps);
- r = ext4_fclose(&f);
-
- printf("ext4_fopen: read test\n");
- start = get_ms();
- r = ext4_fopen(&f, "/mp/test1", "r+");
- if (r != EOK) {
- printf("\text4_fopen rc = %d\n", r);
- return false;
- }
-
- printf("ext4_read: %d * %d ...\n", rw_szie, rw_count);
- for (i = 0; i < rw_count; ++i) {
- memset(wr_buff, i % 10 + '0', rw_szie);
- r = ext4_fread(&f, rd_buff, rw_szie, &size);
-
- if ((r != EOK) || (size != rw_szie))
- break;
-
- if (memcmp(rd_buff, wr_buff, rw_szie)) {
- break;
- }
- }
- if (i != rw_count) {
- printf("\tfile_test: rw_count = %d\n", i);
- return false;
- }
- stop = get_ms();
- diff = stop - start;
- size_bytes = rw_szie * rw_count;
- size_bytes = (size_bytes * 1000) / 1024;
- kbps = (size_bytes) / (diff + 1);
- printf("\tread time: %d ms\n", (int)diff);
- printf("\tread speed: %" PRIu32 " KB/s\n", kbps);
- r = ext4_fclose(&f);
-
- return true;
+ int r;
+ uint32_t size;
+ ext4_file f;
+ int i;
+ clock_t start;
+ clock_t stop;
+ clock_t diff;
+ uint32_t kbps;
+ uint64_t size_bytes;
+
+ printf("\nfile_test:\n");
+ /*Add hello world file.*/
+ r = ext4_fopen(&f, "/mp/hello.txt", "wb");
+ r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0);
+ r = ext4_fclose(&f);
+
+ printf("ext4_fopen: write test\n");
+ start = get_ms();
+ r = ext4_fopen(&f, "/mp/test1", "wb");
+ if (r != EOK) {
+ printf("\text4_fopen rc = %d\n", r);
+ return false;
+ }
+
+ printf("ext4_write: %d * %d ...\n", rw_szie, rw_count);
+ for (i = 0; i < rw_count; ++i) {
+
+ memset(wr_buff, i % 10 + '0', rw_szie);
+
+ r = ext4_fwrite(&f, wr_buff, rw_szie, &size);
+
+ if ((r != EOK) || (size != rw_szie))
+ break;
+ }
+
+ if (i != rw_count) {
+ printf("\tfile_test: rw_count = %d\n", i);
+ return false;
+ }
+
+ stop = get_ms();
+ diff = stop - start;
+ size_bytes = rw_szie * rw_count;
+ size_bytes = (size_bytes * 1000) / 1024;
+ kbps = (size_bytes) / (diff + 1);
+ printf("\twrite time: %d ms\n", (int)diff);
+ printf("\twrite speed: %" PRIu32 " KB/s\n", kbps);
+ r = ext4_fclose(&f);
+
+ printf("ext4_fopen: read test\n");
+ start = get_ms();
+ r = ext4_fopen(&f, "/mp/test1", "r+");
+ if (r != EOK) {
+ printf("\text4_fopen rc = %d\n", r);
+ return false;
+ }
+
+ printf("ext4_read: %d * %d ...\n", rw_szie, rw_count);
+ for (i = 0; i < rw_count; ++i) {
+ memset(wr_buff, i % 10 + '0', rw_szie);
+ r = ext4_fread(&f, rd_buff, rw_szie, &size);
+
+ if ((r != EOK) || (size != rw_szie))
+ break;
+
+ if (memcmp(rd_buff, wr_buff, rw_szie)) {
+ break;
+ }
+ }
+ if (i != rw_count) {
+ printf("\tfile_test: rw_count = %d\n", i);
+ return false;
+ }
+ stop = get_ms();
+ diff = stop - start;
+ size_bytes = rw_szie * rw_count;
+ size_bytes = (size_bytes * 1000) / 1024;
+ kbps = (size_bytes) / (diff + 1);
+ printf("\tread time: %d ms\n", (int)diff);
+ printf("\tread speed: %" PRIu32 " KB/s\n", kbps);
+ r = ext4_fclose(&f);
+
+ return true;
}
static void cleanup(void)
{
- clock_t start;
- clock_t stop;
- clock_t diff;
-
- printf("\ncleanup:\n");
- ext4_fremove("/mp/hello.txt");
- printf("cleanup: remove /mp/test1\n");
- ext4_fremove("/mp/test1");
-
- printf("cleanup: remove /mp/dir1\n");
- start = get_ms();
- ext4_dir_rm("/mp/dir1");
- stop = get_ms();
- diff = stop - start;
- printf("cleanup: time: %d ms\n", (int)diff);
+ clock_t start;
+ clock_t stop;
+ clock_t diff;
+
+ printf("\ncleanup:\n");
+ ext4_fremove("/mp/hello.txt");
+ printf("cleanup: remove /mp/test1\n");
+ ext4_fremove("/mp/test1");
+
+ printf("cleanup: remove /mp/dir1\n");
+ start = get_ms();
+ ext4_dir_rm("/mp/dir1");
+ stop = get_ms();
+ diff = stop - start;
+ printf("cleanup: time: %d ms\n", (int)diff);
}
static bool open_filedev(void)
{
- ext4_filedev_filename(input_name);
- bd = ext4_filedev_get();
- if (!bd) {
- printf("open_filedev: fail\n");
- return false;
- }
- return true;
+ ext4_filedev_filename(input_name);
+ bd = ext4_filedev_get();
+ if (!bd) {
+ printf("open_filedev: fail\n");
+ return false;
+ }
+ return true;
}
static bool open_winpartition(void)
{
#ifdef WIN32
- ext4_io_raw_filename(input_name);
- bd = ext4_io_raw_dev_get();
- if (!bd) {
- printf("open_winpartition: fail\n");
- return false;
- }
- return true;
+ ext4_io_raw_filename(input_name);
+ bd = ext4_io_raw_dev_get();
+ if (!bd) {
+ printf("open_winpartition: fail\n");
+ return false;
+ }
+ return true;
#else
- printf(
- "open_winpartition: this mode should be used only under windows !\n");
- return false;
+ printf("open_winpartition: this mode should be used only under windows "
+ "!\n");
+ return false;
#endif
}
static bool mount(void)
{
- int r;
- if (winpart) {
- if (!open_winpartition())
- return false;
- } else {
- if (!open_filedev())
- return false;
- }
- wr_buff = malloc(rw_szie);
- rd_buff = malloc(rw_szie);
-
- if (!wr_buff || !rd_buff) {
- printf("mount: allocation failed\n");
- return false;
- }
-
- ext4_dmask_set(EXT4_DEBUG_ALL);
-
- r = ext4_device_register(bd, cache_mode ? 0 : bc, "ext4_fs");
- if (r != EOK) {
- printf("ext4_device_register: rc = %d\n", r);
- return false;
- }
-
- r = ext4_mount("ext4_fs", "/mp/");
- if (r != EOK) {
- printf("ext4_mount: rc = %d\n", r);
- return false;
- }
-
- return true;
+ int r;
+ if (winpart) {
+ if (!open_winpartition())
+ return false;
+ } else {
+ if (!open_filedev())
+ return false;
+ }
+ wr_buff = malloc(rw_szie);
+ rd_buff = malloc(rw_szie);
+
+ if (!wr_buff || !rd_buff) {
+ printf("mount: allocation failed\n");
+ return false;
+ }
+
+ ext4_dmask_set(EXT4_DEBUG_ALL);
+
+ r = ext4_device_register(bd, cache_mode ? 0 : bc, "ext4_fs");
+ if (r != EOK) {
+ printf("ext4_device_register: rc = %d\n", r);
+ return false;
+ }
+
+ r = ext4_mount("ext4_fs", "/mp/");
+ if (r != EOK) {
+ printf("ext4_mount: rc = %d\n", r);
+ return false;
+ }
+
+ return true;
}
static bool umount(void)
{
- int r = ext4_umount("/mp/");
- if (r != EOK) {
- printf("ext4_umount: rc = %d", r);
- return false;
- }
- return true;
+ int r = ext4_umount("/mp/");
+ if (r != EOK) {
+ printf("ext4_umount: rc = %d", r);
+ return false;
+ }
+ return true;
}
static bool parse_opt(int argc, char **argv)
{
- int option_index = 0;
- int c;
-
- static struct option long_options[] = {{"in", required_argument, 0, 'a'},
- {"rws", required_argument, 0, 'b'},
- {"rwc", required_argument, 0, 'c'},
- {"cache", required_argument, 0, 'd'},
- {"dirs", required_argument, 0, 'e'},
- {"clean", no_argument, 0, 'f'},
- {"bstat", no_argument, 0, 'g'},
- {"sbstat", no_argument, 0, 'h'},
- {"wpart", no_argument, 0, 'i'},
- {0, 0, 0, 0}};
-
- while (-1 != (c = getopt_long(argc, argv, "a:b:c:d:e:fghi", long_options,
- &option_index))) {
-
- switch (c) {
- case 'a':
- strcpy(input_name, optarg);
- break;
- case 'b':
- rw_szie = atoi(optarg);
- break;
- case 'c':
- rw_count = atoi(optarg);
- break;
- case 'd':
- cache_mode = atoi(optarg);
- break;
- case 'e':
- dir_cnt = atoi(optarg);
- break;
- case 'f':
- cleanup_flag = true;
- break;
- case 'g':
- bstat = true;
- break;
- case 'h':
- sbstat = true;
- break;
- case 'i':
- winpart = true;
- break;
- default:
- printf("%s", usage);
- return false;
- }
- }
- return true;
+ int option_index = 0;
+ int c;
+
+ static struct option long_options[] = {
+ {"in", required_argument, 0, 'a'},
+ {"rws", required_argument, 0, 'b'},
+ {"rwc", required_argument, 0, 'c'},
+ {"cache", required_argument, 0, 'd'},
+ {"dirs", required_argument, 0, 'e'},
+ {"clean", no_argument, 0, 'f'},
+ {"bstat", no_argument, 0, 'g'},
+ {"sbstat", no_argument, 0, 'h'},
+ {"wpart", no_argument, 0, 'i'},
+ {0, 0, 0, 0}};
+
+ while (-1 != (c = getopt_long(argc, argv, "a:b:c:d:e:fghi",
+ long_options, &option_index))) {
+
+ switch (c) {
+ case 'a':
+ strcpy(input_name, optarg);
+ break;
+ case 'b':
+ rw_szie = atoi(optarg);
+ break;
+ case 'c':
+ rw_count = atoi(optarg);
+ break;
+ case 'd':
+ cache_mode = atoi(optarg);
+ break;
+ case 'e':
+ dir_cnt = atoi(optarg);
+ break;
+ case 'f':
+ cleanup_flag = true;
+ break;
+ case 'g':
+ bstat = true;
+ break;
+ case 'h':
+ sbstat = true;
+ break;
+ case 'i':
+ winpart = true;
+ break;
+ default:
+ printf("%s", usage);
+ return false;
+ }
+ }
+ return true;
}
int main(int argc, char **argv)
{
- if (!parse_opt(argc, argv))
- return EXIT_FAILURE;
+ if (!parse_opt(argc, argv))
+ return EXIT_FAILURE;
- printf("test conditions:\n");
- printf("\timput name: %s\n", input_name);
- printf("\trw size: %d\n", rw_szie);
- printf("\trw count: %d\n", rw_count);
- printf("\tcache mode: %s\n", cache_mode ? "dynamic" : "static");
+ printf("test conditions:\n");
+ printf("\timput name: %s\n", input_name);
+ printf("\trw size: %d\n", rw_szie);
+ printf("\trw count: %d\n", rw_count);
+ printf("\tcache mode: %s\n", cache_mode ? "dynamic" : "static");
- if (!mount())
- return EXIT_FAILURE;
+ if (!mount())
+ return EXIT_FAILURE;
- cleanup();
+ cleanup();
- if (sbstat)
- mp_stats();
+ if (sbstat)
+ mp_stats();
- dir_ls("/mp/");
- fflush(stdout);
- if (!dir_test(dir_cnt))
- return EXIT_FAILURE;
+ dir_ls("/mp/");
+ fflush(stdout);
+ if (!dir_test(dir_cnt))
+ return EXIT_FAILURE;
- fflush(stdout);
- if (!file_test())
- return EXIT_FAILURE;
+ fflush(stdout);
+ if (!file_test())
+ return EXIT_FAILURE;
- fflush(stdout);
- dir_ls("/mp/");
+ fflush(stdout);
+ dir_ls("/mp/");
- if (sbstat)
- mp_stats();
+ if (sbstat)
+ mp_stats();
- if (cleanup_flag)
- cleanup();
+ if (cleanup_flag)
+ cleanup();
- if (bstat)
- block_stats();
+ if (bstat)
+ block_stats();
- if (!umount())
- return EXIT_FAILURE;
+ if (!umount())
+ return EXIT_FAILURE;
- printf("\ntest finished\n");
- return EXIT_SUCCESS;
+ printf("\ntest finished\n");
+ return EXIT_SUCCESS;
}
diff --git a/fs_test/lwext4_client.c b/fs_test/lwext4_client.c index a4db7fa..e90a532 100644 --- a/fs_test/lwext4_client.c +++ b/fs_test/lwext4_client.c @@ -70,143 +70,146 @@ Usage: \n\ static int client_connect(void)
{
- int fd = 0;
- struct sockaddr_in serv_addr;
-
- if (winsock_init() < 0) {
- printf("winsock_init error\n");
- exit(-1);
- }
-
- memset(&serv_addr, '0', sizeof(serv_addr));
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- printf("socket() error: %s\n", strerror(errno));
- exit(-1);
- }
-
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(connection_port);
-
- if (!inet_pton(AF_INET, server_addr, &serv_addr.sin_addr)) {
- printf("inet_pton() error\n");
- exit(-1);
- }
-
- if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {
- printf("connect() error: %s\n", strerror(errno));
- exit(-1);
- }
-
- return fd;
+ int fd = 0;
+ struct sockaddr_in serv_addr;
+
+ if (winsock_init() < 0) {
+ printf("winsock_init error\n");
+ exit(-1);
+ }
+
+ memset(&serv_addr, '0', sizeof(serv_addr));
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ printf("socket() error: %s\n", strerror(errno));
+ exit(-1);
+ }
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(connection_port);
+
+ if (!inet_pton(AF_INET, server_addr, &serv_addr.sin_addr)) {
+ printf("inet_pton() error\n");
+ exit(-1);
+ }
+
+ if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {
+ printf("connect() error: %s\n", strerror(errno));
+ exit(-1);
+ }
+
+ return fd;
}
static bool parse_opt(int argc, char **argv)
{
- int option_index = 0;
- int c;
-
- static struct option long_options[] = {{"call", required_argument, 0, 'c'},
- {"port", required_argument, 0, 'p'},
- {"addr", required_argument, 0, 'a'},
- {0, 0, 0, 0}};
-
- while (-1 != (c = getopt_long(argc, argv, "c:p:a:", long_options,
- &option_index))) {
-
- switch (c) {
- case 'a':
- server_addr = optarg;
- break;
- case 'p':
- connection_port = atoi(optarg);
- break;
- case 'c':
- op_code = optarg;
- break;
- default:
- printf("%s", usage);
- return false;
- }
- }
- return true;
+ int option_index = 0;
+ int c;
+
+ static struct option long_options[] = {
+ {"call", required_argument, 0, 'c'},
+ {"port", required_argument, 0, 'p'},
+ {"addr", required_argument, 0, 'a'},
+ {0, 0, 0, 0}};
+
+ while (-1 != (c = getopt_long(argc, argv, "c:p:a:", long_options,
+ &option_index))) {
+
+ switch (c) {
+ case 'a':
+ server_addr = optarg;
+ break;
+ case 'p':
+ connection_port = atoi(optarg);
+ break;
+ case 'c':
+ op_code = optarg;
+ break;
+ default:
+ printf("%s", usage);
+ return false;
+ }
+ }
+ return true;
}
int main(int argc, char *argv[])
{
- int sockfd;
- int n;
- int rc;
- char recvBuff[1024];
-
- if (!parse_opt(argc, argv))
- return -1;
-
- sockfd = client_connect();
-
- n = send(sockfd, op_code, strlen(op_code), 0);
- if (n < 0) {
- printf("\tWrite error: %s fd = %d\n", strerror(errno), sockfd);
- return -1;
- }
-
- n = recv(sockfd, (void *)&rc, sizeof(rc), 0);
- if (n < 0) {
- printf("\tWrite error: %s fd = %d\n", strerror(errno), sockfd);
- return -1;
- }
-
- printf("rc: %d %s\n", rc, strerror(rc));
- if (rc)
- printf("\t%s\n", op_code);
-
- winsock_fini();
- return rc;
+ int sockfd;
+ int n;
+ int rc;
+ char recvBuff[1024];
+
+ if (!parse_opt(argc, argv))
+ return -1;
+
+ sockfd = client_connect();
+
+ n = send(sockfd, op_code, strlen(op_code), 0);
+ if (n < 0) {
+ printf("\tWrite error: %s fd = %d\n", strerror(errno), sockfd);
+ return -1;
+ }
+
+ n = recv(sockfd, (void *)&rc, sizeof(rc), 0);
+ if (n < 0) {
+ printf("\tWrite error: %s fd = %d\n", strerror(errno), sockfd);
+ return -1;
+ }
+
+ printf("rc: %d %s\n", rc, strerror(rc));
+ if (rc)
+ printf("\t%s\n", op_code);
+
+ winsock_fini();
+ return rc;
}
static int winsock_init(void)
{
#if WIN32
- int rc;
- static WSADATA wsaData;
- rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (rc != 0) {
- return -1;
- }
+ int rc;
+ static WSADATA wsaData;
+ rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (rc != 0) {
+ return -1;
+ }
#endif
- return 0;
+ return 0;
}
static void winsock_fini(void)
{
#if WIN32
- WSACleanup();
+ WSACleanup();
#endif
}
#if WIN32
static int inet_pton(int af, const char *src, void *dst)
{
- struct sockaddr_storage ss;
- int size = sizeof(ss);
- char src_copy[INET6_ADDRSTRLEN + 1];
-
- ZeroMemory(&ss, sizeof(ss));
- /* stupid non-const API */
- strncpy(src_copy, src, INET6_ADDRSTRLEN + 1);
- src_copy[INET6_ADDRSTRLEN] = 0;
-
- if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) ==
- 0) {
- switch (af) {
- case AF_INET:
- *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
- return 1;
- case AF_INET6:
- *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
- return 1;
- }
- }
- return 0;
+ struct sockaddr_storage ss;
+ int size = sizeof(ss);
+ char src_copy[INET6_ADDRSTRLEN + 1];
+
+ ZeroMemory(&ss, sizeof(ss));
+ /* stupid non-const API */
+ strncpy(src_copy, src, INET6_ADDRSTRLEN + 1);
+ src_copy[INET6_ADDRSTRLEN] = 0;
+
+ if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss,
+ &size) == 0) {
+ switch (af) {
+ case AF_INET:
+ *(struct in_addr *)dst =
+ ((struct sockaddr_in *)&ss)->sin_addr;
+ return 1;
+ case AF_INET6:
+ *(struct in6_addr *)dst =
+ ((struct sockaddr_in6 *)&ss)->sin6_addr;
+ return 1;
+ }
+ }
+ return 0;
}
#endif
diff --git a/fs_test/lwext4_server.c b/fs_test/lwext4_server.c index 865f985..4c9c96a 100644 --- a/fs_test/lwext4_server.c +++ b/fs_test/lwext4_server.c @@ -96,24 +96,24 @@ Usage: \n\ /**@brief Open file instance descriptor.*/
struct lwext4_files {
- char name[255];
- ext4_file fd;
+ char name[255];
+ ext4_file fd;
};
/**@brief Open directory instance descriptor.*/
struct lwext4_dirs {
- char name[255];
- ext4_dir fd;
+ char name[255];
+ ext4_dir fd;
};
/**@brief Library call opcode.*/
struct lwext4_op_codes {
- char *func;
+ char *func;
};
/**@brief Library call wraper.*/
struct lwext4_call {
- int (*lwext4_call)(char *p);
+ int (*lwext4_call)(char *p);
};
/**@brief */
@@ -185,22 +185,22 @@ int _stats_check(char *p); /**@brief */
static struct lwext4_call op_call[] = {
_device_register, /*PARAMS(3): 0 cache_mode dev_name */
- _mount, /*PARAMS(2): dev_name mount_point */
- _umount, /*PARAMS(1): mount_point */
+ _mount, /*PARAMS(2): dev_name mount_point */
+ _umount, /*PARAMS(1): mount_point */
_mount_point_stats, /*PARAMS(2): mount_point, 0 */
_cache_write_back, /*PARAMS(2): mount_point, en */
- _fremove, /*PARAMS(1): path */
- _fopen, /*PARAMS(2): fid path flags */
- _fclose, /*PARAMS(1): fid */
- _fread, /*PARAMS(4): fid 0 len 0 */
- _fwrite, /*PARAMS(4): fid 0 len 0 */
- _fseek, /*PARAMS(2): fid off origin */
- _ftell, /*PARAMS(2): fid exp */
- _fsize, /*PARAMS(2): fid exp */
- _dir_rm, /*PARAMS(1): path */
- _dir_mk, /*PARAMS(1): path */
- _dir_open, /*PARAMS(2): did, path */
- _dir_close, /*PARAMS(1): did */
+ _fremove, /*PARAMS(1): path */
+ _fopen, /*PARAMS(2): fid path flags */
+ _fclose, /*PARAMS(1): fid */
+ _fread, /*PARAMS(4): fid 0 len 0 */
+ _fwrite, /*PARAMS(4): fid 0 len 0 */
+ _fseek, /*PARAMS(2): fid off origin */
+ _ftell, /*PARAMS(2): fid exp */
+ _fsize, /*PARAMS(2): fid exp */
+ _dir_rm, /*PARAMS(1): path */
+ _dir_mk, /*PARAMS(1): path */
+ _dir_open, /*PARAMS(2): did, path */
+ _dir_close, /*PARAMS(1): did */
_dir_entry_get, /*PARAMS(2): did, exp */
_multi_fcreate, /*PARAMS(3): path prefix cnt */
@@ -215,915 +215,930 @@ static struct lwext4_call op_call[] = { static clock_t get_ms(void)
{
- struct timeval t;
- gettimeofday(&t, NULL);
- return (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ return (t.tv_sec * 1000) + (t.tv_usec / 1000);
}
/**@brief */
static int exec_op_code(char *opcode)
{
- int i;
- int r = -1;
+ int i;
+ int r = -1;
- for (i = 0; i < sizeof(op_codes) / sizeof(op_codes[0]); ++i) {
+ for (i = 0; i < sizeof(op_codes) / sizeof(op_codes[0]); ++i) {
- if (strncmp(op_codes[i].func, opcode, strlen(op_codes[i].func)))
- continue;
+ if (strncmp(op_codes[i].func, opcode, strlen(op_codes[i].func)))
+ continue;
- if (opcode[strlen(op_codes[i].func)] != ' ')
- continue;
+ if (opcode[strlen(op_codes[i].func)] != ' ')
+ continue;
- printf("%s\n", opcode);
- opcode += strlen(op_codes[i].func);
- /*Call*/
+ printf("%s\n", opcode);
+ opcode += strlen(op_codes[i].func);
+ /*Call*/
- clock_t t = get_ms();
- r = op_call[i].lwext4_call(opcode);
+ clock_t t = get_ms();
+ r = op_call[i].lwext4_call(opcode);
- printf("rc: %d, time: %ums\n", r, (unsigned int)(get_ms() - t));
+ printf("rc: %d, time: %ums\n", r, (unsigned int)(get_ms() - t));
- break;
- }
+ break;
+ }
- return r;
+ return r;
}
static int server_open(void)
{
- int fd = 0;
- struct sockaddr_in serv_addr;
-
- memset(&serv_addr, 0, sizeof(serv_addr));
-
- if (winsock_init() < 0) {
- printf("winsock_init() error\n");
- exit(-1);
- }
-
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- printf("socket() error: %s\n", strerror(errno));
- exit(-1);
- }
-
- int yes = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(int))) {
- printf("setsockopt() error: %s\n", strerror(errno));
- exit(-1);
- }
-
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- serv_addr.sin_port = htons(connection_port);
-
- if (bind(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {
- printf("bind() error: %s\n", strerror(errno));
- exit(-1);
- }
-
- if (listen(fd, 1)) {
- printf("listen() error: %s\n", strerror(errno));
- exit(-1);
- }
-
- return fd;
+ int fd = 0;
+ struct sockaddr_in serv_addr;
+
+ memset(&serv_addr, 0, sizeof(serv_addr));
+
+ if (winsock_init() < 0) {
+ printf("winsock_init() error\n");
+ exit(-1);
+ }
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ printf("socket() error: %s\n", strerror(errno));
+ exit(-1);
+ }
+
+ int yes = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes,
+ sizeof(int))) {
+ printf("setsockopt() error: %s\n", strerror(errno));
+ exit(-1);
+ }
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(connection_port);
+
+ if (bind(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {
+ printf("bind() error: %s\n", strerror(errno));
+ exit(-1);
+ }
+
+ if (listen(fd, 1)) {
+ printf("listen() error: %s\n", strerror(errno));
+ exit(-1);
+ }
+
+ return fd;
}
static bool parse_opt(int argc, char **argv)
{
- int option_index = 0;
- int c;
-
- static struct option long_options[] = {
- {"image", required_argument, 0, 'i'},
- {"port", required_argument, 0, 'p'},
- {"verbose", required_argument, 0, 'v'},
- {"winpart", required_argument, 0, 'w'},
- {"cache_wb", required_argument, 0, 'c'},
- {0, 0, 0, 0}};
-
- while (-1 != (c = getopt_long(argc, argv, "c:i:p:v:w:", long_options,
- &option_index))) {
-
- switch (c) {
- case 'i':
- ext4_fname = optarg;
- break;
- case 'p':
- connection_port = atoi(optarg);
- break;
- case 'v':
- verbose = atoi(optarg);
- break;
- case 'c':
- cache_wb = atoi(optarg);
- break;
- case 'w':
- winpart = atoi(optarg);
- break;
- default:
- printf("%s", usage);
- return false;
- }
- }
- return true;
+ int option_index = 0;
+ int c;
+
+ static struct option long_options[] = {
+ {"image", required_argument, 0, 'i'},
+ {"port", required_argument, 0, 'p'},
+ {"verbose", required_argument, 0, 'v'},
+ {"winpart", required_argument, 0, 'w'},
+ {"cache_wb", required_argument, 0, 'c'},
+ {0, 0, 0, 0}};
+
+ while (-1 != (c = getopt_long(argc, argv, "c:i:p:v:w:", long_options,
+ &option_index))) {
+
+ switch (c) {
+ case 'i':
+ ext4_fname = optarg;
+ break;
+ case 'p':
+ connection_port = atoi(optarg);
+ break;
+ case 'v':
+ verbose = atoi(optarg);
+ break;
+ case 'c':
+ cache_wb = atoi(optarg);
+ break;
+ case 'w':
+ winpart = atoi(optarg);
+ break;
+ default:
+ printf("%s", usage);
+ return false;
+ }
+ }
+ return true;
}
int main(int argc, char *argv[])
{
- int n;
- int listenfd;
- int connfd;
- char op_code[128];
+ int n;
+ int listenfd;
+ int connfd;
+ char op_code[128];
- if (!parse_opt(argc, argv))
- return -1;
+ if (!parse_opt(argc, argv))
+ return -1;
- listenfd = server_open();
+ listenfd = server_open();
- printf("lwext4_server: listening on port: %d\n", connection_port);
+ printf("lwext4_server: listening on port: %d\n", connection_port);
- memset(write_buffer, RW_BUFFER_PATERN, MAX_RW_BUFFER);
- while (1) {
- connfd = accept(listenfd, (struct sockaddr *)NULL, NULL);
+ memset(write_buffer, RW_BUFFER_PATERN, MAX_RW_BUFFER);
+ while (1) {
+ connfd = accept(listenfd, (struct sockaddr *)NULL, NULL);
- n = recv(connfd, op_code, sizeof(op_code), 0);
+ n = recv(connfd, op_code, sizeof(op_code), 0);
- if (n < 0) {
- printf("recv() error: %s fd = %d\n", strerror(errno), connfd);
- break;
- }
+ if (n < 0) {
+ printf("recv() error: %s fd = %d\n", strerror(errno),
+ connfd);
+ break;
+ }
- op_code[n] = 0;
+ op_code[n] = 0;
- int r = exec_op_code(op_code);
+ int r = exec_op_code(op_code);
- n = send(connfd, (void *)&r, sizeof(r), 0);
- if (n < 0) {
- printf("send() error: %s fd = %d\n", strerror(errno), connfd);
- break;
- }
+ n = send(connfd, (void *)&r, sizeof(r), 0);
+ if (n < 0) {
+ printf("send() error: %s fd = %d\n", strerror(errno),
+ connfd);
+ break;
+ }
- close(connfd);
- }
+ close(connfd);
+ }
- winsock_fini();
- return 0;
+ winsock_fini();
+ return 0;
}
int _device_register(char *p)
{
- int dev;
- int cache_mode;
- char dev_name[32];
+ int dev;
+ int cache_mode;
+ char dev_name[32];
- if (sscanf(p, "%d %d %s", &dev, &cache_mode, dev_name) != 3) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%d %d %s", &dev, &cache_mode, dev_name) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
#ifdef WIN32
- if (winpart) {
- ext4_io_raw_filename(ext4_fname);
- bd = ext4_io_raw_dev_get();
+ if (winpart) {
+ ext4_io_raw_filename(ext4_fname);
+ bd = ext4_io_raw_dev_get();
- } else
+ } else
#endif
- {
- ext4_filedev_filename(ext4_fname);
- bd = ext4_filedev_get();
- }
- return ext4_device_register(bd, 0, dev_name);
+ {
+ ext4_filedev_filename(ext4_fname);
+ bd = ext4_filedev_get();
+ }
+ return ext4_device_register(bd, 0, dev_name);
}
int _mount(char *p)
{
- char dev_name[32];
- char mount_point[32];
- int rc;
-
- if (sscanf(p, "%s %s", dev_name, mount_point) != 2) {
- printf("Param list error\n");
- return -1;
- }
-
- rc = ext4_mount(dev_name, mount_point);
- if (cache_wb)
- ext4_cache_write_back(mount_point, 1);
- return rc;
+ char dev_name[32];
+ char mount_point[32];
+ int rc;
+
+ if (sscanf(p, "%s %s", dev_name, mount_point) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ rc = ext4_mount(dev_name, mount_point);
+ if (cache_wb)
+ ext4_cache_write_back(mount_point, 1);
+ return rc;
}
int _umount(char *p)
{
- char mount_point[32];
+ char mount_point[32];
- if (sscanf(p, "%s", mount_point) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s", mount_point) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- if (cache_wb)
- ext4_cache_write_back(mount_point, 0);
+ if (cache_wb)
+ ext4_cache_write_back(mount_point, 0);
- return ext4_umount(mount_point);
+ return ext4_umount(mount_point);
}
int _mount_point_stats(char *p)
{
- char mount_point[32];
- int d;
- int rc;
- struct ext4_mount_stats stats;
+ char mount_point[32];
+ int d;
+ int rc;
+ struct ext4_mount_stats stats;
- if (sscanf(p, "%s %d", mount_point, &d) != 2) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s %d", mount_point, &d) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
- rc = ext4_mount_point_stats(mount_point, &stats);
+ rc = ext4_mount_point_stats(mount_point, &stats);
- if (rc != EOK)
- return rc;
+ if (rc != EOK)
+ return rc;
- if (verbose) {
- printf("\tinodes_count = %d\n", stats.inodes_count);
- printf("\tfree_inodes_count = %d\n", stats.free_inodes_count);
- printf("\tblocks_count = %llu\n", stats.blocks_count);
- printf("\tfree_blocks_count = %llu\n", stats.free_blocks_count);
+ if (verbose) {
+ printf("\tinodes_count = %d\n", stats.inodes_count);
+ printf("\tfree_inodes_count = %d\n", stats.free_inodes_count);
+ printf("\tblocks_count = %llu\n", stats.blocks_count);
+ printf("\tfree_blocks_count = %llu\n", stats.free_blocks_count);
- printf("\tblock_size = %d\n", stats.block_size);
- printf("\tblock_group_count = %d\n", stats.block_group_count);
- printf("\tblocks_per_group = %d\n", stats.blocks_per_group);
- printf("\tinodes_per_group = %d\n", stats.inodes_per_group);
+ printf("\tblock_size = %d\n", stats.block_size);
+ printf("\tblock_group_count = %d\n", stats.block_group_count);
+ printf("\tblocks_per_group = %d\n", stats.blocks_per_group);
+ printf("\tinodes_per_group = %d\n", stats.inodes_per_group);
- printf("\tvolume_name = %s\n", stats.volume_name);
- }
+ printf("\tvolume_name = %s\n", stats.volume_name);
+ }
- return rc;
+ return rc;
}
int _cache_write_back(char *p)
{
- char mount_point[32];
- int en;
+ char mount_point[32];
+ int en;
- if (sscanf(p, "%s %d", mount_point, &en) != 2) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s %d", mount_point, &en) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
- return ext4_cache_write_back(mount_point, en);
+ return ext4_cache_write_back(mount_point, en);
}
int _fremove(char *p)
{
- char path[255];
+ char path[255];
- if (sscanf(p, "%s", path) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s", path) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- return ext4_fremove(path);
+ return ext4_fremove(path);
}
int _fopen(char *p)
{
- int fid = MAX_FILES;
- char path[256];
- char flags[8];
- int rc;
+ int fid = MAX_FILES;
+ char path[256];
+ char flags[8];
+ int rc;
- if (sscanf(p, "%d %s %s", &fid, path, flags) != 3) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%d %s %s", &fid, path, flags) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
- rc = ext4_fopen(&file_tab[fid].fd, path, flags);
+ rc = ext4_fopen(&file_tab[fid].fd, path, flags);
- if (rc == EOK)
- strcpy(file_tab[fid].name, path);
+ if (rc == EOK)
+ strcpy(file_tab[fid].name, path);
- return rc;
+ return rc;
}
int _fclose(char *p)
{
- int fid = MAX_FILES;
- int rc;
+ int fid = MAX_FILES;
+ int rc;
- if (sscanf(p, "%d", &fid) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%d", &fid) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
- if (file_tab[fid].name[0] == 0) {
- printf("File id empty\n");
- return -1;
- }
+ if (file_tab[fid].name[0] == 0) {
+ printf("File id empty\n");
+ return -1;
+ }
- rc = ext4_fclose(&file_tab[fid].fd);
+ rc = ext4_fclose(&file_tab[fid].fd);
- if (rc == EOK)
- file_tab[fid].name[0] = 0;
+ if (rc == EOK)
+ file_tab[fid].name[0] = 0;
- return rc;
+ return rc;
}
int _fread(char *p)
{
- int fid = MAX_FILES;
- int len;
- int d;
- int rc;
- int rb;
-
- if (sscanf(p, "%d %d %d %d", &fid, &d, &len, &d) != 4) {
- printf("Param list error\n");
- return -1;
- }
-
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
-
- if (file_tab[fid].name[0] == 0) {
- printf("File id empty\n");
- return -1;
- }
-
- while (len) {
- d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
-
- memset(read_buffer, 0, MAX_RW_BUFFER);
- rc = ext4_fread(&file_tab[fid].fd, read_buffer, d, &rb);
-
- if (rc != EOK)
- break;
-
- if (rb != d) {
- printf("Read count error\n");
- return -1;
- }
-
- if (memcmp(read_buffer, write_buffer, d)) {
- printf("Read compare error\n");
- return -1;
- }
-
- len -= d;
- }
-
- return rc;
+ int fid = MAX_FILES;
+ int len;
+ int d;
+ int rc;
+ int rb;
+
+ if (sscanf(p, "%d %d %d %d", &fid, &d, &len, &d) != 4) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
+
+ if (file_tab[fid].name[0] == 0) {
+ printf("File id empty\n");
+ return -1;
+ }
+
+ while (len) {
+ d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
+
+ memset(read_buffer, 0, MAX_RW_BUFFER);
+ rc = ext4_fread(&file_tab[fid].fd, read_buffer, d, &rb);
+
+ if (rc != EOK)
+ break;
+
+ if (rb != d) {
+ printf("Read count error\n");
+ return -1;
+ }
+
+ if (memcmp(read_buffer, write_buffer, d)) {
+ printf("Read compare error\n");
+ return -1;
+ }
+
+ len -= d;
+ }
+
+ return rc;
}
int _fwrite(char *p)
{
- int fid = MAX_FILES;
- int len;
- int d;
- int rc;
- int wb;
-
- if (sscanf(p, "%d %d %d %d", &fid, &d, &len, &d) != 4) {
- printf("Param list error\n");
- return -1;
- }
-
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
-
- if (file_tab[fid].name[0] == 0) {
- printf("File id empty\n");
- return -1;
- }
-
- while (len) {
- d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
- rc = ext4_fwrite(&file_tab[fid].fd, write_buffer, d, &wb);
-
- if (rc != EOK)
- break;
-
- if (wb != d) {
- printf("Write count error\n");
- return -1;
- }
-
- len -= d;
- }
-
- return rc;
+ int fid = MAX_FILES;
+ int len;
+ int d;
+ int rc;
+ int wb;
+
+ if (sscanf(p, "%d %d %d %d", &fid, &d, &len, &d) != 4) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
+
+ if (file_tab[fid].name[0] == 0) {
+ printf("File id empty\n");
+ return -1;
+ }
+
+ while (len) {
+ d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
+ rc = ext4_fwrite(&file_tab[fid].fd, write_buffer, d, &wb);
+
+ if (rc != EOK)
+ break;
+
+ if (wb != d) {
+ printf("Write count error\n");
+ return -1;
+ }
+
+ len -= d;
+ }
+
+ return rc;
}
int _fseek(char *p)
{
- int fid = MAX_FILES;
- int off;
- int origin;
-
- if (sscanf(p, "%d %d %d", &fid, &off, &origin) != 3) {
- printf("Param list error\n");
- return -1;
- }
-
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
-
- if (file_tab[fid].name[0] == 0) {
- printf("File id empty\n");
- return -1;
- }
-
- return ext4_fseek(&file_tab[fid].fd, off, origin);
+ int fid = MAX_FILES;
+ int off;
+ int origin;
+
+ if (sscanf(p, "%d %d %d", &fid, &off, &origin) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
+
+ if (file_tab[fid].name[0] == 0) {
+ printf("File id empty\n");
+ return -1;
+ }
+
+ return ext4_fseek(&file_tab[fid].fd, off, origin);
}
int _ftell(char *p)
{
- int fid = MAX_FILES;
- uint32_t exp_pos;
-
- if (sscanf(p, "%d %u", &fid, &exp_pos) != 2) {
- printf("Param list error\n");
- return -1;
- }
-
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
-
- if (file_tab[fid].name[0] == 0) {
- printf("File id empty\n");
- return -1;
- }
-
- if (exp_pos != ext4_ftell(&file_tab[fid].fd)) {
- printf("Expected filepos error\n");
- return -1;
- }
-
- return EOK;
+ int fid = MAX_FILES;
+ uint32_t exp_pos;
+
+ if (sscanf(p, "%d %u", &fid, &exp_pos) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
+
+ if (file_tab[fid].name[0] == 0) {
+ printf("File id empty\n");
+ return -1;
+ }
+
+ if (exp_pos != ext4_ftell(&file_tab[fid].fd)) {
+ printf("Expected filepos error\n");
+ return -1;
+ }
+
+ return EOK;
}
int _fsize(char *p)
{
- int fid = MAX_FILES;
- uint32_t exp_size;
-
- if (sscanf(p, "%d %u", &fid, &exp_size) != 2) {
- printf("Param list error\n");
- return -1;
- }
-
- if (!(fid < MAX_FILES)) {
- printf("File id too big\n");
- return -1;
- }
-
- if (file_tab[fid].name[0] == 0) {
- printf("File id empty\n");
- return -1;
- }
-
- if (exp_size != ext4_fsize(&file_tab[fid].fd)) {
- printf("Expected filesize error\n");
- return -1;
- }
-
- return EOK;
+ int fid = MAX_FILES;
+ uint32_t exp_size;
+
+ if (sscanf(p, "%d %u", &fid, &exp_size) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ if (!(fid < MAX_FILES)) {
+ printf("File id too big\n");
+ return -1;
+ }
+
+ if (file_tab[fid].name[0] == 0) {
+ printf("File id empty\n");
+ return -1;
+ }
+
+ if (exp_size != ext4_fsize(&file_tab[fid].fd)) {
+ printf("Expected filesize error\n");
+ return -1;
+ }
+
+ return EOK;
}
int _dir_rm(char *p)
{
- char path[255];
+ char path[255];
- if (sscanf(p, "%s", path) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s", path) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- return ext4_dir_rm(path);
+ return ext4_dir_rm(path);
}
int _dir_mk(char *p)
{
- char path[255];
+ char path[255];
- if (sscanf(p, "%s", path) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s", path) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- return ext4_dir_mk(path);
+ return ext4_dir_mk(path);
}
int _dir_open(char *p)
{
- int did = MAX_DIRS;
- char path[255];
- int rc;
+ int did = MAX_DIRS;
+ char path[255];
+ int rc;
- if (sscanf(p, "%d %s", &did, path) != 2) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%d %s", &did, path) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
- if (!(did < MAX_DIRS)) {
- printf("Dir id too big\n");
- return -1;
- }
+ if (!(did < MAX_DIRS)) {
+ printf("Dir id too big\n");
+ return -1;
+ }
- rc = ext4_dir_open(&dir_tab[did].fd, path);
+ rc = ext4_dir_open(&dir_tab[did].fd, path);
- if (rc == EOK)
- strcpy(dir_tab[did].name, path);
+ if (rc == EOK)
+ strcpy(dir_tab[did].name, path);
- return rc;
+ return rc;
}
int _dir_close(char *p)
{
- int did = MAX_DIRS;
- int rc;
+ int did = MAX_DIRS;
+ int rc;
- if (sscanf(p, "%d", &did) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%d", &did) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- if (!(did < MAX_DIRS)) {
- printf("Dir id too big\n");
- return -1;
- }
+ if (!(did < MAX_DIRS)) {
+ printf("Dir id too big\n");
+ return -1;
+ }
- if (dir_tab[did].name[0] == 0) {
- printf("Dir id empty\n");
- return -1;
- }
+ if (dir_tab[did].name[0] == 0) {
+ printf("Dir id empty\n");
+ return -1;
+ }
- rc = ext4_dir_close(&dir_tab[did].fd);
+ rc = ext4_dir_close(&dir_tab[did].fd);
- if (rc == EOK)
- dir_tab[did].name[0] = 0;
+ if (rc == EOK)
+ dir_tab[did].name[0] = 0;
- return rc;
+ return rc;
}
int _dir_entry_get(char *p)
{
- int did = MAX_DIRS;
- int exp;
- char name[256];
-
- if (sscanf(p, "%d %d", &did, &exp) != 2) {
- printf("Param list error\n");
- return -1;
- }
-
- if (!(did < MAX_DIRS)) {
- printf("Dir id too big\n");
- return -1;
- }
-
- if (dir_tab[did].name[0] == 0) {
- printf("Dir id empty\n");
- return -1;
- }
-
- int idx = 0;
- const ext4_direntry *d;
-
- while ((d = ext4_dir_entry_next(&dir_tab[did].fd)) != NULL) {
-
- idx++;
- memcpy(name, d->name, d->name_length);
- name[d->name_length] = 0;
- if (verbose) {
- printf("\t%s %s\n", entry_to_str(d->inode_type), name);
- }
- }
-
- if (idx < 2) {
- printf("Minumum dir entry error\n");
- return -1;
- }
-
- if ((idx - 2) != exp) {
- printf("Expected dir entry error\n");
- return -1;
- }
-
- return EOK;
+ int did = MAX_DIRS;
+ int exp;
+ char name[256];
+
+ if (sscanf(p, "%d %d", &did, &exp) != 2) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ if (!(did < MAX_DIRS)) {
+ printf("Dir id too big\n");
+ return -1;
+ }
+
+ if (dir_tab[did].name[0] == 0) {
+ printf("Dir id empty\n");
+ return -1;
+ }
+
+ int idx = 0;
+ const ext4_direntry *d;
+
+ while ((d = ext4_dir_entry_next(&dir_tab[did].fd)) != NULL) {
+
+ idx++;
+ memcpy(name, d->name, d->name_length);
+ name[d->name_length] = 0;
+ if (verbose) {
+ printf("\t%s %s\n", entry_to_str(d->inode_type), name);
+ }
+ }
+
+ if (idx < 2) {
+ printf("Minumum dir entry error\n");
+ return -1;
+ }
+
+ if ((idx - 2) != exp) {
+ printf("Expected dir entry error\n");
+ return -1;
+ }
+
+ return EOK;
}
int _multi_fcreate(char *p)
{
- char path[256];
- char path1[256];
- char prefix[32];
- int cnt;
- int rc;
- int i;
- ext4_file fd;
-
- if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
- printf("Param list error\n");
- return -1;
- }
-
- for (i = 0; i < cnt; ++i) {
- sprintf(path1, "%s%s%d", path, prefix, i);
- rc = ext4_fopen(&fd, path1, "wb+");
-
- if (rc != EOK)
- break;
- }
-
- return rc;
+ char path[256];
+ char path1[256];
+ char prefix[32];
+ int cnt;
+ int rc;
+ int i;
+ ext4_file fd;
+
+ if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ for (i = 0; i < cnt; ++i) {
+ sprintf(path1, "%s%s%d", path, prefix, i);
+ rc = ext4_fopen(&fd, path1, "wb+");
+
+ if (rc != EOK)
+ break;
+ }
+
+ return rc;
}
int _multi_fwrite(char *p)
{
- char path[256];
- char path1[256];
- char prefix[32];
- int cnt;
- int len, ll;
- int rc;
- int i, d, wb;
- ext4_file fd;
-
- if (sscanf(p, "%s %s %d %d", path, prefix, &cnt, &ll) != 4) {
- printf("Param list error\n");
- return -1;
- }
-
- for (i = 0; i < cnt; ++i) {
- sprintf(path1, "%s%s%d", path, prefix, i);
- rc = ext4_fopen(&fd, path1, "rb+");
-
- if (rc != EOK)
- break;
-
- len = ll;
- while (len) {
- d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
- rc = ext4_fwrite(&fd, write_buffer, d, &wb);
-
- if (rc != EOK)
- break;
-
- if (wb != d) {
- printf("Write count error\n");
- return -1;
- }
-
- len -= d;
- }
- }
-
- return rc;
+ char path[256];
+ char path1[256];
+ char prefix[32];
+ int cnt;
+ int len, ll;
+ int rc;
+ int i, d, wb;
+ ext4_file fd;
+
+ if (sscanf(p, "%s %s %d %d", path, prefix, &cnt, &ll) != 4) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ for (i = 0; i < cnt; ++i) {
+ sprintf(path1, "%s%s%d", path, prefix, i);
+ rc = ext4_fopen(&fd, path1, "rb+");
+
+ if (rc != EOK)
+ break;
+
+ len = ll;
+ while (len) {
+ d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
+ rc = ext4_fwrite(&fd, write_buffer, d, &wb);
+
+ if (rc != EOK)
+ break;
+
+ if (wb != d) {
+ printf("Write count error\n");
+ return -1;
+ }
+
+ len -= d;
+ }
+ }
+
+ return rc;
}
int _multi_fread(char *p)
{
- char path[256];
- char path1[256];
- char prefix[32];
- int cnt;
- int len, ll;
- int rc;
- int i, d, rb;
- ext4_file fd;
-
- if (sscanf(p, "%s %s %d %d", path, prefix, &cnt, &ll) != 4) {
- printf("Param list error\n");
- return -1;
- }
-
- for (i = 0; i < cnt; ++i) {
- sprintf(path1, "%s%s%d", path, prefix, i);
- rc = ext4_fopen(&fd, path1, "rb+");
-
- if (rc != EOK)
- break;
-
- len = ll;
- while (len) {
- d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
-
- memset(read_buffer, 0, MAX_RW_BUFFER);
- rc = ext4_fread(&fd, read_buffer, d, &rb);
-
- if (rc != EOK)
- break;
-
- if (rb != d) {
- printf("Read count error\n");
- return -1;
- }
-
- if (memcmp(read_buffer, write_buffer, d)) {
- printf("Read compare error\n");
- return -1;
- }
-
- len -= d;
- }
- }
-
- return rc;
+ char path[256];
+ char path1[256];
+ char prefix[32];
+ int cnt;
+ int len, ll;
+ int rc;
+ int i, d, rb;
+ ext4_file fd;
+
+ if (sscanf(p, "%s %s %d %d", path, prefix, &cnt, &ll) != 4) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ for (i = 0; i < cnt; ++i) {
+ sprintf(path1, "%s%s%d", path, prefix, i);
+ rc = ext4_fopen(&fd, path1, "rb+");
+
+ if (rc != EOK)
+ break;
+
+ len = ll;
+ while (len) {
+ d = len > MAX_RW_BUFFER ? MAX_RW_BUFFER : len;
+
+ memset(read_buffer, 0, MAX_RW_BUFFER);
+ rc = ext4_fread(&fd, read_buffer, d, &rb);
+
+ if (rc != EOK)
+ break;
+
+ if (rb != d) {
+ printf("Read count error\n");
+ return -1;
+ }
+
+ if (memcmp(read_buffer, write_buffer, d)) {
+ printf("Read compare error\n");
+ return -1;
+ }
+
+ len -= d;
+ }
+ }
+
+ return rc;
}
int _multi_fremove(char *p)
{
- char path[256];
- char path1[256];
- char prefix[32];
- int cnt, i, rc;
-
- if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
- printf("Param list error\n");
- return -1;
- }
-
- for (i = 0; i < cnt; ++i) {
- sprintf(path1, "%s%s%d", path, prefix, i);
- rc = ext4_fremove(path1);
- if (rc != EOK)
- break;
- }
-
- return rc;
+ char path[256];
+ char path1[256];
+ char prefix[32];
+ int cnt, i, rc;
+
+ if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ for (i = 0; i < cnt; ++i) {
+ sprintf(path1, "%s%s%d", path, prefix, i);
+ rc = ext4_fremove(path1);
+ if (rc != EOK)
+ break;
+ }
+
+ return rc;
}
int _multi_dcreate(char *p)
{
- char path[256];
- char path1[256];
- char prefix[32];
- int cnt, i, rc;
-
- if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
- printf("Param list error\n");
- return -1;
- }
-
- for (i = 0; i < cnt; ++i) {
- sprintf(path1, "%s%s%d", path, prefix, i);
- rc = ext4_dir_mk(path1);
- if (rc != EOK)
- break;
- }
-
- return rc;
+ char path[256];
+ char path1[256];
+ char prefix[32];
+ int cnt, i, rc;
+
+ if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ for (i = 0; i < cnt; ++i) {
+ sprintf(path1, "%s%s%d", path, prefix, i);
+ rc = ext4_dir_mk(path1);
+ if (rc != EOK)
+ break;
+ }
+
+ return rc;
}
int _multi_dremove(char *p)
{
- char path[256];
- char path1[256];
- char prefix[32];
- int cnt, i, rc;
-
- if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
- printf("Param list error\n");
- return -1;
- }
-
- for (i = 0; i < cnt; ++i) {
- sprintf(path1, "%s%s%d", path, prefix, i);
- rc = ext4_dir_rm(path1);
- if (rc != EOK)
- break;
- }
-
- return rc;
+ char path[256];
+ char path1[256];
+ char prefix[32];
+ int cnt, i, rc;
+
+ if (sscanf(p, "%s %s %d", path, prefix, &cnt) != 3) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ for (i = 0; i < cnt; ++i) {
+ sprintf(path1, "%s%s%d", path, prefix, i);
+ rc = ext4_dir_rm(path1);
+ if (rc != EOK)
+ break;
+ }
+
+ return rc;
}
struct ext4_mount_stats saved_stats;
int _stats_save(char *p)
{
- char path[256];
+ char path[256];
- if (sscanf(p, "%s", path) != 1) {
- printf("Param list error\n");
- return -1;
- }
+ if (sscanf(p, "%s", path) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
- return ext4_mount_point_stats(path, &saved_stats);
+ return ext4_mount_point_stats(path, &saved_stats);
}
int _stats_check(char *p)
{
- char path[256];
- int rc;
-
- struct ext4_mount_stats actual_stats;
-
- if (sscanf(p, "%s", path) != 1) {
- printf("Param list error\n");
- return -1;
- }
-
- rc = ext4_mount_point_stats(path, &actual_stats);
-
- if (rc != EOK)
- return rc;
-
- if (memcmp(&saved_stats, &actual_stats, sizeof(struct ext4_mount_stats))) {
- if (verbose) {
- printf("\tMount point stats error:\n");
- printf("\tsaved_stats:\n");
- printf("\tinodes_count = %d\n", saved_stats.inodes_count);
- printf("\tfree_inodes_count = %d\n", saved_stats.free_inodes_count);
- printf("\tblocks_count = %llu\n", saved_stats.blocks_count);
- printf("\tfree_blocks_count = %llu\n",
- saved_stats.free_blocks_count);
- printf("\tblock_size = %d\n", saved_stats.block_size);
- printf("\tblock_group_count = %d\n", saved_stats.block_group_count);
- printf("\tblocks_per_group = %d\n", saved_stats.blocks_per_group);
- printf("\tinodes_per_group = %d\n", saved_stats.inodes_per_group);
- printf("\tvolume_name = %s\n", saved_stats.volume_name);
- printf("\tactual_stats:\n");
- printf("\tinodes_count = %d\n", actual_stats.inodes_count);
- printf("\tfree_inodes_count = %d\n",
- actual_stats.free_inodes_count);
- printf("\tblocks_count = %llu\n", actual_stats.blocks_count);
- printf("\tfree_blocks_count = %llu\n",
- actual_stats.free_blocks_count);
- printf("\tblock_size = %d\n", actual_stats.block_size);
- printf("\tblock_group_count = %d\n",
- actual_stats.block_group_count);
- printf("\tblocks_per_group = %d\n", actual_stats.blocks_per_group);
- printf("\tinodes_per_group = %d\n", actual_stats.inodes_per_group);
- printf("\tvolume_name = %s\n", actual_stats.volume_name);
- }
- return -1;
- }
-
- return rc;
+ char path[256];
+ int rc;
+
+ struct ext4_mount_stats actual_stats;
+
+ if (sscanf(p, "%s", path) != 1) {
+ printf("Param list error\n");
+ return -1;
+ }
+
+ rc = ext4_mount_point_stats(path, &actual_stats);
+
+ if (rc != EOK)
+ return rc;
+
+ if (memcmp(&saved_stats, &actual_stats,
+ sizeof(struct ext4_mount_stats))) {
+ if (verbose) {
+ printf("\tMount point stats error:\n");
+ printf("\tsaved_stats:\n");
+ printf("\tinodes_count = %d\n",
+ saved_stats.inodes_count);
+ printf("\tfree_inodes_count = %d\n",
+ saved_stats.free_inodes_count);
+ printf("\tblocks_count = %llu\n",
+ saved_stats.blocks_count);
+ printf("\tfree_blocks_count = %llu\n",
+ saved_stats.free_blocks_count);
+ printf("\tblock_size = %d\n", saved_stats.block_size);
+ printf("\tblock_group_count = %d\n",
+ saved_stats.block_group_count);
+ printf("\tblocks_per_group = %d\n",
+ saved_stats.blocks_per_group);
+ printf("\tinodes_per_group = %d\n",
+ saved_stats.inodes_per_group);
+ printf("\tvolume_name = %s\n", saved_stats.volume_name);
+ printf("\tactual_stats:\n");
+ printf("\tinodes_count = %d\n",
+ actual_stats.inodes_count);
+ printf("\tfree_inodes_count = %d\n",
+ actual_stats.free_inodes_count);
+ printf("\tblocks_count = %llu\n",
+ actual_stats.blocks_count);
+ printf("\tfree_blocks_count = %llu\n",
+ actual_stats.free_blocks_count);
+ printf("\tblock_size = %d\n", actual_stats.block_size);
+ printf("\tblock_group_count = %d\n",
+ actual_stats.block_group_count);
+ printf("\tblocks_per_group = %d\n",
+ actual_stats.blocks_per_group);
+ printf("\tinodes_per_group = %d\n",
+ actual_stats.inodes_per_group);
+ printf("\tvolume_name = %s\n",
+ actual_stats.volume_name);
+ }
+ return -1;
+ }
+
+ return rc;
}
static char *entry_to_str(uint8_t type)
{
- switch (type) {
- case EXT4_DIRENTRY_UNKNOWN:
- return "[UNK] ";
- case EXT4_DIRENTRY_REG_FILE:
- return "[FIL] ";
- case EXT4_DIRENTRY_DIR:
- return "[DIR] ";
- case EXT4_DIRENTRY_CHRDEV:
- return "[CHA] ";
- case EXT4_DIRENTRY_BLKDEV:
- return "[BLK] ";
- case EXT4_DIRENTRY_FIFO:
- return "[FIF] ";
- case EXT4_DIRENTRY_SOCK:
- return "[SOC] ";
- case EXT4_DIRENTRY_SYMLINK:
- return "[SYM] ";
- default:
- break;
- }
- return "[???]";
+ switch (type) {
+ case EXT4_DIRENTRY_UNKNOWN:
+ return "[UNK] ";
+ case EXT4_DIRENTRY_REG_FILE:
+ return "[FIL] ";
+ case EXT4_DIRENTRY_DIR:
+ return "[DIR] ";
+ case EXT4_DIRENTRY_CHRDEV:
+ return "[CHA] ";
+ case EXT4_DIRENTRY_BLKDEV:
+ return "[BLK] ";
+ case EXT4_DIRENTRY_FIFO:
+ return "[FIF] ";
+ case EXT4_DIRENTRY_SOCK:
+ return "[SOC] ";
+ case EXT4_DIRENTRY_SYMLINK:
+ return "[SYM] ";
+ default:
+ break;
+ }
+ return "[???]";
}
static int winsock_init(void)
{
#if WIN32
- int rc;
- static WSADATA wsaData;
- rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (rc != 0) {
- return -1;
- }
+ int rc;
+ static WSADATA wsaData;
+ rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (rc != 0) {
+ return -1;
+ }
#endif
- return 0;
+ return 0;
}
static void winsock_fini(void)
{
#if WIN32
- WSACleanup();
+ WSACleanup();
#endif
}
diff --git a/lwext4/ext4.c b/lwext4/ext4.c index b812d2d..aea79d4 100644 --- a/lwext4/ext4.c +++ b/lwext4/ext4.c @@ -51,48 +51,48 @@ /**@brief Mount point OS dependent lock*/
#define EXT4_MP_LOCK(_m) \
- do { \
- if ((_m)->os_locks) \
- (_m)->os_locks->lock(); \
- } while (0)
+ do { \
+ if ((_m)->os_locks) \
+ (_m)->os_locks->lock(); \
+ } while (0)
/**@brief Mount point OS dependent unlock*/
#define EXT4_MP_UNLOCK(_m) \
- do { \
- if ((_m)->os_locks) \
- (_m)->os_locks->unlock(); \
- } while (0)
+ do { \
+ if ((_m)->os_locks) \
+ (_m)->os_locks->unlock(); \
+ } while (0)
/**@brief Mount point descriptor.*/
struct ext4_mountpoint {
- /**@brief Mount done flag.*/
- bool mounted;
+ /**@brief Mount done flag.*/
+ bool mounted;
- /**@brief Mount point name (@ref ext4_mount)*/
- char name[32];
+ /**@brief Mount point name (@ref ext4_mount)*/
+ char name[32];
- /**@brief OS dependent lock/unlock functions.*/
- const struct ext4_lock *os_locks;
+ /**@brief OS dependent lock/unlock functions.*/
+ const struct ext4_lock *os_locks;
- /**@brief Ext4 filesystem internals.*/
- struct ext4_fs fs;
+ /**@brief Ext4 filesystem internals.*/
+ struct ext4_fs fs;
- /**@brief Dynamic allocation cache flag.*/
- bool cache_dynamic;
+ /**@brief Dynamic allocation cache flag.*/
+ bool cache_dynamic;
};
/**@brief Block devices descriptor.*/
struct _ext4_devices {
- /**@brief Block device name (@ref ext4_device_register)*/
- char name[32];
+ /**@brief Block device name (@ref ext4_device_register)*/
+ char name[32];
- /**@brief Block device handle.*/
- struct ext4_blockdev *bd;
+ /**@brief Block device handle.*/
+ struct ext4_blockdev *bd;
- /**@brief Block cache handle.*/
- struct ext4_bcache *bc;
+ /**@brief Block cache handle.*/
+ struct ext4_bcache *bc;
};
/**@brief Block devices.*/
@@ -102,463 +102,471 @@ struct _ext4_devices _bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT]; struct ext4_mountpoint _mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];
int ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
- const char *dev_name)
+ const char *dev_name)
{
- uint32_t i;
- ext4_assert(bd && dev_name);
-
- for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
- if (!_bdevices[i].bd) {
- strcpy(_bdevices[i].name, dev_name);
- _bdevices[i].bd = bd;
- _bdevices[i].bc = bc;
- return EOK;
- }
-
- if (!strcmp(_bdevices[i].name, dev_name))
- return EOK;
- }
- return ENOSPC;
+ uint32_t i;
+ ext4_assert(bd && dev_name);
+
+ for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
+ if (!_bdevices[i].bd) {
+ strcpy(_bdevices[i].name, dev_name);
+ _bdevices[i].bd = bd;
+ _bdevices[i].bc = bc;
+ return EOK;
+ }
+
+ if (!strcmp(_bdevices[i].name, dev_name))
+ return EOK;
+ }
+ return ENOSPC;
}
/****************************************************************************/
static bool ext4_is_dots(const uint8_t *name, size_t name_size)
{
- if ((name_size == 1) && (name[0] == '.'))
- return true;
+ if ((name_size == 1) && (name[0] == '.'))
+ return true;
- if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))
- return true;
+ if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))
+ return true;
- return false;
+ return false;
}
static int ext4_has_children(bool *has_children, struct ext4_inode_ref *enode)
{
- struct ext4_fs *fs = enode->fs;
-
- /* Check if node is directory */
- if (!ext4_inode_is_type(&fs->sb, enode->inode, EXT4_INODE_MODE_DIRECTORY)) {
- *has_children = false;
- return EOK;
- }
-
- struct ext4_directory_iterator it;
- int rc = ext4_dir_iterator_init(&it, enode, 0);
- if (rc != EOK)
- return rc;
-
- /* Find a non-empty directory entry */
- bool found = false;
- while (it.current != NULL) {
- if (it.current->inode != 0) {
- uint16_t name_size =
- ext4_dir_entry_ll_get_name_length(&fs->sb, it.current);
- if (!ext4_is_dots(it.current->name, name_size)) {
- found = true;
- break;
- }
- }
-
- rc = ext4_dir_iterator_next(&it);
- if (rc != EOK) {
- ext4_dir_iterator_fini(&it);
- return rc;
- }
- }
-
- rc = ext4_dir_iterator_fini(&it);
- if (rc != EOK)
- return rc;
-
- *has_children = found;
-
- return EOK;
+ struct ext4_fs *fs = enode->fs;
+
+ /* Check if node is directory */
+ if (!ext4_inode_is_type(&fs->sb, enode->inode,
+ EXT4_INODE_MODE_DIRECTORY)) {
+ *has_children = false;
+ return EOK;
+ }
+
+ struct ext4_directory_iterator it;
+ int rc = ext4_dir_iterator_init(&it, enode, 0);
+ if (rc != EOK)
+ return rc;
+
+ /* Find a non-empty directory entry */
+ bool found = false;
+ while (it.current != NULL) {
+ if (it.current->inode != 0) {
+ uint16_t name_size = ext4_dir_entry_ll_get_name_length(
+ &fs->sb, it.current);
+ if (!ext4_is_dots(it.current->name, name_size)) {
+ found = true;
+ break;
+ }
+ }
+
+ rc = ext4_dir_iterator_next(&it);
+ if (rc != EOK) {
+ ext4_dir_iterator_fini(&it);
+ return rc;
+ }
+ }
+
+ rc = ext4_dir_iterator_fini(&it);
+ if (rc != EOK)
+ return rc;
+
+ *has_children = found;
+
+ return EOK;
}
static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,
- struct ext4_inode_ref *child, const char *name,
- uint32_t name_len)
+ struct ext4_inode_ref *child, const char *name,
+ uint32_t name_len)
{
- /* Check maximum name length */
- if (name_len > EXT4_DIRECTORY_FILENAME_LEN)
- return EINVAL;
-
- /* Add entry to parent directory */
- int rc = ext4_dir_add_entry(parent, name, name_len, child);
- if (rc != EOK)
- return rc;
-
- /* Fill new dir -> add '.' and '..' entries.
- * Also newly allocated inode should have 0 link count.
- */
- if (ext4_inode_is_type(&mp->fs.sb, child->inode,
- EXT4_INODE_MODE_DIRECTORY)
- && ext4_inode_get_links_count(child->inode) == 0) {
- rc = ext4_dir_add_entry(child, ".", strlen("."), child);
- if (rc != EOK) {
- ext4_dir_remove_entry(parent, name, strlen(name));
- return rc;
- }
-
- rc = ext4_dir_add_entry(child, "..", strlen(".."), parent);
- if (rc != EOK) {
- ext4_dir_remove_entry(parent, name, strlen(name));
- ext4_dir_remove_entry(child, ".", strlen("."));
- return rc;
- }
-
- /*New empty directory. Two links (. and ..) */
- ext4_inode_set_links_count(child->inode, 2);
+ /* Check maximum name length */
+ if (name_len > EXT4_DIRECTORY_FILENAME_LEN)
+ return EINVAL;
+
+ /* Add entry to parent directory */
+ int rc = ext4_dir_add_entry(parent, name, name_len, child);
+ if (rc != EOK)
+ return rc;
+
+ /* Fill new dir -> add '.' and '..' entries.
+ * Also newly allocated inode should have 0 link count.
+ */
+ if (ext4_inode_is_type(&mp->fs.sb, child->inode,
+ EXT4_INODE_MODE_DIRECTORY) &&
+ ext4_inode_get_links_count(child->inode) == 0) {
+ rc = ext4_dir_add_entry(child, ".", strlen("."), child);
+ if (rc != EOK) {
+ ext4_dir_remove_entry(parent, name, strlen(name));
+ return rc;
+ }
+
+ rc = ext4_dir_add_entry(child, "..", strlen(".."), parent);
+ if (rc != EOK) {
+ ext4_dir_remove_entry(parent, name, strlen(name));
+ ext4_dir_remove_entry(child, ".", strlen("."));
+ return rc;
+ }
+
+ /*New empty directory. Two links (. and ..) */
+ ext4_inode_set_links_count(child->inode, 2);
#if CONFIG_DIR_INDEX_ENABLE
- /* Initialize directory index if supported */
- if (ext4_sb_has_feature_compatible(&mp->fs.sb,
- EXT4_FEATURE_COMPAT_DIR_INDEX)) {
- rc = ext4_dir_dx_init(child);
- if (rc != EOK)
- return rc;
-
- ext4_inode_set_flag(child->inode, EXT4_INODE_FLAG_INDEX);
- child->dirty = true;
- }
+ /* Initialize directory index if supported */
+ if (ext4_sb_has_feature_compatible(
+ &mp->fs.sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
+ rc = ext4_dir_dx_init(child);
+ if (rc != EOK)
+ return rc;
+
+ ext4_inode_set_flag(child->inode,
+ EXT4_INODE_FLAG_INDEX);
+ child->dirty = true;
+ }
#endif
- ext4_fs_inode_links_count_inc(parent);
- child->dirty = true;
- parent->dirty = true;
- } else {
- if (ext4_inode_is_type(&mp->fs.sb, child->inode,
- EXT4_INODE_MODE_DIRECTORY)) {
- /* FIXME: SO TRICKY. */
- int has_flag_index =
- ext4_inode_has_flag(child->inode, EXT4_INODE_FLAG_INDEX);
- struct ext4_directory_search_result result;
- if (has_flag_index)
- ext4_inode_clear_flag(child->inode, EXT4_INODE_FLAG_INDEX);
-
- rc = ext4_dir_find_entry(&result, child, "..", strlen(".."));
- if (has_flag_index)
- ext4_inode_set_flag(child->inode, EXT4_INODE_FLAG_INDEX);
-
- if (rc != EOK)
- return EIO;
-
- ext4_dir_entry_ll_set_inode(result.dentry, parent->index);
- result.block.dirty = true;
- rc = ext4_dir_destroy_result(child, &result);
- if (rc != EOK)
- return rc;
-
- ext4_fs_inode_links_count_inc(parent);
- parent->dirty = true;
- } else {
- ext4_fs_inode_links_count_inc(child);
- child->dirty = true;
- }
- }
-
- return rc;
+ ext4_fs_inode_links_count_inc(parent);
+ child->dirty = true;
+ parent->dirty = true;
+ } else {
+ if (ext4_inode_is_type(&mp->fs.sb, child->inode,
+ EXT4_INODE_MODE_DIRECTORY)) {
+ /* FIXME: SO TRICKY. */
+ int has_flag_index = ext4_inode_has_flag(
+ child->inode, EXT4_INODE_FLAG_INDEX);
+ struct ext4_directory_search_result result;
+ if (has_flag_index)
+ ext4_inode_clear_flag(child->inode,
+ EXT4_INODE_FLAG_INDEX);
+
+ rc = ext4_dir_find_entry(&result, child, "..",
+ strlen(".."));
+ if (has_flag_index)
+ ext4_inode_set_flag(child->inode,
+ EXT4_INODE_FLAG_INDEX);
+
+ if (rc != EOK)
+ return EIO;
+
+ ext4_dir_entry_ll_set_inode(result.dentry,
+ parent->index);
+ result.block.dirty = true;
+ rc = ext4_dir_destroy_result(child, &result);
+ if (rc != EOK)
+ return rc;
+
+ ext4_fs_inode_links_count_inc(parent);
+ parent->dirty = true;
+ } else {
+ ext4_fs_inode_links_count_inc(child);
+ child->dirty = true;
+ }
+ }
+
+ return rc;
}
static int ext4_unlink(struct ext4_mountpoint *mp,
- struct ext4_inode_ref *parent,
- struct ext4_inode_ref *child_inode_ref, const char *name,
- uint32_t name_len)
+ struct ext4_inode_ref *parent,
+ struct ext4_inode_ref *child_inode_ref, const char *name,
+ uint32_t name_len)
{
- bool has_children;
- int rc = ext4_has_children(&has_children, child_inode_ref);
- if (rc != EOK)
- return rc;
-
- /* Cannot unlink non-empty node */
- if (has_children)
- return ENOTSUP;
-
- /* Remove entry from parent directory */
- rc = ext4_dir_remove_entry(parent, name, name_len);
- if (rc != EOK)
- return rc;
-
- bool is_dir = ext4_inode_is_type(&mp->fs.sb, child_inode_ref->inode,
- EXT4_INODE_MODE_DIRECTORY);
-
- /* If directory - handle links from parent */
- if (is_dir) {
- // ext4_assert(ext4_inode_get_links_count(child_inode_ref->inode) == 1);
- ext4_fs_inode_links_count_dec(parent);
- parent->dirty = true;
- }
-
- /*
- * TODO: Update timestamps of the parent
- * (when we have wall-clock time).
- *
- * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);
- * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);
- * parent->dirty = true;
- */
-
- /*
- * TODO: Update timestamp for inode.
- *
- * ext4_inode_set_change_inode_time(child_inode_ref->inode,
- * (uint32_t) now);
- */
- if (ext4_inode_get_links_count(child_inode_ref->inode)) {
- ext4_fs_inode_links_count_dec(child_inode_ref);
- child_inode_ref->dirty = true;
- }
-
- return EOK;
+ bool has_children;
+ int rc = ext4_has_children(&has_children, child_inode_ref);
+ if (rc != EOK)
+ return rc;
+
+ /* Cannot unlink non-empty node */
+ if (has_children)
+ return ENOTSUP;
+
+ /* Remove entry from parent directory */
+ rc = ext4_dir_remove_entry(parent, name, name_len);
+ if (rc != EOK)
+ return rc;
+
+ bool is_dir = ext4_inode_is_type(&mp->fs.sb, child_inode_ref->inode,
+ EXT4_INODE_MODE_DIRECTORY);
+
+ /* If directory - handle links from parent */
+ if (is_dir) {
+ // ext4_assert(ext4_inode_get_links_count(child_inode_ref->inode)
+ // == 1);
+ ext4_fs_inode_links_count_dec(parent);
+ parent->dirty = true;
+ }
+
+ /*
+ * TODO: Update timestamps of the parent
+ * (when we have wall-clock time).
+ *
+ * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);
+ * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);
+ * parent->dirty = true;
+ */
+
+ /*
+ * TODO: Update timestamp for inode.
+ *
+ * ext4_inode_set_change_inode_time(child_inode_ref->inode,
+ * (uint32_t) now);
+ */
+ if (ext4_inode_get_links_count(child_inode_ref->inode)) {
+ ext4_fs_inode_links_count_dec(child_inode_ref);
+ child_inode_ref->dirty = true;
+ }
+
+ return EOK;
}
/****************************************************************************/
int ext4_mount(const char *dev_name, const char *mount_point)
{
- ext4_assert(mount_point && dev_name);
- int r;
- int i;
-
- uint32_t bsize;
- struct ext4_blockdev *bd = 0;
- struct ext4_bcache *bc = 0;
- struct ext4_mountpoint *mp = 0;
-
- if (mount_point[strlen(mount_point) - 1] != '/')
- return ENOTSUP;
-
- for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
- if (_bdevices[i].name) {
- if (!strcmp(dev_name, _bdevices[i].name)) {
- bd = _bdevices[i].bd;
- bc = _bdevices[i].bc;
- break;
- }
- }
- }
-
- if (!bd)
- return ENODEV;
-
- for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!_mp[i].mounted) {
- strcpy(_mp[i].name, mount_point);
- _mp[i].mounted = 1;
- mp = &_mp[i];
- break;
- }
-
- if (!strcmp(_mp[i].name, mount_point))
- return EOK;
- }
-
- if (!mp)
- return ENOMEM;
-
- r = ext4_block_init(bd);
- if (r != EOK)
- return r;
-
- r = ext4_fs_init(&mp->fs, bd);
- if (r != EOK) {
- ext4_block_fini(bd);
- return r;
- }
-
- bsize = ext4_sb_get_block_size(&mp->fs.sb);
- ext4_block_set_lb_size(bd, bsize);
-
- mp->cache_dynamic = 0;
-
- if (!bc) {
- /*Automatic block cache alloc.*/
- mp->cache_dynamic = 1;
- bc = malloc(sizeof(struct ext4_bcache));
-
- r = ext4_bcache_init_dynamic(bc, CONFIG_BLOCK_DEV_CACHE_SIZE, bsize);
- if (r != EOK) {
- free(bc);
- ext4_block_fini(bd);
- return r;
- }
- }
-
- if (bsize != bc->itemsize)
- return ENOTSUP;
-
- /*Bind block cache to block device*/
- r = ext4_block_bind_bcache(bd, bc);
- if (r != EOK) {
- ext4_block_fini(bd);
- if (mp->cache_dynamic) {
- ext4_bcache_fini_dynamic(bc);
- free(bc);
- }
- return r;
- }
-
- return r;
+ ext4_assert(mount_point && dev_name);
+ int r;
+ int i;
+
+ uint32_t bsize;
+ struct ext4_blockdev *bd = 0;
+ struct ext4_bcache *bc = 0;
+ struct ext4_mountpoint *mp = 0;
+
+ if (mount_point[strlen(mount_point) - 1] != '/')
+ return ENOTSUP;
+
+ for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
+ if (_bdevices[i].name) {
+ if (!strcmp(dev_name, _bdevices[i].name)) {
+ bd = _bdevices[i].bd;
+ bc = _bdevices[i].bc;
+ break;
+ }
+ }
+ }
+
+ if (!bd)
+ return ENODEV;
+
+ for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+ if (!_mp[i].mounted) {
+ strcpy(_mp[i].name, mount_point);
+ _mp[i].mounted = 1;
+ mp = &_mp[i];
+ break;
+ }
+
+ if (!strcmp(_mp[i].name, mount_point))
+ return EOK;
+ }
+
+ if (!mp)
+ return ENOMEM;
+
+ r = ext4_block_init(bd);
+ if (r != EOK)
+ return r;
+
+ r = ext4_fs_init(&mp->fs, bd);
+ if (r != EOK) {
+ ext4_block_fini(bd);
+ return r;
+ }
+
+ bsize = ext4_sb_get_block_size(&mp->fs.sb);
+ ext4_block_set_lb_size(bd, bsize);
+
+ mp->cache_dynamic = 0;
+
+ if (!bc) {
+ /*Automatic block cache alloc.*/
+ mp->cache_dynamic = 1;
+ bc = malloc(sizeof(struct ext4_bcache));
+
+ r = ext4_bcache_init_dynamic(bc, CONFIG_BLOCK_DEV_CACHE_SIZE,
+ bsize);
+ if (r != EOK) {
+ free(bc);
+ ext4_block_fini(bd);
+ return r;
+ }
+ }
+
+ if (bsize != bc->itemsize)
+ return ENOTSUP;
+
+ /*Bind block cache to block device*/
+ r = ext4_block_bind_bcache(bd, bc);
+ if (r != EOK) {
+ ext4_block_fini(bd);
+ if (mp->cache_dynamic) {
+ ext4_bcache_fini_dynamic(bc);
+ free(bc);
+ }
+ return r;
+ }
+
+ return r;
}
int ext4_umount(const char *mount_point)
{
- int i;
- int r;
- struct ext4_mountpoint *mp = 0;
+ int i;
+ int r;
+ struct ext4_mountpoint *mp = 0;
- for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!strcmp(_mp[i].name, mount_point)) {
- mp = &_mp[i];
- break;
- }
- }
+ for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+ if (!strcmp(_mp[i].name, mount_point)) {
+ mp = &_mp[i];
+ break;
+ }
+ }
- if (!mp)
- return ENODEV;
+ if (!mp)
+ return ENODEV;
- r = ext4_fs_fini(&mp->fs);
- if (r != EOK)
- return r;
+ r = ext4_fs_fini(&mp->fs);
+ if (r != EOK)
+ return r;
- mp->mounted = 0;
+ mp->mounted = 0;
- if (mp->cache_dynamic) {
- ext4_bcache_fini_dynamic(mp->fs.bdev->bc);
- free(mp->fs.bdev->bc);
- }
+ if (mp->cache_dynamic) {
+ ext4_bcache_fini_dynamic(mp->fs.bdev->bc);
+ free(mp->fs.bdev->bc);
+ }
- return ext4_block_fini(mp->fs.bdev);
+ return ext4_block_fini(mp->fs.bdev);
}
int ext4_mount_point_stats(const char *mount_point,
- struct ext4_mount_stats *stats)
+ struct ext4_mount_stats *stats)
{
- uint32_t i;
- struct ext4_mountpoint *mp = 0;
-
- for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!strcmp(_mp[i].name, mount_point)) {
- mp = &_mp[i];
- break;
- }
- }
- if (!mp)
- return ENOENT;
-
- EXT4_MP_LOCK(mp);
- stats->inodes_count = ext4_get32(&mp->fs.sb, inodes_count);
- stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);
- stats->blocks_count = ext4_sb_get_blocks_cnt(&mp->fs.sb);
- stats->free_blocks_count = ext4_sb_get_free_blocks_cnt(&mp->fs.sb);
- stats->block_size = ext4_sb_get_block_size(&mp->fs.sb);
-
- stats->block_group_count = ext4_block_group_cnt(&mp->fs.sb);
- stats->blocks_per_group = ext4_get32(&mp->fs.sb, blocks_per_group);
- stats->inodes_per_group = ext4_get32(&mp->fs.sb, inodes_per_group);
-
- memcpy(stats->volume_name, mp->fs.sb.volume_name, 16);
- EXT4_MP_UNLOCK(mp);
-
- return EOK;
+ uint32_t i;
+ struct ext4_mountpoint *mp = 0;
+
+ for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+ if (!strcmp(_mp[i].name, mount_point)) {
+ mp = &_mp[i];
+ break;
+ }
+ }
+ if (!mp)
+ return ENOENT;
+
+ EXT4_MP_LOCK(mp);
+ stats->inodes_count = ext4_get32(&mp->fs.sb, inodes_count);
+ stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);
+ stats->blocks_count = ext4_sb_get_blocks_cnt(&mp->fs.sb);
+ stats->free_blocks_count = ext4_sb_get_free_blocks_cnt(&mp->fs.sb);
+ stats->block_size = ext4_sb_get_block_size(&mp->fs.sb);
+
+ stats->block_group_count = ext4_block_group_cnt(&mp->fs.sb);
+ stats->blocks_per_group = ext4_get32(&mp->fs.sb, blocks_per_group);
+ stats->inodes_per_group = ext4_get32(&mp->fs.sb, inodes_per_group);
+
+ memcpy(stats->volume_name, mp->fs.sb.volume_name, 16);
+ EXT4_MP_UNLOCK(mp);
+
+ return EOK;
}
int ext4_mount_setup_locks(const char *mount_point,
- const struct ext4_lock *locks)
+ const struct ext4_lock *locks)
{
- uint32_t i;
- struct ext4_mountpoint *mp = 0;
-
- for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!strcmp(_mp[i].name, mount_point)) {
- mp = &_mp[i];
- break;
- }
- }
- if (!mp)
- return ENOENT;
-
- mp->os_locks = locks;
- return EOK;
+ uint32_t i;
+ struct ext4_mountpoint *mp = 0;
+
+ for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+ if (!strcmp(_mp[i].name, mount_point)) {
+ mp = &_mp[i];
+ break;
+ }
+ }
+ if (!mp)
+ return ENOENT;
+
+ mp->os_locks = locks;
+ return EOK;
}
/********************************FILE OPERATIONS*****************************/
static struct ext4_mountpoint *ext4_get_mount(const char *path)
{
- int i;
- for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+ int i;
+ for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!_mp[i].mounted)
- continue;
+ if (!_mp[i].mounted)
+ continue;
- if (!strncmp(_mp[i].name, path, strlen(_mp[i].name)))
- return &_mp[i];
- }
- return 0;
+ if (!strncmp(_mp[i].name, path, strlen(_mp[i].name)))
+ return &_mp[i];
+ }
+ return 0;
}
static int ext4_path_check(const char *path, bool *is_goal)
{
- int i;
+ int i;
- for (i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {
+ for (i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {
- if (path[i] == '/') {
- *is_goal = false;
- return i;
- }
+ if (path[i] == '/') {
+ *is_goal = false;
+ return i;
+ }
- if (path[i] == 0) {
- *is_goal = true;
- return i;
- }
- }
+ if (path[i] == 0) {
+ *is_goal = true;
+ return i;
+ }
+ }
- return 0;
+ return 0;
}
static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
{
- if (!flags)
- return false;
-
- if (!strcmp(flags, "r") || !strcmp(flags, "rb")) {
- *file_flags = O_RDONLY;
- return true;
- }
-
- if (!strcmp(flags, "w") || !strcmp(flags, "wb")) {
- *file_flags = O_WRONLY | O_CREAT | O_TRUNC;
- return true;
- }
-
- if (!strcmp(flags, "a") || !strcmp(flags, "ab")) {
- *file_flags = O_WRONLY | O_CREAT | O_APPEND;
- return true;
- }
-
- if (!strcmp(flags, "r+") || !strcmp(flags, "rb+") ||
- !strcmp(flags, "r+b")) {
- *file_flags = O_RDWR;
- return true;
- }
-
- if (!strcmp(flags, "w+") || !strcmp(flags, "wb+") ||
- !strcmp(flags, "w+b")) {
- *file_flags = O_RDWR | O_CREAT | O_TRUNC;
- return true;
- }
-
- if (!strcmp(flags, "a+") || !strcmp(flags, "ab+") ||
- !strcmp(flags, "a+b")) {
- *file_flags = O_RDWR | O_CREAT | O_APPEND;
- return true;
- }
-
- return false;
+ if (!flags)
+ return false;
+
+ if (!strcmp(flags, "r") || !strcmp(flags, "rb")) {
+ *file_flags = O_RDONLY;
+ return true;
+ }
+
+ if (!strcmp(flags, "w") || !strcmp(flags, "wb")) {
+ *file_flags = O_WRONLY | O_CREAT | O_TRUNC;
+ return true;
+ }
+
+ if (!strcmp(flags, "a") || !strcmp(flags, "ab")) {
+ *file_flags = O_WRONLY | O_CREAT | O_APPEND;
+ return true;
+ }
+
+ if (!strcmp(flags, "r+") || !strcmp(flags, "rb+") ||
+ !strcmp(flags, "r+b")) {
+ *file_flags = O_RDWR;
+ return true;
+ }
+
+ if (!strcmp(flags, "w+") || !strcmp(flags, "wb+") ||
+ !strcmp(flags, "w+b")) {
+ *file_flags = O_RDWR | O_CREAT | O_TRUNC;
+ return true;
+ }
+
+ if (!strcmp(flags, "a+") || !strcmp(flags, "ab+") ||
+ !strcmp(flags, "a+b")) {
+ *file_flags = O_RDWR | O_CREAT | O_APPEND;
+ return true;
+ }
+
+ return false;
}
/*
@@ -566,1301 +574,1308 @@ static bool ext4_parse_flags(const char *flags, uint32_t *file_flags) * any filetype of the target dir entry will be accepted.
*/
static int ext4_generic_open2(ext4_file *f, const char *path, int flags,
- int filetype, uint32_t *parent_inode,
- uint32_t *name_off)
+ int filetype, uint32_t *parent_inode,
+ uint32_t *name_off)
{
- bool is_goal = false;
- uint8_t inode_type = EXT4_DIRECTORY_FILETYPE_DIR;
- uint32_t next_inode;
+ bool is_goal = false;
+ uint8_t inode_type = EXT4_DIRECTORY_FILETYPE_DIR;
+ uint32_t next_inode;
- int r;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- struct ext4_directory_search_result result;
- struct ext4_inode_ref ref;
+ int r;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ struct ext4_directory_search_result result;
+ struct ext4_inode_ref ref;
- f->mp = 0;
+ f->mp = 0;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- f->flags = flags;
+ f->flags = flags;
+
+ /*Skip mount point*/
+ path += strlen(mp->name);
- /*Skip mount point*/
- path += strlen(mp->name);
+ if (name_off)
+ *name_off = strlen(mp->name);
- if (name_off)
- *name_off = strlen(mp->name);
+ /*Load root*/
+ r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
- /*Load root*/
- r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
+ if (r != EOK)
+ return r;
- if (r != EOK)
- return r;
+ if (parent_inode)
+ *parent_inode = ref.index;
- if (parent_inode)
- *parent_inode = ref.index;
+ int len = ext4_path_check(path, &is_goal);
- int len = ext4_path_check(path, &is_goal);
+ while (1) {
- while (1) {
+ len = ext4_path_check(path, &is_goal);
- len = ext4_path_check(path, &is_goal);
+ if (!len) {
+ /*If root open was request.*/
+ if (is_goal &&
+ ((filetype == EXT4_DIRECTORY_FILETYPE_DIR) ||
+ (filetype == EXT4_DIRECTORY_FILETYPE_UNKNOWN)))
+ break;
- if (!len) {
- /*If root open was request.*/
- if (is_goal && ((filetype == EXT4_DIRECTORY_FILETYPE_DIR)
- || (filetype == EXT4_DIRECTORY_FILETYPE_UNKNOWN)))
- break;
+ r = ENOENT;
+ break;
+ }
- r = ENOENT;
- break;
- }
+ r = ext4_dir_find_entry(&result, &ref, path, len);
+ if (r != EOK) {
- r = ext4_dir_find_entry(&result, &ref, path, len);
- if (r != EOK) {
+ if (r != ENOENT)
+ break;
- if (r != ENOENT)
- break;
+ if (!(f->flags & O_CREAT))
+ break;
- if (!(f->flags & O_CREAT))
- break;
+ /*O_CREAT allows create new entry*/
+ struct ext4_inode_ref child_ref;
+ r = ext4_fs_alloc_inode(
+ &mp->fs, &child_ref,
+ is_goal ? (filetype == EXT4_DIRECTORY_FILETYPE_DIR)
+ : true);
+ if (r != EOK)
+ break;
- /*O_CREAT allows create new entry*/
- struct ext4_inode_ref child_ref;
- r = ext4_fs_alloc_inode(&mp->fs, &child_ref,
- is_goal
- ? (filetype == EXT4_DIRECTORY_FILETYPE_DIR)
- : true);
- if (r != EOK)
- break;
+ /*Destroy last result*/
+ ext4_dir_destroy_result(&ref, &result);
- /*Destroy last result*/
- ext4_dir_destroy_result(&ref, &result);
+ /*Link with root dir.*/
+ r = ext4_link(mp, &ref, &child_ref, path, len);
+ if (r != EOK) {
+ /*Fail. Free new inode.*/
+ ext4_fs_free_inode(&child_ref);
+ /*We do not want to write new inode.
+ But block has to be released.*/
+ child_ref.dirty = false;
+ ext4_fs_put_inode_ref(&child_ref);
+ break;
+ }
- /*Link with root dir.*/
- r = ext4_link(mp, &ref, &child_ref, path, len);
- if (r != EOK) {
- /*Fail. Free new inode.*/
- ext4_fs_free_inode(&child_ref);
- /*We do not want to write new inode.
- But block has to be released.*/
- child_ref.dirty = false;
- ext4_fs_put_inode_ref(&child_ref);
- break;
- }
+ ext4_fs_put_inode_ref(&child_ref);
- ext4_fs_put_inode_ref(&child_ref);
+ continue;
+ }
- continue;
- }
+ if (parent_inode)
+ *parent_inode = ref.index;
- if (parent_inode)
- *parent_inode = ref.index;
+ next_inode = result.dentry->inode;
+ inode_type =
+ ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
- next_inode = result.dentry->inode;
- inode_type =
- ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
+ r = ext4_dir_destroy_result(&ref, &result);
+ if (r != EOK)
+ break;
- r = ext4_dir_destroy_result(&ref, &result);
- if (r != EOK)
- break;
+ /*If expected file error*/
+ if (inode_type != EXT4_DIRECTORY_FILETYPE_DIR && !is_goal) {
+ r = ENOENT;
+ break;
+ }
+ if (filetype != EXT4_DIRECTORY_FILETYPE_UNKNOWN) {
+ if ((inode_type != filetype) && is_goal) {
+ r = ENOENT;
+ break;
+ }
+ }
- /*If expected file error*/
- if (inode_type != EXT4_DIRECTORY_FILETYPE_DIR && !is_goal) {
- r = ENOENT;
- break;
- }
- if (filetype != EXT4_DIRECTORY_FILETYPE_UNKNOWN) {
- if ((inode_type != filetype) && is_goal) {
- r = ENOENT;
- break;
- }
- }
+ r = ext4_fs_put_inode_ref(&ref);
+ if (r != EOK)
+ break;
- r = ext4_fs_put_inode_ref(&ref);
- if (r != EOK)
- break;
-
- r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &ref);
- if (r != EOK)
- break;
-
- if (is_goal)
- break;
-
- path += len + 1;
-
- if (name_off)
- *name_off += len + 1;
- };
-
- if (r != EOK) {
- ext4_fs_put_inode_ref(&ref);
- return r;
- }
-
- if (is_goal) {
-
- if ((f->flags & O_TRUNC) &&
- (inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE)) {
-
- r = ext4_fs_truncate_inode(&ref, 0);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&ref);
- return r;
- }
- }
-
- f->mp = mp;
- f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
- f->inode = ref.index;
- f->fpos = 0;
-
- if (f->flags & O_APPEND)
- f->fpos = f->fsize;
- }
-
- r = ext4_fs_put_inode_ref(&ref);
- return r;
+ r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &ref);
+ if (r != EOK)
+ break;
+
+ if (is_goal)
+ break;
+
+ path += len + 1;
+
+ if (name_off)
+ *name_off += len + 1;
+ };
+
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&ref);
+ return r;
+ }
+
+ if (is_goal) {
+
+ if ((f->flags & O_TRUNC) &&
+ (inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE)) {
+
+ r = ext4_fs_truncate_inode(&ref, 0);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&ref);
+ return r;
+ }
+ }
+
+ f->mp = mp;
+ f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+ f->inode = ref.index;
+ f->fpos = 0;
+
+ if (f->flags & O_APPEND)
+ f->fpos = f->fsize;
+ }
+
+ r = ext4_fs_put_inode_ref(&ref);
+ return r;
}
/****************************************************************************/
static int ext4_generic_open(ext4_file *f, const char *path, const char *flags,
- bool file_expect, uint32_t *parent_inode,
- uint32_t *name_off)
+ bool file_expect, uint32_t *parent_inode,
+ uint32_t *name_off)
{
- uint32_t iflags;
- int filetype;
- if (ext4_parse_flags(flags, &iflags) == false)
- return EINVAL;
-
- if (file_expect == true)
- filetype = EXT4_DIRECTORY_FILETYPE_REG_FILE;
- else
- filetype = EXT4_DIRECTORY_FILETYPE_DIR;
-
- return ext4_generic_open2(f, path, iflags, filetype,
- parent_inode, name_off);
+ uint32_t iflags;
+ int filetype;
+ if (ext4_parse_flags(flags, &iflags) == false)
+ return EINVAL;
+
+ if (file_expect == true)
+ filetype = EXT4_DIRECTORY_FILETYPE_REG_FILE;
+ else
+ filetype = EXT4_DIRECTORY_FILETYPE_DIR;
+
+ return ext4_generic_open2(f, path, iflags, filetype, parent_inode,
+ name_off);
}
static int __ext4_create_hardlink(const char *path,
- struct ext4_inode_ref *child_ref)
+ struct ext4_inode_ref *child_ref)
{
- bool is_goal = false;
- uint8_t inode_type = EXT4_DIRECTORY_FILETYPE_DIR;
- uint32_t next_inode;
+ bool is_goal = false;
+ uint8_t inode_type = EXT4_DIRECTORY_FILETYPE_DIR;
+ uint32_t next_inode;
- int r;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- struct ext4_directory_search_result result;
- struct ext4_inode_ref ref;
+ int r;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ struct ext4_directory_search_result result;
+ struct ext4_inode_ref ref;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- /*Skip mount point*/
- path += strlen(mp->name);
+ /*Skip mount point*/
+ path += strlen(mp->name);
- /*Load root*/
- r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
+ /*Load root*/
+ r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
- if (r != EOK)
- return r;
+ if (r != EOK)
+ return r;
- int len = ext4_path_check(path, &is_goal);
+ int len = ext4_path_check(path, &is_goal);
- while (1) {
+ while (1) {
- len = ext4_path_check(path, &is_goal);
+ len = ext4_path_check(path, &is_goal);
- if (!len) {
- /*If root open was request.*/
- if (is_goal)
- r = EINVAL;
- else
- r = ENOENT;
- break;
- }
+ if (!len) {
+ /*If root open was request.*/
+ if (is_goal)
+ r = EINVAL;
+ else
+ r = ENOENT;
+ break;
+ }
- r = ext4_dir_find_entry(&result, &ref, path, len);
- if (r != EOK) {
+ r = ext4_dir_find_entry(&result, &ref, path, len);
+ if (r != EOK) {
- if (r != ENOENT || !is_goal)
- break;
+ if (r != ENOENT || !is_goal)
+ break;
- /*Destroy last result*/
- ext4_dir_destroy_result(&ref, &result);
+ /*Destroy last result*/
+ ext4_dir_destroy_result(&ref, &result);
- /*Link with root dir.*/
- r = ext4_link(mp, &ref, child_ref, path, len);
- break;
- }
+ /*Link with root dir.*/
+ r = ext4_link(mp, &ref, child_ref, path, len);
+ break;
+ }
- next_inode = result.dentry->inode;
- inode_type =
- ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
+ next_inode = result.dentry->inode;
+ inode_type =
+ ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
- r = ext4_dir_destroy_result(&ref, &result);
- if (r != EOK)
- break;
+ r = ext4_dir_destroy_result(&ref, &result);
+ if (r != EOK)
+ break;
- if (inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE) {
- if (is_goal)
- r = EEXIST;
- else
- r = ENOENT;
+ if (inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE) {
+ if (is_goal)
+ r = EEXIST;
+ else
+ r = ENOENT;
- break;
- }
+ break;
+ }
- r = ext4_fs_put_inode_ref(&ref);
- if (r != EOK)
- break;
+ r = ext4_fs_put_inode_ref(&ref);
+ if (r != EOK)
+ break;
- r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &ref);
- if (r != EOK)
- break;
+ r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &ref);
+ if (r != EOK)
+ break;
- if (is_goal)
- break;
+ if (is_goal)
+ break;
- path += len + 1;
- };
+ path += len + 1;
+ };
- if (r != EOK) {
- ext4_fs_put_inode_ref(&ref);
- return r;
- }
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&ref);
+ return r;
+ }
- r = ext4_fs_put_inode_ref(&ref);
- return r;
+ r = ext4_fs_put_inode_ref(&ref);
+ return r;
}
-static int __ext4_get_inode_ref_remove_hardlink(const char *path, struct ext4_inode_ref *child)
+static int __ext4_get_inode_ref_remove_hardlink(const char *path,
+ struct ext4_inode_ref *child)
{
- ext4_file f;
- uint32_t parent_inode;
- uint32_t name_off;
- bool is_goal;
- int r;
- int len;
- struct ext4_inode_ref parent;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
-
- if (!mp)
- return ENOENT;
-
- r = ext4_generic_open2(&f, path, O_RDONLY,
- EXT4_DIRECTORY_FILETYPE_UNKNOWN,
- &parent_inode, &name_off);
- if (r != EOK)
- return r;
-
- /*Load parent*/
- r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);
- if (r != EOK) {
- return r;
- }
-
- /*We have file to unlink. Load it.*/
- r = ext4_fs_get_inode_ref(&mp->fs, f.inode, child);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&parent);
- return r;
- }
-
- if (r != EOK)
- goto Finish;
-
- /*Set path*/
- path += name_off;
-
- len = ext4_path_check(path, &is_goal);
-
- /*Unlink from parent*/
- r = ext4_unlink(mp, &parent, child, path, len);
- if (r != EOK)
- goto Finish;
+ ext4_file f;
+ uint32_t parent_inode;
+ uint32_t name_off;
+ bool is_goal;
+ int r;
+ int len;
+ struct ext4_inode_ref parent;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+
+ if (!mp)
+ return ENOENT;
+
+ r = ext4_generic_open2(&f, path, O_RDONLY,
+ EXT4_DIRECTORY_FILETYPE_UNKNOWN, &parent_inode,
+ &name_off);
+ if (r != EOK)
+ return r;
+
+ /*Load parent*/
+ r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);
+ if (r != EOK) {
+ return r;
+ }
+
+ /*We have file to unlink. Load it.*/
+ r = ext4_fs_get_inode_ref(&mp->fs, f.inode, child);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&parent);
+ return r;
+ }
+
+ if (r != EOK)
+ goto Finish;
+
+ /*Set path*/
+ path += name_off;
+
+ len = ext4_path_check(path, &is_goal);
+
+ /*Unlink from parent*/
+ r = ext4_unlink(mp, &parent, child, path, len);
+ if (r != EOK)
+ goto Finish;
Finish:
- if (r != EOK)
- ext4_fs_put_inode_ref(child);
+ if (r != EOK)
+ ext4_fs_put_inode_ref(child);
- ext4_fs_put_inode_ref(&parent);
- return r;
+ ext4_fs_put_inode_ref(&parent);
+ return r;
}
int ext4_frename(const char *path, const char *new_path)
{
- int r;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- struct ext4_inode_ref inode_ref;
+ int r;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ struct ext4_inode_ref inode_ref;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
+ EXT4_MP_LOCK(mp);
- r = __ext4_get_inode_ref_remove_hardlink(path, &inode_ref);
- if (r != EOK)
- goto Finish;
+ r = __ext4_get_inode_ref_remove_hardlink(path, &inode_ref);
+ if (r != EOK)
+ goto Finish;
- r = __ext4_create_hardlink(new_path, &inode_ref);
- if (r != EOK)
- r = __ext4_create_hardlink(path, &inode_ref);
+ r = __ext4_create_hardlink(new_path, &inode_ref);
+ if (r != EOK)
+ r = __ext4_create_hardlink(path, &inode_ref);
- ext4_fs_put_inode_ref(&inode_ref);
+ ext4_fs_put_inode_ref(&inode_ref);
Finish:
- EXT4_MP_UNLOCK(mp);
- return r;
-
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
/****************************************************************************/
int ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb)
{
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
+ struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- *sb = &mp->fs.sb;
- return EOK;
+ *sb = &mp->fs.sb;
+ return EOK;
}
int ext4_cache_write_back(const char *path, bool on)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
- ext4_block_cache_write_back(mp->fs.bdev, on);
- EXT4_MP_UNLOCK(mp);
- return EOK;
+ EXT4_MP_LOCK(mp);
+ ext4_block_cache_write_back(mp->fs.bdev, on);
+ EXT4_MP_UNLOCK(mp);
+ return EOK;
}
int ext4_fremove(const char *path)
{
- ext4_file f;
- uint32_t parent_inode;
- uint32_t name_off;
- bool is_goal;
- int r;
- int len;
- struct ext4_inode_ref child;
- struct ext4_inode_ref parent;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
-
- if (!mp)
- return ENOENT;
-
- EXT4_MP_LOCK(mp);
- r = ext4_generic_open(&f, path, "r", true, &parent_inode, &name_off);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
-
- /*Load parent*/
- r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
-
- /*We have file to delete. Load it.*/
- r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &child);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&parent);
- EXT4_MP_UNLOCK(mp);
- return r;
- }
-
- /*Set path*/
- path += name_off;
-
- len = ext4_path_check(path, &is_goal);
-
- /*Unlink from parent*/
- r = ext4_unlink(mp, &parent, &child, path, len);
- if (r != EOK)
- goto Finish;
-
- /*Link count is zero, the inode should be freed. */
- if (!ext4_inode_get_links_count(child.inode)) {
- printf("ttttt\n");
- ext4_inode_set_deletion_time(child.inode, 0xFFFFFFFF);
- /*Turncate*/
- ext4_block_cache_write_back(mp->fs.bdev, 1);
- /*Truncate may be IO heavy. Do it writeback cache mode.*/
- r = ext4_fs_truncate_inode(&child, 0);
- ext4_block_cache_write_back(mp->fs.bdev, 0);
-
- if (r != EOK)
- goto Finish;
-
- r = ext4_fs_free_inode(&child);
- if (r != EOK)
- goto Finish;
-
- }
+ ext4_file f;
+ uint32_t parent_inode;
+ uint32_t name_off;
+ bool is_goal;
+ int r;
+ int len;
+ struct ext4_inode_ref child;
+ struct ext4_inode_ref parent;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+
+ if (!mp)
+ return ENOENT;
+
+ EXT4_MP_LOCK(mp);
+ r = ext4_generic_open(&f, path, "r", true, &parent_inode, &name_off);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
+
+ /*Load parent*/
+ r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
+
+ /*We have file to delete. Load it.*/
+ r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &child);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&parent);
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
+
+ /*Set path*/
+ path += name_off;
+
+ len = ext4_path_check(path, &is_goal);
+
+ /*Unlink from parent*/
+ r = ext4_unlink(mp, &parent, &child, path, len);
+ if (r != EOK)
+ goto Finish;
+
+ /*Link count is zero, the inode should be freed. */
+ if (!ext4_inode_get_links_count(child.inode)) {
+ printf("ttttt\n");
+ ext4_inode_set_deletion_time(child.inode, 0xFFFFFFFF);
+ /*Turncate*/
+ ext4_block_cache_write_back(mp->fs.bdev, 1);
+ /*Truncate may be IO heavy. Do it writeback cache mode.*/
+ r = ext4_fs_truncate_inode(&child, 0);
+ ext4_block_cache_write_back(mp->fs.bdev, 0);
+
+ if (r != EOK)
+ goto Finish;
+
+ r = ext4_fs_free_inode(&child);
+ if (r != EOK)
+ goto Finish;
+ }
Finish:
- ext4_fs_put_inode_ref(&child);
- ext4_fs_put_inode_ref(&parent);
- EXT4_MP_UNLOCK(mp);
- return r;
+ ext4_fs_put_inode_ref(&child);
+ ext4_fs_put_inode_ref(&parent);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
-int ext4_fill_raw_inode(const char *mount_point, uint32_t ino, struct ext4_inode *inode)
+int ext4_fill_raw_inode(const char *mount_point, uint32_t ino,
+ struct ext4_inode *inode)
{
- int r;
- struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
+ int r;
+ struct ext4_inode_ref inode_ref;
+ struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
+ EXT4_MP_LOCK(mp);
- /*Load parent*/
- r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
+ /*Load parent*/
+ r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
- memcpy(inode, inode_ref.inode, sizeof(struct ext4_inode));
+ memcpy(inode, inode_ref.inode, sizeof(struct ext4_inode));
- ext4_fs_put_inode_ref(&inode_ref);
- EXT4_MP_UNLOCK(mp);
- return r;
+ ext4_fs_put_inode_ref(&inode_ref);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_fopen(ext4_file *f, const char *path, const char *flags)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- int r;
-
- if (!mp)
- return ENOENT;
-
- EXT4_MP_LOCK(mp);
- ext4_block_cache_write_back(mp->fs.bdev, 1);
- r = ext4_generic_open(f, path, flags, true, 0, 0);
- ext4_block_cache_write_back(mp->fs.bdev, 0);
- EXT4_MP_UNLOCK(mp);
- return r;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ int r;
+
+ if (!mp)
+ return ENOENT;
+
+ EXT4_MP_LOCK(mp);
+ ext4_block_cache_write_back(mp->fs.bdev, 1);
+ r = ext4_generic_open(f, path, flags, true, 0, 0);
+ ext4_block_cache_write_back(mp->fs.bdev, 0);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_fopen2(ext4_file *f, const char *path, int flags, bool file_expect)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- int r;
- int filetype;
-
- if (!mp)
- return ENOENT;
-
- if (file_expect == true)
- filetype = EXT4_DIRECTORY_FILETYPE_REG_FILE;
- else
- filetype = EXT4_DIRECTORY_FILETYPE_DIR;
-
- EXT4_MP_LOCK(mp);
- ext4_block_cache_write_back(mp->fs.bdev, 1);
- r = ext4_generic_open2(f, path, flags, filetype, 0, 0);
- ext4_block_cache_write_back(mp->fs.bdev, 0);
- EXT4_MP_UNLOCK(mp);
- return r;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ int r;
+ int filetype;
+
+ if (!mp)
+ return ENOENT;
+
+ if (file_expect == true)
+ filetype = EXT4_DIRECTORY_FILETYPE_REG_FILE;
+ else
+ filetype = EXT4_DIRECTORY_FILETYPE_DIR;
+
+ EXT4_MP_LOCK(mp);
+ ext4_block_cache_write_back(mp->fs.bdev, 1);
+ r = ext4_generic_open2(f, path, flags, filetype, 0, 0);
+ ext4_block_cache_write_back(mp->fs.bdev, 0);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_fclose(ext4_file *f)
{
- ext4_assert(f && f->mp);
+ ext4_assert(f && f->mp);
- f->mp = 0;
- f->flags = 0;
- f->inode = 0;
- f->fpos = f->fsize = 0;
+ f->mp = 0;
+ f->flags = 0;
+ f->inode = 0;
+ f->fpos = f->fsize = 0;
- return EOK;
+ return EOK;
}
int ext4_ftruncate(ext4_file *f, uint64_t size)
{
- struct ext4_inode_ref ref;
- int r;
+ struct ext4_inode_ref ref;
+ int r;
+ ext4_assert(f && f->mp);
- ext4_assert(f && f->mp);
+ if (f->flags & O_RDONLY)
+ return EPERM;
- if (f->flags & O_RDONLY)
- return EPERM;
+ EXT4_MP_LOCK(f->mp);
- EXT4_MP_LOCK(f->mp);
+ r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(f->mp);
+ return r;
+ }
- r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(f->mp);
- return r;
- }
+ /*Sync file size*/
+ f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+ if (f->fsize <= size) {
+ r = EOK;
+ goto Finish;
+ }
- /*Sync file size*/
- f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
- if (f->fsize <= size) {
- r = EOK;
- goto Finish;
- }
+ /*Start write back cache mode.*/
+ r = ext4_block_cache_write_back(f->mp->fs.bdev, 1);
+ if (r != EOK)
+ goto Finish;
- /*Start write back cache mode.*/
- r = ext4_block_cache_write_back(f->mp->fs.bdev, 1);
- if (r != EOK)
- goto Finish;
+ r = ext4_fs_truncate_inode(&ref, size);
+ if (r != EOK)
+ goto Finish;
- r = ext4_fs_truncate_inode(&ref, size);
- if (r != EOK)
- goto Finish;
+ f->fsize = size;
+ if (f->fpos > size)
+ f->fpos = size;
- f->fsize = size;
- if (f->fpos > size)
- f->fpos = size;
+ /*Stop write back cache mode*/
+ ext4_block_cache_write_back(f->mp->fs.bdev, 0);
- /*Stop write back cache mode*/
- ext4_block_cache_write_back(f->mp->fs.bdev, 0);
-
- if (r != EOK)
- goto Finish;
+ if (r != EOK)
+ goto Finish;
Finish:
- ext4_fs_put_inode_ref(&ref);
- EXT4_MP_UNLOCK(f->mp);
- return r;
-
+ ext4_fs_put_inode_ref(&ref);
+ EXT4_MP_UNLOCK(f->mp);
+ return r;
}
int ext4_fread(ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)
{
- uint32_t u;
- uint32_t fblock;
- uint32_t fblock_start;
- uint32_t fblock_cnt;
- uint32_t sblock;
- uint32_t sblock_end;
- uint32_t block_size;
- uint8_t *u8_buf = buf;
- int r;
- struct ext4_block b;
- struct ext4_inode_ref ref;
+ uint32_t u;
+ uint32_t fblock;
+ uint32_t fblock_start;
+ uint32_t fblock_cnt;
+ uint32_t sblock;
+ uint32_t sblock_end;
+ uint32_t block_size;
+ uint8_t *u8_buf = buf;
+ int r;
+ struct ext4_block b;
+ struct ext4_inode_ref ref;
- ext4_assert(f && f->mp);
+ ext4_assert(f && f->mp);
- if (f->flags & O_WRONLY)
- return EPERM;
+ if (f->flags & O_WRONLY)
+ return EPERM;
- if (!size)
- return EOK;
+ if (!size)
+ return EOK;
- EXT4_MP_LOCK(f->mp);
+ EXT4_MP_LOCK(f->mp);
- if (rcnt)
- *rcnt = 0;
+ if (rcnt)
+ *rcnt = 0;
- r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(f->mp);
- return r;
- }
+ r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(f->mp);
+ return r;
+ }
- /*Sync file size*/
- f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+ /*Sync file size*/
+ f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
- block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
- size = size > (f->fsize - f->fpos) ? (f->fsize - f->fpos) : size;
- sblock = (f->fpos) / block_size;
- sblock_end = (f->fpos + size) / block_size;
- u = (f->fpos) % block_size;
+ block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
+ size = size > (f->fsize - f->fpos) ? (f->fsize - f->fpos) : size;
+ sblock = (f->fpos) / block_size;
+ sblock_end = (f->fpos + size) / block_size;
+ u = (f->fpos) % block_size;
- if (u) {
+ if (u) {
- uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
+ uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
- r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
- if (r != EOK)
- goto Finish;
+ r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+ if (r != EOK)
+ goto Finish;
- r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
- if (r != EOK)
- goto Finish;
+ r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+ if (r != EOK)
+ goto Finish;
- memcpy(u8_buf, b.data + u, ll);
+ memcpy(u8_buf, b.data + u, ll);
- r = ext4_block_set(f->mp->fs.bdev, &b);
- if (r != EOK)
- goto Finish;
+ r = ext4_block_set(f->mp->fs.bdev, &b);
+ if (r != EOK)
+ goto Finish;
- u8_buf += ll;
- size -= ll;
- f->fpos += ll;
+ u8_buf += ll;
+ size -= ll;
+ f->fpos += ll;
- if (rcnt)
- *rcnt += ll;
+ if (rcnt)
+ *rcnt += ll;
- sblock++;
- }
+ sblock++;
+ }
- fblock_start = 0;
- fblock_cnt = 0;
- while (size >= block_size) {
- while (sblock < sblock_end) {
- r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
- if (r != EOK)
- goto Finish;
+ fblock_start = 0;
+ fblock_cnt = 0;
+ while (size >= block_size) {
+ while (sblock < sblock_end) {
+ r = ext4_fs_get_inode_data_block_index(&ref, sblock,
+ &fblock);
+ if (r != EOK)
+ goto Finish;
- sblock++;
+ sblock++;
- if (!fblock_start) {
- fblock_start = fblock;
- }
+ if (!fblock_start) {
+ fblock_start = fblock;
+ }
- if ((fblock_start + fblock_cnt) != fblock)
- break;
+ if ((fblock_start + fblock_cnt) != fblock)
+ break;
- fblock_cnt++;
- }
+ fblock_cnt++;
+ }
- r = ext4_blocks_get_direct(f->mp->fs.bdev, u8_buf, fblock_start,
- fblock_cnt);
- if (r != EOK)
- goto Finish;
+ r = ext4_blocks_get_direct(f->mp->fs.bdev, u8_buf, fblock_start,
+ fblock_cnt);
+ if (r != EOK)
+ goto Finish;
- size -= block_size * fblock_cnt;
- u8_buf += block_size * fblock_cnt;
- f->fpos += block_size * fblock_cnt;
+ size -= block_size * fblock_cnt;
+ u8_buf += block_size * fblock_cnt;
+ f->fpos += block_size * fblock_cnt;
- if (rcnt)
- *rcnt += block_size * fblock_cnt;
+ if (rcnt)
+ *rcnt += block_size * fblock_cnt;
- fblock_start = fblock;
- fblock_cnt = 1;
- }
+ fblock_start = fblock;
+ fblock_cnt = 1;
+ }
- if (size) {
- r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
- if (r != EOK)
- goto Finish;
+ if (size) {
+ r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+ if (r != EOK)
+ goto Finish;
- r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
- if (r != EOK)
- goto Finish;
+ r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+ if (r != EOK)
+ goto Finish;
- memcpy(u8_buf, b.data, size);
+ memcpy(u8_buf, b.data, size);
- r = ext4_block_set(f->mp->fs.bdev, &b);
- if (r != EOK)
- goto Finish;
+ r = ext4_block_set(f->mp->fs.bdev, &b);
+ if (r != EOK)
+ goto Finish;
- f->fpos += size;
+ f->fpos += size;
- if (rcnt)
- *rcnt += size;
- }
+ if (rcnt)
+ *rcnt += size;
+ }
Finish:
- ext4_fs_put_inode_ref(&ref);
- EXT4_MP_UNLOCK(f->mp);
- return r;
+ ext4_fs_put_inode_ref(&ref);
+ EXT4_MP_UNLOCK(f->mp);
+ return r;
}
int ext4_fwrite(ext4_file *f, const void *buf, uint32_t size, uint32_t *wcnt)
{
- uint32_t u;
- uint32_t fblock;
-
- uint32_t sblock;
- uint32_t sblock_end;
- uint32_t file_blocks;
- uint32_t block_size;
- uint32_t fblock_start;
- uint32_t fblock_cnt;
-
- struct ext4_block b;
- struct ext4_inode_ref ref;
- const uint8_t *u8_buf = buf;
- int r;
+ uint32_t u;
+ uint32_t fblock;
+ uint32_t sblock;
+ uint32_t sblock_end;
+ uint32_t file_blocks;
+ uint32_t block_size;
+ uint32_t fblock_start;
+ uint32_t fblock_cnt;
- ext4_assert(f && f->mp);
+ struct ext4_block b;
+ struct ext4_inode_ref ref;
+ const uint8_t *u8_buf = buf;
+ int r;
- if (f->flags & O_RDONLY)
- return EPERM;
+ ext4_assert(f && f->mp);
- if (!size)
- return EOK;
+ if (f->flags & O_RDONLY)
+ return EPERM;
- EXT4_MP_LOCK(f->mp);
+ if (!size)
+ return EOK;
- if (wcnt)
- *wcnt = 0;
+ EXT4_MP_LOCK(f->mp);
- r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(f->mp);
- return r;
- }
+ if (wcnt)
+ *wcnt = 0;
- /*Sync file size*/
- f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+ r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(f->mp);
+ return r;
+ }
- block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
+ /*Sync file size*/
+ f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
- sblock_end = (f->fpos + size) > f->fsize ? (f->fpos + size) : f->fsize;
- sblock_end /= block_size;
- file_blocks = (f->fsize / block_size);
+ block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
- if (f->fsize % block_size)
- file_blocks++;
+ sblock_end = (f->fpos + size) > f->fsize ? (f->fpos + size) : f->fsize;
+ sblock_end /= block_size;
+ file_blocks = (f->fsize / block_size);
- sblock = (f->fpos) / block_size;
+ if (f->fsize % block_size)
+ file_blocks++;
- u = (f->fpos) % block_size;
+ sblock = (f->fpos) / block_size;
- if (u) {
- uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
+ u = (f->fpos) % block_size;
- r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
- if (r != EOK)
- goto Finish;
+ if (u) {
+ uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
- r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
- if (r != EOK)
- goto Finish;
+ r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+ if (r != EOK)
+ goto Finish;
- memcpy(b.data + u, u8_buf, ll);
- b.dirty = true;
+ r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+ if (r != EOK)
+ goto Finish;
- r = ext4_block_set(f->mp->fs.bdev, &b);
- if (r != EOK)
- goto Finish;
+ memcpy(b.data + u, u8_buf, ll);
+ b.dirty = true;
- u8_buf += ll;
- size -= ll;
- f->fpos += ll;
+ r = ext4_block_set(f->mp->fs.bdev, &b);
+ if (r != EOK)
+ goto Finish;
- if (wcnt)
- *wcnt += ll;
+ u8_buf += ll;
+ size -= ll;
+ f->fpos += ll;
- sblock++;
- }
+ if (wcnt)
+ *wcnt += ll;
- /*Start write back cache mode.*/
- r = ext4_block_cache_write_back(f->mp->fs.bdev, 1);
- if (r != EOK)
- goto Finish;
+ sblock++;
+ }
- fblock_start = 0;
- fblock_cnt = 0;
- while (size >= block_size) {
+ /*Start write back cache mode.*/
+ r = ext4_block_cache_write_back(f->mp->fs.bdev, 1);
+ if (r != EOK)
+ goto Finish;
- while (sblock < sblock_end) {
- if (sblock < file_blocks) {
- r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
- if (r != EOK)
- break;
- } else {
- r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
- if (r != EOK)
- break;
- }
+ fblock_start = 0;
+ fblock_cnt = 0;
+ while (size >= block_size) {
- sblock++;
+ while (sblock < sblock_end) {
+ if (sblock < file_blocks) {
+ r = ext4_fs_get_inode_data_block_index(
+ &ref, sblock, &fblock);
+ if (r != EOK)
+ break;
+ } else {
+ r = ext4_fs_append_inode_block(&ref, &fblock,
+ &sblock);
+ if (r != EOK)
+ break;
+ }
- if (!fblock_start) {
- fblock_start = fblock;
- }
+ sblock++;
- if ((fblock_start + fblock_cnt) != fblock)
- break;
+ if (!fblock_start) {
+ fblock_start = fblock;
+ }
- fblock_cnt++;
- }
+ if ((fblock_start + fblock_cnt) != fblock)
+ break;
- r = ext4_blocks_set_direct(f->mp->fs.bdev, u8_buf, fblock_start,
- fblock_cnt);
- if (r != EOK)
- break;
+ fblock_cnt++;
+ }
- size -= block_size * fblock_cnt;
- u8_buf += block_size * fblock_cnt;
- f->fpos += block_size * fblock_cnt;
+ r = ext4_blocks_set_direct(f->mp->fs.bdev, u8_buf, fblock_start,
+ fblock_cnt);
+ if (r != EOK)
+ break;
- if (wcnt)
- *wcnt += block_size * fblock_cnt;
+ size -= block_size * fblock_cnt;
+ u8_buf += block_size * fblock_cnt;
+ f->fpos += block_size * fblock_cnt;
- fblock_start = fblock;
- fblock_cnt = 1;
- }
+ if (wcnt)
+ *wcnt += block_size * fblock_cnt;
- /*Stop write back cache mode*/
- ext4_block_cache_write_back(f->mp->fs.bdev, 0);
+ fblock_start = fblock;
+ fblock_cnt = 1;
+ }
- if (r != EOK)
- goto Finish;
+ /*Stop write back cache mode*/
+ ext4_block_cache_write_back(f->mp->fs.bdev, 0);
- if (size) {
- if (sblock < file_blocks) {
- r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
- if (r != EOK)
- goto Finish;
- } else {
- r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
- if (r != EOK)
- goto Finish;
- }
+ if (r != EOK)
+ goto Finish;
- r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
- if (r != EOK)
- goto Finish;
+ if (size) {
+ if (sblock < file_blocks) {
+ r = ext4_fs_get_inode_data_block_index(&ref, sblock,
+ &fblock);
+ if (r != EOK)
+ goto Finish;
+ } else {
+ r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
+ if (r != EOK)
+ goto Finish;
+ }
- memcpy(b.data, u8_buf, size);
- b.dirty = true;
-
- r = ext4_block_set(f->mp->fs.bdev, &b);
- if (r != EOK)
- goto Finish;
-
- f->fpos += size;
-
- if (wcnt)
- *wcnt += size;
- }
-
- if (f->fpos > f->fsize) {
- f->fsize = f->fpos;
- ext4_inode_set_size(ref.inode, f->fsize);
- ref.dirty = true;
- }
+ r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+ if (r != EOK)
+ goto Finish;
+
+ memcpy(b.data, u8_buf, size);
+ b.dirty = true;
+
+ r = ext4_block_set(f->mp->fs.bdev, &b);
+ if (r != EOK)
+ goto Finish;
+
+ f->fpos += size;
+
+ if (wcnt)
+ *wcnt += size;
+ }
+
+ if (f->fpos > f->fsize) {
+ f->fsize = f->fpos;
+ ext4_inode_set_size(ref.inode, f->fsize);
+ ref.dirty = true;
+ }
Finish:
- ext4_fs_put_inode_ref(&ref);
- EXT4_MP_UNLOCK(f->mp);
- return r;
+ ext4_fs_put_inode_ref(&ref);
+ EXT4_MP_UNLOCK(f->mp);
+ return r;
}
int ext4_fseek(ext4_file *f, uint64_t offset, uint32_t origin)
{
- switch (origin) {
- case SEEK_SET:
- if (offset > f->fsize)
- return EINVAL;
-
- f->fpos = offset;
- return EOK;
- case SEEK_CUR:
- if ((offset + f->fpos) > f->fsize)
- return EINVAL;
-
- f->fpos += offset;
- return EOK;
- case SEEK_END:
- if (offset > f->fsize)
- return EINVAL;
-
- f->fpos = f->fsize - offset;
- return EOK;
- }
- return EINVAL;
+ switch (origin) {
+ case SEEK_SET:
+ if (offset > f->fsize)
+ return EINVAL;
+
+ f->fpos = offset;
+ return EOK;
+ case SEEK_CUR:
+ if ((offset + f->fpos) > f->fsize)
+ return EINVAL;
+
+ f->fpos += offset;
+ return EOK;
+ case SEEK_END:
+ if (offset > f->fsize)
+ return EINVAL;
+
+ f->fpos = f->fsize - offset;
+ return EOK;
+ }
+ return EINVAL;
}
-uint64_t ext4_ftell(ext4_file *f)
-{
- return f->fpos;
-}
+uint64_t ext4_ftell(ext4_file *f) { return f->fpos; }
-uint64_t ext4_fsize(ext4_file *f)
-{
- return f->fsize;
-}
+uint64_t ext4_fsize(ext4_file *f) { return f->fsize; }
int ext4_fchmod(ext4_file *f, uint32_t mode)
{
- int r;
- uint32_t ino;
- struct ext4_sblock *sb;
- struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = f->mp;
-
- if (!mp)
- return ENOENT;
-
- EXT4_MP_LOCK(mp);
-
- ino = f->inode;
- r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
-
- sb = &f->mp->fs.sb;
- ext4_inode_set_mode(sb, inode_ref.inode, mode);
- inode_ref.dirty = true;
-
- ext4_fs_put_inode_ref(&inode_ref);
- EXT4_MP_UNLOCK(mp);
- return r;
+ int r;
+ uint32_t ino;
+ struct ext4_sblock *sb;
+ struct ext4_inode_ref inode_ref;
+ struct ext4_mountpoint *mp = f->mp;
+
+ if (!mp)
+ return ENOENT;
+
+ EXT4_MP_LOCK(mp);
+
+ ino = f->inode;
+ r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
+
+ sb = &f->mp->fs.sb;
+ ext4_inode_set_mode(sb, inode_ref.inode, mode);
+ inode_ref.dirty = true;
+
+ ext4_fs_put_inode_ref(&inode_ref);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_fchown(ext4_file *f, uint32_t uid, uint32_t gid)
{
- int r;
- uint32_t ino;
- struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = f->mp;
-
- if (!mp)
- return ENOENT;
-
- EXT4_MP_LOCK(mp);
-
- ino = f->inode;
- r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
-
- ext4_inode_set_uid(inode_ref.inode, uid);
- ext4_inode_set_gid(inode_ref.inode, gid);
- inode_ref.dirty = true;
-
- ext4_fs_put_inode_ref(&inode_ref);
- EXT4_MP_UNLOCK(mp);
- return r;
+ int r;
+ uint32_t ino;
+ struct ext4_inode_ref inode_ref;
+ struct ext4_mountpoint *mp = f->mp;
+
+ if (!mp)
+ return ENOENT;
+
+ EXT4_MP_LOCK(mp);
+
+ ino = f->inode;
+ r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
+
+ ext4_inode_set_uid(inode_ref.inode, uid);
+ ext4_inode_set_gid(inode_ref.inode, gid);
+ inode_ref.dirty = true;
+
+ ext4_fs_put_inode_ref(&inode_ref);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_file_set_atime(ext4_file *f, uint32_t atime)
{
- int r;
- uint32_t ino;
- struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = f->mp;
+ int r;
+ uint32_t ino;
+ struct ext4_inode_ref inode_ref;
+ struct ext4_mountpoint *mp = f->mp;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
+ EXT4_MP_LOCK(mp);
- ino = f->inode;
- r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
+ ino = f->inode;
+ r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
- ext4_inode_set_access_time(inode_ref.inode, atime);
- inode_ref.dirty = true;
+ ext4_inode_set_access_time(inode_ref.inode, atime);
+ inode_ref.dirty = true;
- ext4_fs_put_inode_ref(&inode_ref);
- EXT4_MP_UNLOCK(mp);
- return r;
+ ext4_fs_put_inode_ref(&inode_ref);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_file_set_mtime(ext4_file *f, uint32_t mtime)
{
- int r;
- uint32_t ino;
- struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = f->mp;
+ int r;
+ uint32_t ino;
+ struct ext4_inode_ref inode_ref;
+ struct ext4_mountpoint *mp = f->mp;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
+ EXT4_MP_LOCK(mp);
- ino = f->inode;
- r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
+ ino = f->inode;
+ r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
- ext4_inode_set_modification_time(inode_ref.inode, mtime);
- inode_ref.dirty = true;
+ ext4_inode_set_modification_time(inode_ref.inode, mtime);
+ inode_ref.dirty = true;
- ext4_fs_put_inode_ref(&inode_ref);
- EXT4_MP_UNLOCK(mp);
- return r;
+ ext4_fs_put_inode_ref(&inode_ref);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_file_set_ctime(ext4_file *f, uint32_t ctime)
{
- int r;
- uint32_t ino;
- struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = f->mp;
+ int r;
+ uint32_t ino;
+ struct ext4_inode_ref inode_ref;
+ struct ext4_mountpoint *mp = f->mp;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
+ EXT4_MP_LOCK(mp);
- ino = f->inode;
- r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
+ ino = f->inode;
+ r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
- ext4_inode_set_change_inode_time(inode_ref.inode, ctime);
- inode_ref.dirty = true;
+ ext4_inode_set_change_inode_time(inode_ref.inode, ctime);
+ inode_ref.dirty = true;
- ext4_fs_put_inode_ref(&inode_ref);
- EXT4_MP_UNLOCK(mp);
- return r;
+ ext4_fs_put_inode_ref(&inode_ref);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
/*********************************DIRECTORY OPERATION************************/
int ext4_dir_rm(const char *path)
{
- int r;
- int len;
- ext4_file f;
-
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- struct ext4_inode_ref current;
- struct ext4_inode_ref child;
- struct ext4_directory_iterator it;
-
- uint32_t name_off;
- uint32_t inode_up;
- uint32_t inode_current;
- uint32_t depth = 1;
-
- bool has_children;
- bool is_goal;
- bool dir_end;
-
- if (!mp)
- return ENOENT;
-
- EXT4_MP_LOCK(mp);
-
- /*Check if exist.*/
- r = ext4_generic_open(&f, path, "r", false, &inode_up, &name_off);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
-
- path += name_off;
- len = ext4_path_check(path, &is_goal);
-
- inode_current = f.inode;
- dir_end = false;
-
- ext4_block_cache_write_back(mp->fs.bdev, 1);
-
- do {
- /*Load directory node.*/
- r = ext4_fs_get_inode_ref(&f.mp->fs, inode_current, ¤t);
- if (r != EOK) {
- break;
- }
-
- /*Initialize iterator.*/
- r = ext4_dir_iterator_init(&it, ¤t, 0);
- if (r != EOK) {
- ext4_fs_put_inode_ref(¤t);
- break;
- }
-
- while (r == EOK) {
-
- if (!it.current) {
- dir_end = true;
- break;
- }
-
- /*Get up directory inode when ".." entry*/
- if ((it.current->name_length == 2) &&
- ext4_is_dots(it.current->name, it.current->name_length)) {
- inode_up = it.current->inode;
- }
-
- /*If directory or file entry, but not "." ".." entry*/
- if (!ext4_is_dots(it.current->name, it.current->name_length)) {
-
- /*Get child inode reference do unlink directory/file.*/
- r = ext4_fs_get_inode_ref(&f.mp->fs, it.current->inode, &child);
- if (r != EOK)
- break;
-
- /*If directory with no leaf children*/
- r = ext4_has_children(&has_children, &child);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&child);
- break;
- }
-
- if (has_children) {
- /*Has directory children. Go into this directory.*/
- inode_up = inode_current;
- inode_current = it.current->inode;
- depth++;
- ext4_fs_put_inode_ref(&child);
- break;
- }
-
- /*No children in child directory or file. Just unlink.*/
- r = ext4_unlink(f.mp, ¤t, &child,
- (char *)it.current->name,
- it.current->name_length);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&child);
- break;
- }
-
- ext4_inode_set_deletion_time(child.inode, 0xFFFFFFFF);
- ext4_inode_set_links_count(child.inode, 0);
- child.dirty = true;
- /*Turncate*/
- r = ext4_fs_truncate_inode(&child, 0);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&child);
- break;
- }
-
- r = ext4_fs_free_inode(&child);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&child);
- break;
- }
-
-
- r = ext4_fs_put_inode_ref(&child);
- if (r != EOK)
- break;
- }
-
- r = ext4_dir_iterator_next(&it);
- }
-
- if (dir_end) {
- /*Directory iterator reached last entry*/
- ext4_has_children(&has_children, ¤t);
- if (!has_children) {
- inode_current = inode_up;
- if (depth)
- depth--;
- }
- /*Last unlink*/
- if (!depth) {
- /*Load parent.*/
- struct ext4_inode_ref parent;
- r = ext4_fs_get_inode_ref(&f.mp->fs, inode_up, &parent);
- if (r != EOK)
- goto End;
-
- /* In this place all directories should be unlinked.
- * Last unlink from root of current directory*/
- r = ext4_unlink(f.mp, &parent, ¤t, (char *)path, len);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&parent);
- goto End;
- }
-
- if (ext4_inode_get_links_count(current.inode) == 2) {
- ext4_inode_set_deletion_time(current.inode, 0xFFFFFFFF);
- ext4_inode_set_links_count(current.inode, 0);
- current.dirty = true;
- /*Turncate*/
- r = ext4_fs_truncate_inode(¤t, 0);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&parent);
- goto End;
- }
-
- r = ext4_fs_free_inode(¤t);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&parent);
- goto End;
- }
-
- }
-
- r = ext4_fs_put_inode_ref(&parent);
- if (r != EOK)
- goto End;
- }
- }
-
- End:
- ext4_dir_iterator_fini(&it);
- ext4_fs_put_inode_ref(¤t);
- dir_end = false;
-
- /*When something goes wrong. End loop.*/
- if (r != EOK)
- break;
-
- } while (depth);
-
- ext4_block_cache_write_back(mp->fs.bdev, 0);
- EXT4_MP_UNLOCK(mp);
- return r;
+ int r;
+ int len;
+ ext4_file f;
+
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ struct ext4_inode_ref current;
+ struct ext4_inode_ref child;
+ struct ext4_directory_iterator it;
+
+ uint32_t name_off;
+ uint32_t inode_up;
+ uint32_t inode_current;
+ uint32_t depth = 1;
+
+ bool has_children;
+ bool is_goal;
+ bool dir_end;
+
+ if (!mp)
+ return ENOENT;
+
+ EXT4_MP_LOCK(mp);
+
+ /*Check if exist.*/
+ r = ext4_generic_open(&f, path, "r", false, &inode_up, &name_off);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
+
+ path += name_off;
+ len = ext4_path_check(path, &is_goal);
+
+ inode_current = f.inode;
+ dir_end = false;
+
+ ext4_block_cache_write_back(mp->fs.bdev, 1);
+
+ do {
+ /*Load directory node.*/
+ r = ext4_fs_get_inode_ref(&f.mp->fs, inode_current, ¤t);
+ if (r != EOK) {
+ break;
+ }
+
+ /*Initialize iterator.*/
+ r = ext4_dir_iterator_init(&it, ¤t, 0);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(¤t);
+ break;
+ }
+
+ while (r == EOK) {
+
+ if (!it.current) {
+ dir_end = true;
+ break;
+ }
+
+ /*Get up directory inode when ".." entry*/
+ if ((it.current->name_length == 2) &&
+ ext4_is_dots(it.current->name,
+ it.current->name_length)) {
+ inode_up = it.current->inode;
+ }
+
+ /*If directory or file entry, but not "." ".." entry*/
+ if (!ext4_is_dots(it.current->name,
+ it.current->name_length)) {
+
+ /*Get child inode reference do unlink
+ * directory/file.*/
+ r = ext4_fs_get_inode_ref(
+ &f.mp->fs, it.current->inode, &child);
+ if (r != EOK)
+ break;
+
+ /*If directory with no leaf children*/
+ r = ext4_has_children(&has_children, &child);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&child);
+ break;
+ }
+
+ if (has_children) {
+ /*Has directory children. Go into this
+ * directory.*/
+ inode_up = inode_current;
+ inode_current = it.current->inode;
+ depth++;
+ ext4_fs_put_inode_ref(&child);
+ break;
+ }
+
+ /*No children in child directory or file. Just
+ * unlink.*/
+ r = ext4_unlink(f.mp, ¤t, &child,
+ (char *)it.current->name,
+ it.current->name_length);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&child);
+ break;
+ }
+
+ ext4_inode_set_deletion_time(child.inode,
+ 0xFFFFFFFF);
+ ext4_inode_set_links_count(child.inode, 0);
+ child.dirty = true;
+ /*Turncate*/
+ r = ext4_fs_truncate_inode(&child, 0);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&child);
+ break;
+ }
+
+ r = ext4_fs_free_inode(&child);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&child);
+ break;
+ }
+
+ r = ext4_fs_put_inode_ref(&child);
+ if (r != EOK)
+ break;
+ }
+
+ r = ext4_dir_iterator_next(&it);
+ }
+
+ if (dir_end) {
+ /*Directory iterator reached last entry*/
+ ext4_has_children(&has_children, ¤t);
+ if (!has_children) {
+ inode_current = inode_up;
+ if (depth)
+ depth--;
+ }
+ /*Last unlink*/
+ if (!depth) {
+ /*Load parent.*/
+ struct ext4_inode_ref parent;
+ r = ext4_fs_get_inode_ref(&f.mp->fs, inode_up,
+ &parent);
+ if (r != EOK)
+ goto End;
+
+ /* In this place all directories should be
+ * unlinked.
+ * Last unlink from root of current directory*/
+ r = ext4_unlink(f.mp, &parent, ¤t,
+ (char *)path, len);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&parent);
+ goto End;
+ }
+
+ if (ext4_inode_get_links_count(current.inode) ==
+ 2) {
+ ext4_inode_set_deletion_time(
+ current.inode, 0xFFFFFFFF);
+ ext4_inode_set_links_count(
+ current.inode, 0);
+ current.dirty = true;
+ /*Turncate*/
+ r = ext4_fs_truncate_inode(¤t, 0);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&parent);
+ goto End;
+ }
+
+ r = ext4_fs_free_inode(¤t);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&parent);
+ goto End;
+ }
+ }
+
+ r = ext4_fs_put_inode_ref(&parent);
+ if (r != EOK)
+ goto End;
+ }
+ }
+
+ End:
+ ext4_dir_iterator_fini(&it);
+ ext4_fs_put_inode_ref(¤t);
+ dir_end = false;
+
+ /*When something goes wrong. End loop.*/
+ if (r != EOK)
+ break;
+
+ } while (depth);
+
+ ext4_block_cache_write_back(mp->fs.bdev, 0);
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_dir_mk(const char *path)
{
- int r;
- ext4_file f;
+ int r;
+ ext4_file f;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
+ EXT4_MP_LOCK(mp);
- /*Check if exist.*/
- r = ext4_generic_open(&f, path, "r", false, 0, 0);
- if (r == EOK) {
- /*Directory already created*/
- EXT4_MP_UNLOCK(mp);
- return r;
- }
+ /*Check if exist.*/
+ r = ext4_generic_open(&f, path, "r", false, 0, 0);
+ if (r == EOK) {
+ /*Directory already created*/
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
- /*Create new dir*/
- r = ext4_generic_open(&f, path, "w", false, 0, 0);
- if (r != EOK) {
- EXT4_MP_UNLOCK(mp);
- return r;
- }
+ /*Create new dir*/
+ r = ext4_generic_open(&f, path, "w", false, 0, 0);
+ if (r != EOK) {
+ EXT4_MP_UNLOCK(mp);
+ return r;
+ }
- EXT4_MP_UNLOCK(mp);
- return r;
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_dir_open(ext4_dir *d, const char *path)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- int r;
+ struct ext4_mountpoint *mp = ext4_get_mount(path);
+ int r;
- if (!mp)
- return ENOENT;
+ if (!mp)
+ return ENOENT;
- EXT4_MP_LOCK(mp);
- r = ext4_generic_open(&d->f, path, "r", false, 0, 0);
- d->next_off = 0;
- EXT4_MP_UNLOCK(mp);
- return r;
+ EXT4_MP_LOCK(mp);
+ r = ext4_generic_open(&d->f, path, "r", false, 0, 0);
+ d->next_off = 0;
+ EXT4_MP_UNLOCK(mp);
+ return r;
}
int ext4_dir_close(ext4_dir *d) { return ext4_fclose(&d->f); }
@@ -1869,40 +1884,41 @@ const ext4_direntry *ext4_dir_entry_next(ext4_dir *d) {
#define EXT4_DIR_ENTRY_OFFSET_TERM (uint64_t)(-1)
- int r;
- ext4_direntry *de = 0;
- struct ext4_inode_ref dir;
- struct ext4_directory_iterator it;
+ int r;
+ ext4_direntry *de = 0;
+ struct ext4_inode_ref dir;
+ struct ext4_directory_iterator it;
- EXT4_MP_LOCK(d->f.mp);
+ EXT4_MP_LOCK(d->f.mp);
- if (d->next_off == EXT4_DIR_ENTRY_OFFSET_TERM)
- return 0;
+ if (d->next_off == EXT4_DIR_ENTRY_OFFSET_TERM)
+ return 0;
- r = ext4_fs_get_inode_ref(&d->f.mp->fs, d->f.inode, &dir);
- if (r != EOK) {
- goto Finish;
- }
+ r = ext4_fs_get_inode_ref(&d->f.mp->fs, d->f.inode, &dir);
+ if (r != EOK) {
+ goto Finish;
+ }
- r = ext4_dir_iterator_init(&it, &dir, d->next_off);
- if (r != EOK) {
- ext4_fs_put_inode_ref(&dir);
- goto Finish;
- }
+ r = ext4_dir_iterator_init(&it, &dir, d->next_off);
+ if (r != EOK) {
+ ext4_fs_put_inode_ref(&dir);
+ goto Finish;
+ }
- memcpy(&d->de, it.current, sizeof(ext4_direntry));
- de = &d->de;
+ memcpy(&d->de, it.current, sizeof(ext4_direntry));
+ de = &d->de;
- ext4_dir_iterator_next(&it);
+ ext4_dir_iterator_next(&it);
- d->next_off = it.current ? it.current_offset : EXT4_DIR_ENTRY_OFFSET_TERM;
+ d->next_off =
+ it.current ? it.current_offset : EXT4_DIR_ENTRY_OFFSET_TERM;
- ext4_dir_iterator_fini(&it);
- ext4_fs_put_inode_ref(&dir);
+ ext4_dir_iterator_fini(&it);
+ ext4_fs_put_inode_ref(&dir);
Finish:
- EXT4_MP_UNLOCK(d->f.mp);
- return de;
+ EXT4_MP_UNLOCK(d->f.mp);
+ return de;
}
/**
diff --git a/lwext4/ext4.h b/lwext4/ext4.h index 4169023..a0fae64 100644 --- a/lwext4/ext4.h +++ b/lwext4/ext4.h @@ -93,11 +93,11 @@ /**@brief OS dependent lock interface.*/
struct ext4_lock {
- /**@brief Lock access to mount point*/
- void (*lock)(void);
+ /**@brief Lock access to mount point*/
+ void (*lock)(void);
- /**@brief Unlock access to mount point*/
- void (*unlock)(void);
+ /**@brief Unlock access to mount point*/
+ void (*unlock)(void);
};
/********************************FILE DESCRIPTOR*****************************/
@@ -105,51 +105,49 @@ struct ext4_lock { /**@brief File descriptor*/
typedef struct ext4_file {
- /**@brief Mount point handle.*/
- struct ext4_mountpoint *mp;
+ /**@brief Mount point handle.*/
+ struct ext4_mountpoint *mp;
- /**@brief File inode id*/
- uint32_t inode;
+ /**@brief File inode id*/
+ uint32_t inode;
- /**@brief Open flags.*/
- uint32_t flags;
+ /**@brief Open flags.*/
+ uint32_t flags;
- /**@brief File size.*/
- uint64_t fsize;
+ /**@brief File size.*/
+ uint64_t fsize;
- /**@brief File position*/
- uint64_t fpos;
+ /**@brief File position*/
+ uint64_t fpos;
} ext4_file;
/*****************************DIRECTORY DESCRIPTOR***************************/
/**@brief Directory entry types. Copy from ext4_types.h*/
-enum {
- EXT4_DIRENTRY_UNKNOWN = 0,
- EXT4_DIRENTRY_REG_FILE,
- EXT4_DIRENTRY_DIR,
- EXT4_DIRENTRY_CHRDEV,
- EXT4_DIRENTRY_BLKDEV,
- EXT4_DIRENTRY_FIFO,
- EXT4_DIRENTRY_SOCK,
- EXT4_DIRENTRY_SYMLINK
-};
+enum { EXT4_DIRENTRY_UNKNOWN = 0,
+ EXT4_DIRENTRY_REG_FILE,
+ EXT4_DIRENTRY_DIR,
+ EXT4_DIRENTRY_CHRDEV,
+ EXT4_DIRENTRY_BLKDEV,
+ EXT4_DIRENTRY_FIFO,
+ EXT4_DIRENTRY_SOCK,
+ EXT4_DIRENTRY_SYMLINK };
/**@brief Directory entry descriptor. Copy from ext4_types.h*/
typedef struct {
- uint32_t inode;
- uint16_t entry_length;
- uint8_t name_length;
- uint8_t inode_type;
- uint8_t name[255];
+ uint32_t inode;
+ uint16_t entry_length;
+ uint8_t name_length;
+ uint8_t inode_type;
+ uint8_t name[255];
} ext4_direntry;
typedef struct {
- /**@brief File descriptor*/
- ext4_file f;
- /**@brief Current directory entry.*/
- ext4_direntry de;
- /**@brief Next entry offset*/
- uint64_t next_off;
+ /**@brief File descriptor*/
+ ext4_file f;
+ /**@brief Current directory entry.*/
+ ext4_direntry de;
+ /**@brief Next entry offset*/
+ uint64_t next_off;
} ext4_dir;
/********************************MOUNT OPERATIONS****************************/
@@ -164,7 +162,7 @@ typedef struct { * @param dev_name register name
* @param standard error code*/
int ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
- const char *dev_name);
+ const char *dev_name);
/**@brief Mount a block device with EXT4 partition to the mount point.
* @param dev_name block device name (@ref ext4_device_register)
@@ -183,17 +181,17 @@ int ext4_umount(const char *mount_point); /**@brief Some of the filesystem stats.*/
struct ext4_mount_stats {
- uint32_t inodes_count;
- uint32_t free_inodes_count;
- uint64_t blocks_count;
- uint64_t free_blocks_count;
+ uint32_t inodes_count;
+ uint32_t free_inodes_count;
+ uint64_t blocks_count;
+ uint64_t free_blocks_count;
- uint32_t block_size;
- uint32_t block_group_count;
- uint32_t blocks_per_group;
- uint32_t inodes_per_group;
+ uint32_t block_size;
+ uint32_t block_group_count;
+ uint32_t blocks_per_group;
+ uint32_t inodes_per_group;
- char volume_name[16];
+ char volume_name[16];
};
/**@brief Get file system params.
@@ -201,14 +199,14 @@ struct ext4_mount_stats { * @param stats ext fs stats
* @return standard error code */
int ext4_mount_point_stats(const char *mount_point,
- struct ext4_mount_stats *stats);
+ struct ext4_mount_stats *stats);
/**@brief Setup OS lock routines.
* @param mount_point mount path
* @param locks - lock and unlock functions
* @return standard error code */
int ext4_mount_setup_locks(const char *mount_point,
- const struct ext4_lock *locks);
+ const struct ext4_lock *locks);
/**@brief Acquire the filesystem superblock pointer of a mp.
* @param mount_point mount path
@@ -304,7 +302,8 @@ int ext4_fclose(ext4_file *f); * @param inode no.
* @param ext4_inode buffer
* @return standard error code*/
-int ext4_fill_raw_inode(const char *mount_point, uint32_t ino, struct ext4_inode *inode);
+int ext4_fill_raw_inode(const char *mount_point, uint32_t ino,
+ struct ext4_inode *inode);
/**@brief File truncate function.
* @param f file handle
diff --git a/lwext4/ext4_balloc.c b/lwext4/ext4_balloc.c index 0c395be..73acf67 100644 --- a/lwext4/ext4_balloc.c +++ b/lwext4/ext4_balloc.c @@ -53,204 +53,210 @@ * @return Block group index */ static uint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s, - uint32_t baddr) + uint32_t baddr) { - if (ext4_get32(s, first_data_block)) - baddr--; + if (ext4_get32(s, first_data_block)) + baddr--; - return baddr / ext4_get32(s, blocks_per_group); + return baddr / ext4_get32(s, blocks_per_group); } uint32_t ext4_balloc_get_first_data_block_in_group(struct ext4_sblock *s, - struct ext4_block_group_ref *bg_ref) + struct ext4_block_group_ref *bg_ref) { - uint32_t block_group_count = ext4_block_group_cnt(s); - uint32_t inode_table_first_block = - ext4_bg_get_inode_table_first_block(bg_ref->block_group, s); - uint32_t block_size = ext4_sb_get_block_size(s); + uint32_t block_group_count = ext4_block_group_cnt(s); + uint32_t inode_table_first_block = + ext4_bg_get_inode_table_first_block(bg_ref->block_group, s); + uint32_t block_size = ext4_sb_get_block_size(s); - uint16_t inode_size = ext4_get16(s, inode_size); - uint32_t inodes_per_group = ext4_get32(s, inodes_per_group); + uint16_t inode_size = ext4_get16(s, inode_size); + uint32_t inodes_per_group = ext4_get32(s, inodes_per_group); - uint32_t inode_table_bytes; + uint32_t inode_table_bytes; - if (bg_ref->index < block_group_count - 1) { - inode_table_bytes = inodes_per_group * inode_size; - } else { - /* Last block group could be smaller */ - uint32_t inodes_count_total = ext4_get32(s, inodes_count); - inode_table_bytes = (inodes_count_total - - ((block_group_count - 1) * inodes_per_group)) * - inode_size; - } + if (bg_ref->index < block_group_count - 1) { + inode_table_bytes = inodes_per_group * inode_size; + } else { + /* Last block group could be smaller */ + uint32_t inodes_count_total = ext4_get32(s, inodes_count); + inode_table_bytes = + (inodes_count_total - + ((block_group_count - 1) * inodes_per_group)) * + inode_size; + } - uint32_t inode_table_blocks = inode_table_bytes / block_size; + uint32_t inode_table_blocks = inode_table_bytes / block_size; - if (inode_table_bytes % block_size) - inode_table_blocks++; + if (inode_table_bytes % block_size) + inode_table_blocks++; - return inode_table_first_block + inode_table_blocks; + return inode_table_first_block + inode_table_blocks; } int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, uint32_t baddr) { - struct ext4_fs *fs = inode_ref->fs; - struct ext4_sblock *sb = &fs->sb; - - uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr); - uint32_t index_in_group = ext4_fs_baddr2_index_in_group(sb, baddr); - - /* Load block group reference */ - struct ext4_block_group_ref bg_ref; - int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref); - if (rc != EOK) - return rc; - - /* Load block with bitmap */ - uint32_t bitmap_block_addr = - ext4_bg_get_block_bitmap(bg_ref.block_group, sb); - - struct ext4_block bitmap_block; - - rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - /* Modify bitmap */ - ext4_bmap_bit_clr(bitmap_block.data, index_in_group); - bitmap_block.dirty = true; - - /* Release block with bitmap */ - rc = ext4_block_set(fs->bdev, &bitmap_block); - if (rc != EOK) { - /* Error in saving bitmap */ - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - uint32_t block_size = ext4_sb_get_block_size(sb); - - /* Update superblock free blocks count */ - uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); - sb_free_blocks++; - ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); - - /* Update inode blocks count */ - uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); - ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE; - ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); - inode_ref->dirty = true; - - /* Update block group free blocks count */ - uint32_t free_blocks = - ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); - free_blocks++; - ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, free_blocks); - - bg_ref.dirty = true; - - /* Release block group reference */ - return ext4_fs_put_block_group_ref(&bg_ref); + struct ext4_fs *fs = inode_ref->fs; + struct ext4_sblock *sb = &fs->sb; + + uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr); + uint32_t index_in_group = ext4_fs_baddr2_index_in_group(sb, baddr); + + /* Load block group reference */ + struct ext4_block_group_ref bg_ref; + int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref); + if (rc != EOK) + return rc; + + /* Load block with bitmap */ + uint32_t bitmap_block_addr = + ext4_bg_get_block_bitmap(bg_ref.block_group, sb); + + struct ext4_block bitmap_block; + + rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + /* Modify bitmap */ + ext4_bmap_bit_clr(bitmap_block.data, index_in_group); + bitmap_block.dirty = true; + + /* Release block with bitmap */ + rc = ext4_block_set(fs->bdev, &bitmap_block); + if (rc != EOK) { + /* Error in saving bitmap */ + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + uint32_t block_size = ext4_sb_get_block_size(sb); + + /* Update superblock free blocks count */ + uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); + sb_free_blocks++; + ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); + + /* Update inode blocks count */ + uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); + ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE; + ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); + inode_ref->dirty = true; + + /* Update block group free blocks count */ + uint32_t free_blocks = + ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); + free_blocks++; + ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, free_blocks); + + bg_ref.dirty = true; + + /* Release block group reference */ + return ext4_fs_put_block_group_ref(&bg_ref); } int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first, - uint32_t count) + uint32_t count) { - int rc = EOK; - struct ext4_fs *fs = inode_ref->fs; - struct ext4_sblock *sb = &fs->sb; - - /* Compute indexes */ - uint32_t block_group_first = ext4_balloc_get_bgid_of_block(sb, first); - - /* Compute indexes */ - uint32_t block_group_last = - ext4_balloc_get_bgid_of_block(sb, first + count - 1); - - if (!ext4_sb_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { - /*It is not possible without flex_bg that blocks are continuous - * and and last block belongs to other bg.*/ - ext4_assert(block_group_first == - ext4_balloc_get_bgid_of_block(sb, first + count - 1)); - } - - /* Load block group reference */ - struct ext4_block_group_ref bg_ref; - while (block_group_first <= block_group_last) { - - rc = ext4_fs_get_block_group_ref(fs, block_group_first, &bg_ref); - if (rc != EOK) - return rc; - - uint32_t index_in_group_first = - ext4_fs_baddr2_index_in_group(sb, first); - - /* Load block with bitmap */ - uint32_t bitmap_block_addr = - ext4_bg_get_block_bitmap(bg_ref.block_group, sb); - - struct ext4_block bitmap_block; - - rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - uint32_t free_cnt = - ext4_sb_get_block_size(sb) * 8 - index_in_group_first; - - /*If last block, free only count blocks*/ - free_cnt = count > free_cnt ? free_cnt : count; - - /* Modify bitmap */ - ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, free_cnt); - bitmap_block.dirty = true; - - count -= free_cnt; - first += free_cnt; - - /* Release block with bitmap */ - rc = ext4_block_set(fs->bdev, &bitmap_block); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - uint32_t block_size = ext4_sb_get_block_size(sb); - - /* Update superblock free blocks count */ - uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); - sb_free_blocks += free_cnt; - ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); - - /* Update inode blocks count */ - uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); - ino_blocks -= free_cnt * (block_size / EXT4_INODE_BLOCK_SIZE); - ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); - inode_ref->dirty = true; - - /* Update block group free blocks count */ - uint32_t free_blocks = - ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); - free_blocks += free_cnt; - ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, free_blocks); - bg_ref.dirty = true; - - /* Release block group reference */ - rc = ext4_fs_put_block_group_ref(&bg_ref); - if (rc != EOK) - break; - - block_group_first++; - } - - /*All blocks should be released*/ - ext4_assert(count == 0); - return rc; + int rc = EOK; + struct ext4_fs *fs = inode_ref->fs; + struct ext4_sblock *sb = &fs->sb; + + /* Compute indexes */ + uint32_t block_group_first = ext4_balloc_get_bgid_of_block(sb, first); + + /* Compute indexes */ + uint32_t block_group_last = + ext4_balloc_get_bgid_of_block(sb, first + count - 1); + + if (!ext4_sb_has_feature_incompatible(sb, + EXT4_FEATURE_INCOMPAT_FLEX_BG)) { + /*It is not possible without flex_bg that blocks are continuous + * and and last block belongs to other bg.*/ + ext4_assert(block_group_first == ext4_balloc_get_bgid_of_block( + sb, first + count - 1)); + } + + /* Load block group reference */ + struct ext4_block_group_ref bg_ref; + while (block_group_first <= block_group_last) { + + rc = + ext4_fs_get_block_group_ref(fs, block_group_first, &bg_ref); + if (rc != EOK) + return rc; + + uint32_t index_in_group_first = + ext4_fs_baddr2_index_in_group(sb, first); + + /* Load block with bitmap */ + uint32_t bitmap_block_addr = + ext4_bg_get_block_bitmap(bg_ref.block_group, sb); + + struct ext4_block bitmap_block; + + rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + uint32_t free_cnt = + ext4_sb_get_block_size(sb) * 8 - index_in_group_first; + + /*If last block, free only count blocks*/ + free_cnt = count > free_cnt ? free_cnt : count; + + /* Modify bitmap */ + ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, + free_cnt); + bitmap_block.dirty = true; + + count -= free_cnt; + first += free_cnt; + + /* Release block with bitmap */ + rc = ext4_block_set(fs->bdev, &bitmap_block); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + uint32_t block_size = ext4_sb_get_block_size(sb); + + /* Update superblock free blocks count */ + uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); + sb_free_blocks += free_cnt; + ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); + + /* Update inode blocks count */ + uint64_t ino_blocks = + ext4_inode_get_blocks_count(sb, inode_ref->inode); + ino_blocks -= free_cnt * (block_size / EXT4_INODE_BLOCK_SIZE); + ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); + inode_ref->dirty = true; + + /* Update block group free blocks count */ + uint32_t free_blocks = + ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); + free_blocks += free_cnt; + ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, + free_blocks); + bg_ref.dirty = true; + + /* Release block group reference */ + rc = ext4_fs_put_block_group_ref(&bg_ref); + if (rc != EOK) + break; + + block_group_first++; + } + + /*All blocks should be released*/ + ext4_assert(count == 0); + return rc; } /**@brief Compute 'goal' for allocation algorithm. @@ -259,378 +265,385 @@ int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first, * @return error code */ static int ext4_balloc_find_goal(struct ext4_inode_ref *inode_ref, - uint32_t *goal) + uint32_t *goal) { - struct ext4_sblock *sb = &inode_ref->fs->sb; - *goal = 0; - - uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode); - uint32_t block_size = ext4_sb_get_block_size(sb); - uint32_t inode_block_count = inode_size / block_size; - - if (inode_size % block_size != 0) - inode_block_count++; - - /* If inode has some blocks, get last block address + 1 */ - if (inode_block_count > 0) { - int rc = ext4_fs_get_inode_data_block_index( - inode_ref, inode_block_count - 1, goal); - if (rc != EOK) - return rc; - - if (*goal != 0) { - (*goal)++; - return rc; - } - - /* If goal == 0, sparse file -> continue */ - } - - /* Identify block group of inode */ - - uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group); - uint32_t block_group = (inode_ref->index - 1) / inodes_per_group; - block_size = ext4_sb_get_block_size(sb); - - /* Load block group reference */ - struct ext4_block_group_ref bg_ref; - int rc = ext4_fs_get_block_group_ref(inode_ref->fs, block_group, &bg_ref); - if (rc != EOK) - return rc; - - /* Compute indexes */ - uint32_t block_group_count = ext4_block_group_cnt(sb); - uint32_t inode_table_first_block = - ext4_bg_get_inode_table_first_block(bg_ref.block_group, sb); - uint16_t inode_table_item_size = ext4_get16(sb, inode_size); - uint32_t inode_table_bytes; - - /* Check for last block group */ - if (block_group < block_group_count - 1) { - inode_table_bytes = inodes_per_group * inode_table_item_size; - } else { - /* Last block group could be smaller */ - uint32_t inodes_count_total = ext4_get32(sb, inodes_count); - - inode_table_bytes = (inodes_count_total - - ((block_group_count - 1) * inodes_per_group)) * - inode_table_item_size; - } - - uint32_t inode_table_blocks = inode_table_bytes / block_size; - - if (inode_table_bytes % block_size) - inode_table_blocks++; - - *goal = inode_table_first_block + inode_table_blocks; - - return ext4_fs_put_block_group_ref(&bg_ref); + struct ext4_sblock *sb = &inode_ref->fs->sb; + *goal = 0; + + uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode); + uint32_t block_size = ext4_sb_get_block_size(sb); + uint32_t inode_block_count = inode_size / block_size; + + if (inode_size % block_size != 0) + inode_block_count++; + + /* If inode has some blocks, get last block address + 1 */ + if (inode_block_count > 0) { + int rc = ext4_fs_get_inode_data_block_index( + inode_ref, inode_block_count - 1, goal); + if (rc != EOK) + return rc; + + if (*goal != 0) { + (*goal)++; + return rc; + } + + /* If goal == 0, sparse file -> continue */ + } + + /* Identify block group of inode */ + + uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group); + uint32_t block_group = (inode_ref->index - 1) / inodes_per_group; + block_size = ext4_sb_get_block_size(sb); + + /* Load block group reference */ + struct ext4_block_group_ref bg_ref; + int rc = + ext4_fs_get_block_group_ref(inode_ref->fs, block_group, &bg_ref); + if (rc != EOK) + return rc; + + /* Compute indexes */ + uint32_t block_group_count = ext4_block_group_cnt(sb); + uint32_t inode_table_first_block = + ext4_bg_get_inode_table_first_block(bg_ref.block_group, sb); + uint16_t inode_table_item_size = ext4_get16(sb, inode_size); + uint32_t inode_table_bytes; + + /* Check for last block group */ + if (block_group < block_group_count - 1) { + inode_table_bytes = inodes_per_group * inode_table_item_size; + } else { + /* Last block group could be smaller */ + uint32_t inodes_count_total = ext4_get32(sb, inodes_count); + + inode_table_bytes = + (inodes_count_total - + ((block_group_count - 1) * inodes_per_group)) * + inode_table_item_size; + } + + uint32_t inode_table_blocks = inode_table_bytes / block_size; + + if (inode_table_bytes % block_size) + inode_table_blocks++; + + *goal = inode_table_first_block + inode_table_blocks; + + return ext4_fs_put_block_group_ref(&bg_ref); } int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, uint32_t *fblock) { - uint32_t allocated_block = 0; - uint32_t bitmap_block_addr; - uint32_t rel_block_idx = 0; - uint32_t free_blocks; - uint32_t goal; - struct ext4_block bitmap_block; - - int rc = ext4_balloc_find_goal(inode_ref, &goal); - if (rc != EOK) { - /* no goal found => partition is full */ - return rc; - } - - struct ext4_sblock *sb = &inode_ref->fs->sb; - - /* Load block group number for goal and relative index */ - uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal); - uint32_t index_in_group = ext4_fs_baddr2_index_in_group(sb, goal); - - /* Load block group reference */ - struct ext4_block_group_ref bg_ref; - rc = ext4_fs_get_block_group_ref(inode_ref->fs, block_group, &bg_ref); - if (rc != EOK) - return rc; - - free_blocks = ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); - if (free_blocks == 0) { - /* This group has no free blocks */ - goto goal_failed; - } - - /* Compute indexes */ - uint32_t first_in_group = - ext4_balloc_get_first_data_block_in_group(sb, &bg_ref); - - uint32_t first_in_group_index = - ext4_fs_baddr2_index_in_group(sb, first_in_group); - - if (index_in_group < first_in_group_index) - index_in_group = first_in_group_index; - - /* Load block with bitmap */ - bitmap_block_addr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb); - - rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block, bitmap_block_addr); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - /* Check if goal is free */ - if (ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group)) { - ext4_bmap_bit_set(bitmap_block.data, index_in_group); - bitmap_block.dirty = true; - rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - allocated_block = - ext4_fs_index_in_group2_baddr(sb, index_in_group, block_group); - - goto success; - } - - uint32_t blocks_in_group = ext4_blocks_in_group_cnt(sb, block_group); - - uint32_t end_idx = (index_in_group + 63) & ~63; - if (end_idx > blocks_in_group) - end_idx = blocks_in_group; - - /* Try to find free block near to goal */ - uint32_t tmp_idx; - for (tmp_idx = index_in_group + 1; tmp_idx < end_idx; ++tmp_idx) { - if (ext4_bmap_is_bit_clr(bitmap_block.data, tmp_idx)) { - ext4_bmap_bit_set(bitmap_block.data, tmp_idx); - - bitmap_block.dirty = true; - rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); - if (rc != EOK) - return rc; - - allocated_block = - ext4_fs_index_in_group2_baddr(sb, tmp_idx, block_group); - - goto success; - } - } - - /* Find free bit in bitmap */ - rc = ext4_bmap_bit_find_clr(bitmap_block.data, index_in_group, - blocks_in_group, &rel_block_idx); - if (rc == EOK) { - ext4_bmap_bit_set(bitmap_block.data, rel_block_idx); - bitmap_block.dirty = true; - rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); - if (rc != EOK) - return rc; - - allocated_block = - ext4_fs_index_in_group2_baddr(sb, rel_block_idx, block_group); - - goto success; - } - - /* No free block found yet */ - rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } + uint32_t allocated_block = 0; + uint32_t bitmap_block_addr; + uint32_t rel_block_idx = 0; + uint32_t free_blocks; + uint32_t goal; + struct ext4_block bitmap_block; + + int rc = ext4_balloc_find_goal(inode_ref, &goal); + if (rc != EOK) { + /* no goal found => partition is full */ + return rc; + } + + struct ext4_sblock *sb = &inode_ref->fs->sb; + + /* Load block group number for goal and relative index */ + uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal); + uint32_t index_in_group = ext4_fs_baddr2_index_in_group(sb, goal); + + /* Load block group reference */ + struct ext4_block_group_ref bg_ref; + rc = ext4_fs_get_block_group_ref(inode_ref->fs, block_group, &bg_ref); + if (rc != EOK) + return rc; + + free_blocks = ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); + if (free_blocks == 0) { + /* This group has no free blocks */ + goto goal_failed; + } + + /* Compute indexes */ + uint32_t first_in_group = + ext4_balloc_get_first_data_block_in_group(sb, &bg_ref); + + uint32_t first_in_group_index = + ext4_fs_baddr2_index_in_group(sb, first_in_group); + + if (index_in_group < first_in_group_index) + index_in_group = first_in_group_index; + + /* Load block with bitmap */ + bitmap_block_addr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb); + + rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block, + bitmap_block_addr); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + /* Check if goal is free */ + if (ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group)) { + ext4_bmap_bit_set(bitmap_block.data, index_in_group); + bitmap_block.dirty = true; + rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + allocated_block = ext4_fs_index_in_group2_baddr( + sb, index_in_group, block_group); + + goto success; + } + + uint32_t blocks_in_group = ext4_blocks_in_group_cnt(sb, block_group); + + uint32_t end_idx = (index_in_group + 63) & ~63; + if (end_idx > blocks_in_group) + end_idx = blocks_in_group; + + /* Try to find free block near to goal */ + uint32_t tmp_idx; + for (tmp_idx = index_in_group + 1; tmp_idx < end_idx; ++tmp_idx) { + if (ext4_bmap_is_bit_clr(bitmap_block.data, tmp_idx)) { + ext4_bmap_bit_set(bitmap_block.data, tmp_idx); + + bitmap_block.dirty = true; + rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); + if (rc != EOK) + return rc; + + allocated_block = ext4_fs_index_in_group2_baddr( + sb, tmp_idx, block_group); + + goto success; + } + } + + /* Find free bit in bitmap */ + rc = ext4_bmap_bit_find_clr(bitmap_block.data, index_in_group, + blocks_in_group, &rel_block_idx); + if (rc == EOK) { + ext4_bmap_bit_set(bitmap_block.data, rel_block_idx); + bitmap_block.dirty = true; + rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); + if (rc != EOK) + return rc; + + allocated_block = ext4_fs_index_in_group2_baddr( + sb, rel_block_idx, block_group); + + goto success; + } + + /* No free block found yet */ + rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } goal_failed: - rc = ext4_fs_put_block_group_ref(&bg_ref); - if (rc != EOK) - return rc; + rc = ext4_fs_put_block_group_ref(&bg_ref); + if (rc != EOK) + return rc; - /* Try other block groups */ - uint32_t block_group_count = ext4_block_group_cnt(sb); + /* Try other block groups */ + uint32_t block_group_count = ext4_block_group_cnt(sb); - uint32_t bgid = (block_group + 1) % block_group_count; - uint32_t count = block_group_count; + uint32_t bgid = (block_group + 1) % block_group_count; + uint32_t count = block_group_count; - while (count > 0) { - rc = ext4_fs_get_block_group_ref(inode_ref->fs, bgid, &bg_ref); - if (rc != EOK) - return rc; + while (count > 0) { + rc = ext4_fs_get_block_group_ref(inode_ref->fs, bgid, &bg_ref); + if (rc != EOK) + return rc; - free_blocks = ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); - if (free_blocks == 0) { - /* This group has no free blocks */ - goto next_group; - } + free_blocks = + ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); + if (free_blocks == 0) { + /* This group has no free blocks */ + goto next_group; + } - /* Load block with bitmap */ - bitmap_block_addr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb); + /* Load block with bitmap */ + bitmap_block_addr = + ext4_bg_get_block_bitmap(bg_ref.block_group, sb); - rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block, - bitmap_block_addr); + rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block, + bitmap_block_addr); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } - /* Compute indexes */ - first_in_group = ext4_balloc_get_first_data_block_in_group(sb, &bg_ref); - index_in_group = ext4_fs_baddr2_index_in_group(sb, first_in_group); - blocks_in_group = ext4_blocks_in_group_cnt(sb, bgid); + /* Compute indexes */ + first_in_group = + ext4_balloc_get_first_data_block_in_group(sb, &bg_ref); + index_in_group = + ext4_fs_baddr2_index_in_group(sb, first_in_group); + blocks_in_group = ext4_blocks_in_group_cnt(sb, bgid); - first_in_group_index = - ext4_fs_baddr2_index_in_group(sb, first_in_group); + first_in_group_index = + ext4_fs_baddr2_index_in_group(sb, first_in_group); - if (index_in_group < first_in_group_index) - index_in_group = first_in_group_index; + if (index_in_group < first_in_group_index) + index_in_group = first_in_group_index; - rc = ext4_bmap_bit_find_clr(bitmap_block.data, index_in_group, - blocks_in_group, &rel_block_idx); + rc = ext4_bmap_bit_find_clr(bitmap_block.data, index_in_group, + blocks_in_group, &rel_block_idx); - if (rc == EOK) { + if (rc == EOK) { - ext4_bmap_bit_set(bitmap_block.data, rel_block_idx); + ext4_bmap_bit_set(bitmap_block.data, rel_block_idx); - bitmap_block.dirty = true; - rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } + bitmap_block.dirty = true; + rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } - allocated_block = - ext4_fs_index_in_group2_baddr(sb, rel_block_idx, bgid); + allocated_block = ext4_fs_index_in_group2_baddr( + sb, rel_block_idx, bgid); - goto success; - } + goto success; + } - rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } + rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } - next_group: - rc = ext4_fs_put_block_group_ref(&bg_ref); - if (rc != EOK) { - return rc; - } + next_group: + rc = ext4_fs_put_block_group_ref(&bg_ref); + if (rc != EOK) { + return rc; + } - /* Goto next group */ - bgid = (bgid + 1) % block_group_count; - count--; - } + /* Goto next group */ + bgid = (bgid + 1) % block_group_count; + count--; + } - return ENOSPC; + return ENOSPC; success: /* Empty command - because of syntax */ ; - uint32_t block_size = ext4_sb_get_block_size(sb); + uint32_t block_size = ext4_sb_get_block_size(sb); - /* Update superblock free blocks count */ - uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); - sb_free_blocks--; - ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); + /* Update superblock free blocks count */ + uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); + sb_free_blocks--; + ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); - /* Update inode blocks (different block size!) count */ - uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); - ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE; - ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); - inode_ref->dirty = true; + /* Update inode blocks (different block size!) count */ + uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); + ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE; + ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); + inode_ref->dirty = true; - /* Update block group free blocks count */ - uint32_t bg_free_blocks = - ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); - bg_free_blocks--; - ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, bg_free_blocks); + /* Update block group free blocks count */ + uint32_t bg_free_blocks = + ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); + bg_free_blocks--; + ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, bg_free_blocks); - bg_ref.dirty = true; + bg_ref.dirty = true; - rc = ext4_fs_put_block_group_ref(&bg_ref); + rc = ext4_fs_put_block_group_ref(&bg_ref); - *fblock = allocated_block; - return rc; + *fblock = allocated_block; + return rc; } int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref, - uint32_t baddr, bool *free) + uint32_t baddr, bool *free) { - int rc; - - struct ext4_fs *fs = inode_ref->fs; - struct ext4_sblock *sb = &fs->sb; - - /* Compute indexes */ - uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr); - uint32_t index_in_group = ext4_fs_baddr2_index_in_group(sb, baddr); - - /* Load block group reference */ - struct ext4_block_group_ref bg_ref; - rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref); - if (rc != EOK) - return rc; - - /* Load block with bitmap */ - uint32_t bitmap_block_addr = - ext4_bg_get_block_bitmap(bg_ref.block_group, sb); - - struct ext4_block bitmap_block; - - rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr); - if (rc != EOK) { - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - /* Check if block is free */ - *free = ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group); - - /* Allocate block if possible */ - if (*free) { - ext4_bmap_bit_set(bitmap_block.data, index_in_group); - bitmap_block.dirty = true; - } - - /* Release block with bitmap */ - rc = ext4_block_set(fs->bdev, &bitmap_block); - if (rc != EOK) { - /* Error in saving bitmap */ - ext4_fs_put_block_group_ref(&bg_ref); - return rc; - } - - /* If block is not free, return */ - if (!(*free)) - goto terminate; - - uint32_t block_size = ext4_sb_get_block_size(sb); - - /* Update superblock free blocks count */ - uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); - sb_free_blocks--; - ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); - - /* Update inode blocks count */ - uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); - ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE; - ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); - inode_ref->dirty = true; - - /* Update block group free blocks count */ - uint32_t free_blocks = - ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); - free_blocks--; - ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, free_blocks); - - bg_ref.dirty = true; + int rc; + + struct ext4_fs *fs = inode_ref->fs; + struct ext4_sblock *sb = &fs->sb; + + /* Compute indexes */ + uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr); + uint32_t index_in_group = ext4_fs_baddr2_index_in_group(sb, baddr); + + /* Load block group reference */ + struct ext4_block_group_ref bg_ref; + rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref); + if (rc != EOK) + return rc; + + /* Load block with bitmap */ + uint32_t bitmap_block_addr = + ext4_bg_get_block_bitmap(bg_ref.block_group, sb); + + struct ext4_block bitmap_block; + + rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr); + if (rc != EOK) { + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + /* Check if block is free */ + *free = ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group); + + /* Allocate block if possible */ + if (*free) { + ext4_bmap_bit_set(bitmap_block.data, index_in_group); + bitmap_block.dirty = true; + } + + /* Release block with bitmap */ + rc = ext4_block_set(fs->bdev, &bitmap_block); + if (rc != EOK) { + /* Error in saving bitmap */ + ext4_fs_put_block_group_ref(&bg_ref); + return rc; + } + + /* If block is not free, return */ + if (!(*free)) + goto terminate; + + uint32_t block_size = ext4_sb_get_block_size(sb); + + /* Update superblock free blocks count */ + uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb); + sb_free_blocks--; + ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks); + + /* Update inode blocks count */ + uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode); + ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE; + ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks); + inode_ref->dirty = true; + + /* Update block group free blocks count */ + uint32_t free_blocks = + ext4_bg_get_free_blocks_count(bg_ref.block_group, sb); + free_blocks--; + ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, free_blocks); + + bg_ref.dirty = true; terminate: - return ext4_fs_put_block_group_ref(&bg_ref); + return ext4_fs_put_block_group_ref(&bg_ref); } /** diff --git a/lwext4/ext4_balloc.h b/lwext4/ext4_balloc.h index 24cf470..06ad897 100644 --- a/lwext4/ext4_balloc.h +++ b/lwext4/ext4_balloc.h @@ -54,7 +54,7 @@ * @return block id of the first datablock in block group*/ uint32_t ext4_balloc_get_first_data_block_in_group(struct ext4_sblock *s, - struct ext4_block_group_ref *bg_ref); + struct ext4_block_group_ref *bg_ref); /**@brief Free block from inode. * @param inode_ref inode reference @@ -67,7 +67,7 @@ int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, uint32_t baddr); * @param baddr block address * @return standard error code*/ int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first, - uint32_t count); + uint32_t count); /**@brief Allocate block procedure. * @param inode_ref inode reference @@ -81,7 +81,7 @@ int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, uint32_t *baddr); * @param free if baddr is not allocated * @return standard error code*/ int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref, - uint32_t baddr, bool *free); + uint32_t baddr, bool *free); #endif /* EXT4_BALLOC_H_ */ diff --git a/lwext4/ext4_bcache.c b/lwext4/ext4_bcache.c index f9fd3b4..4ae1cdc 100644 --- a/lwext4/ext4_bcache.c +++ b/lwext4/ext4_bcache.c @@ -43,169 +43,169 @@ #include <stdlib.h>
int ext4_bcache_init_dynamic(struct ext4_bcache *bc, uint32_t cnt,
- uint32_t itemsize)
+ uint32_t itemsize)
{
- ext4_assert(bc && cnt && itemsize);
+ ext4_assert(bc && cnt && itemsize);
- memset(bc, 0, sizeof(struct ext4_bcache));
+ memset(bc, 0, sizeof(struct ext4_bcache));
- bc->data = malloc(cnt * itemsize);
- if (!bc->data)
- goto error;
+ bc->data = malloc(cnt * itemsize);
+ if (!bc->data)
+ goto error;
- bc->cnt = cnt;
- bc->itemsize = itemsize;
- bc->ref_blocks = 0;
- bc->max_ref_blocks = 0;
+ bc->cnt = cnt;
+ bc->itemsize = itemsize;
+ bc->ref_blocks = 0;
+ bc->max_ref_blocks = 0;
- return EOK;
+ return EOK;
error:
- if (bc->data)
- free(bc->data);
+ if (bc->data)
+ free(bc->data);
- memset(bc, 0, sizeof(struct ext4_bcache));
+ memset(bc, 0, sizeof(struct ext4_bcache));
- return ENOMEM;
+ return ENOMEM;
}
int ext4_bcache_fini_dynamic(struct ext4_bcache *bc)
{
- if (bc->data)
- free(bc->data);
+ if (bc->data)
+ free(bc->data);
- memset(bc, 0, sizeof(struct ext4_bcache));
+ memset(bc, 0, sizeof(struct ext4_bcache));
- return EOK;
+ return EOK;
}
int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,
- bool *is_new)
+ bool *is_new)
{
- uint32_t i;
- ext4_assert(bc && b && is_new);
+ uint32_t i;
+ ext4_assert(bc && b && is_new);
- /*Check if valid.*/
- ext4_assert(b->lb_id);
- if (!b->lb_id) {
- ext4_assert(b->lb_id);
- }
+ /*Check if valid.*/
+ ext4_assert(b->lb_id);
+ if (!b->lb_id) {
+ ext4_assert(b->lb_id);
+ }
- uint32_t cache_id = bc->cnt;
- uint32_t alloc_id = 0;
+ uint32_t cache_id = bc->cnt;
+ uint32_t alloc_id = 0;
- *is_new = false;
+ *is_new = false;
- /*Find in free blocks (Last Recently Used).*/
- for (i = 0; i < bc->cnt; ++i) {
+ /*Find in free blocks (Last Recently Used).*/
+ for (i = 0; i < bc->cnt; ++i) {
- /*Check if block is already in cache*/
- if (b->lb_id == bc->lba[i]) {
+ /*Check if block is already in cache*/
+ if (b->lb_id == bc->lba[i]) {
- if (!bc->refctr[i] && !bc->free_delay[i])
- bc->ref_blocks++;
+ if (!bc->refctr[i] && !bc->free_delay[i])
+ bc->ref_blocks++;
- /*Update reference counter*/
- bc->refctr[i]++;
+ /*Update reference counter*/
+ bc->refctr[i]++;
- /*Update usage marker*/
- bc->lru_id[i] = ++bc->lru_ctr;
+ /*Update usage marker*/
+ bc->lru_id[i] = ++bc->lru_ctr;
- /*Set valid cache data and id*/
- b->data = bc->data + i * bc->itemsize;
- b->cache_id = i;
+ /*Set valid cache data and id*/
+ b->data = bc->data + i * bc->itemsize;
+ b->cache_id = i;
- return EOK;
- }
+ return EOK;
+ }
- /*Best fit calculations.*/
- if (bc->refctr[i])
- continue;
+ /*Best fit calculations.*/
+ if (bc->refctr[i])
+ continue;
- if (bc->free_delay[i])
- continue;
+ if (bc->free_delay[i])
+ continue;
- /*Block is unreferenced, but it may exist block with
- * lower usage marker*/
+ /*Block is unreferenced, but it may exist block with
+ * lower usage marker*/
- /*First find.*/
- if (cache_id == bc->cnt) {
- cache_id = i;
- alloc_id = bc->lru_id[i];
- continue;
- }
+ /*First find.*/
+ if (cache_id == bc->cnt) {
+ cache_id = i;
+ alloc_id = bc->lru_id[i];
+ continue;
+ }
- /*Next find*/
- if (alloc_id <= bc->lru_id[i])
- continue;
+ /*Next find*/
+ if (alloc_id <= bc->lru_id[i])
+ continue;
- /*This block has lower alloc id marker*/
- cache_id = i;
- alloc_id = bc->lru_id[i];
- }
+ /*This block has lower alloc id marker*/
+ cache_id = i;
+ alloc_id = bc->lru_id[i];
+ }
- if (cache_id != bc->cnt) {
- /*There was unreferenced block*/
- bc->lba[cache_id] = b->lb_id;
- bc->refctr[cache_id] = 1;
- bc->lru_id[cache_id] = ++bc->lru_ctr;
+ if (cache_id != bc->cnt) {
+ /*There was unreferenced block*/
+ bc->lba[cache_id] = b->lb_id;
+ bc->refctr[cache_id] = 1;
+ bc->lru_id[cache_id] = ++bc->lru_ctr;
- /*Set valid cache data and id*/
- b->data = bc->data + cache_id * bc->itemsize;
- b->cache_id = cache_id;
+ /*Set valid cache data and id*/
+ b->data = bc->data + cache_id * bc->itemsize;
+ b->cache_id = cache_id;
- /*Statistics*/
- bc->ref_blocks++;
- if (bc->ref_blocks > bc->max_ref_blocks)
- bc->max_ref_blocks = bc->ref_blocks;
+ /*Statistics*/
+ bc->ref_blocks++;
+ if (bc->ref_blocks > bc->max_ref_blocks)
+ bc->max_ref_blocks = bc->ref_blocks;
- /*Block needs to be read.*/
- *is_new = true;
+ /*Block needs to be read.*/
+ *is_new = true;
- return EOK;
- }
+ return EOK;
+ }
- ext4_dprintf(EXT4_DEBUG_BCACHE,
- "ext4_bcache_alloc: FAIL, unable to alloc block cache!\n");
- return ENOMEM;
+ ext4_dprintf(EXT4_DEBUG_BCACHE,
+ "ext4_bcache_alloc: FAIL, unable to alloc block cache!\n");
+ return ENOMEM;
}
int ext4_bcache_free(struct ext4_bcache *bc, struct ext4_block *b,
- uint8_t free_delay)
+ uint8_t free_delay)
{
- ext4_assert(bc && b);
+ ext4_assert(bc && b);
- /*Check if valid.*/
- ext4_assert(b->lb_id);
+ /*Check if valid.*/
+ ext4_assert(b->lb_id);
- /*Block should be in cache.*/
- ext4_assert(b->cache_id < bc->cnt);
+ /*Block should be in cache.*/
+ ext4_assert(b->cache_id < bc->cnt);
- /*Check if someone don't try free unreferenced block cache.*/
- ext4_assert(bc->refctr[b->cache_id]);
+ /*Check if someone don't try free unreferenced block cache.*/
+ ext4_assert(bc->refctr[b->cache_id]);
- /*Just decrease reference counter*/
- if (bc->refctr[b->cache_id])
- bc->refctr[b->cache_id]--;
+ /*Just decrease reference counter*/
+ if (bc->refctr[b->cache_id])
+ bc->refctr[b->cache_id]--;
- if (free_delay)
- bc->free_delay[b->cache_id] = free_delay;
+ if (free_delay)
+ bc->free_delay[b->cache_id] = free_delay;
- /*Update statistics*/
- if (!bc->refctr[b->cache_id] && !bc->free_delay[b->cache_id])
- bc->ref_blocks--;
+ /*Update statistics*/
+ if (!bc->refctr[b->cache_id] && !bc->free_delay[b->cache_id])
+ bc->ref_blocks--;
- b->lb_id = 0;
- b->data = 0;
- b->cache_id = 0;
+ b->lb_id = 0;
+ b->data = 0;
+ b->cache_id = 0;
- return EOK;
+ return EOK;
}
bool ext4_bcache_is_full(struct ext4_bcache *bc)
{
- return (bc->cnt == bc->ref_blocks);
+ return (bc->cnt == bc->ref_blocks);
}
/**
diff --git a/lwext4/ext4_bcache.h b/lwext4/ext4_bcache.h index b2573c5..5a3fdbe 100644 --- a/lwext4/ext4_bcache.h +++ b/lwext4/ext4_bcache.h @@ -44,65 +44,65 @@ /**@brief Single block descriptor*/
struct ext4_block {
- /**@brief Dirty flag*/
- bool dirty;
+ /**@brief Dirty flag*/
+ bool dirty;
- /**@brief Logical block ID*/
- uint64_t lb_id;
+ /**@brief Logical block ID*/
+ uint64_t lb_id;
- /**@brief Cache id*/
- uint32_t cache_id;
+ /**@brief Cache id*/
+ uint32_t cache_id;
- /**@brief Data buffer.*/
- uint8_t *data;
+ /**@brief Data buffer.*/
+ uint8_t *data;
};
/**@brief Block cache descriptor*/
struct ext4_bcache {
- /**@brief Item count in block cache*/
- uint32_t cnt;
+ /**@brief Item count in block cache*/
+ uint32_t cnt;
- /**@brief Item size in block cache*/
- uint32_t itemsize;
+ /**@brief Item size in block cache*/
+ uint32_t itemsize;
- /**@brief Last recently used counter*/
- uint32_t lru_ctr;
+ /**@brief Last recently used counter*/
+ uint32_t lru_ctr;
- /**@brief Reference count table*/
- uint32_t refctr[CONFIG_BLOCK_DEV_CACHE_SIZE];
+ /**@brief Reference count table*/
+ uint32_t refctr[CONFIG_BLOCK_DEV_CACHE_SIZE];
- /**@brief Last recently used ID table*/
- uint32_t lru_id[CONFIG_BLOCK_DEV_CACHE_SIZE];
+ /**@brief Last recently used ID table*/
+ uint32_t lru_id[CONFIG_BLOCK_DEV_CACHE_SIZE];
- /**@brief Writeback free delay mode table*/
- uint8_t free_delay[CONFIG_BLOCK_DEV_CACHE_SIZE];
+ /**@brief Writeback free delay mode table*/
+ uint8_t free_delay[CONFIG_BLOCK_DEV_CACHE_SIZE];
- /**@brief Logical block table*/
- uint64_t lba[CONFIG_BLOCK_DEV_CACHE_SIZE];
+ /**@brief Logical block table*/
+ uint64_t lba[CONFIG_BLOCK_DEV_CACHE_SIZE];
- /**@brief Dirty mark*/
- bool dirty[CONFIG_BLOCK_DEV_CACHE_SIZE];
+ /**@brief Dirty mark*/
+ bool dirty[CONFIG_BLOCK_DEV_CACHE_SIZE];
- /**@brief Cache data buffers*/
- uint8_t *data;
+ /**@brief Cache data buffers*/
+ uint8_t *data;
- /**@brief Currently referenced datablocks*/
- uint32_t ref_blocks;
+ /**@brief Currently referenced datablocks*/
+ uint32_t ref_blocks;
- /**@brief Maximum referenced datablocks*/
- uint32_t max_ref_blocks;
+ /**@brief Maximum referenced datablocks*/
+ uint32_t max_ref_blocks;
};
/**@brief Static initializer of block cache structure.*/
#define EXT4_BCACHE_STATIC_INSTANCE(__name, __cnt, __itemsize) \
- static uint8_t __name##_data[(__cnt) * (__itemsize)]; \
- static struct ext4_bcache __name = { \
- .cnt = __cnt, \
- .itemsize = __itemsize, \
- .lru_ctr = 0, \
- .data = __name##_data, \
- }
+ static uint8_t __name##_data[(__cnt) * (__itemsize)]; \
+ static struct ext4_bcache __name = { \
+ .cnt = __cnt, \
+ .itemsize = __itemsize, \
+ .lru_ctr = 0, \
+ .data = __name##_data, \
+ }
/**@brief Dynamic initialization of block cache.
* @param bc block cache descriptor
@@ -110,7 +110,7 @@ struct ext4_bcache { * @param itemsize single item size (in bytes)
* @return standard error code*/
int ext4_bcache_init_dynamic(struct ext4_bcache *bc, uint32_t cnt,
- uint32_t itemsize);
+ uint32_t itemsize);
/**@brief Dynamic de-initialization of block cache.
* @param bc block cache descriptor
@@ -125,7 +125,7 @@ int ext4_bcache_fini_dynamic(struct ext4_bcache *bc); * @param is_new block is new (needs to be read)
* @return standard error code*/
int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,
- bool *is_new);
+ bool *is_new);
/**@brief Free block from cache memory (decrement reference counter).
* @param bc block cache descriptor
@@ -133,7 +133,7 @@ int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b, * @param cache writeback mode
* @return standard error code*/
int ext4_bcache_free(struct ext4_bcache *bc, struct ext4_block *b,
- uint8_t free_delay);
+ uint8_t free_delay);
/**@brief Return a full status of block cache.
* @param bc block cache descriptor
diff --git a/lwext4/ext4_bitmap.c b/lwext4/ext4_bitmap.c index 7817967..1320033 100644 --- a/lwext4/ext4_bitmap.c +++ b/lwext4/ext4_bitmap.c @@ -41,114 +41,114 @@ void ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt) { - uint32_t i = sbit; - - while (i & 7) { - - if (!bcnt) - return; - - ext4_bmap_bit_clr(bmap, i); - - bcnt--; - i++; - } - sbit = i; - bmap += (sbit >> 3); - - while (bcnt >= 32) { - *(uint32_t *)bmap = 0; - bmap += 4; - bcnt -= 32; - sbit += 32; - } - - while (bcnt >= 16) { - *(uint16_t *)bmap = 0; - bmap += 2; - bcnt -= 16; - sbit += 16; - } - - while (bcnt >= 8) { - *bmap = 0; - bmap += 1; - bcnt -= 8; - sbit += 8; - } - - for (i = 0; i < bcnt; ++i) { - ext4_bmap_bit_clr(bmap, i); - } + uint32_t i = sbit; + + while (i & 7) { + + if (!bcnt) + return; + + ext4_bmap_bit_clr(bmap, i); + + bcnt--; + i++; + } + sbit = i; + bmap += (sbit >> 3); + + while (bcnt >= 32) { + *(uint32_t *)bmap = 0; + bmap += 4; + bcnt -= 32; + sbit += 32; + } + + while (bcnt >= 16) { + *(uint16_t *)bmap = 0; + bmap += 2; + bcnt -= 16; + sbit += 16; + } + + while (bcnt >= 8) { + *bmap = 0; + bmap += 1; + bcnt -= 8; + sbit += 8; + } + + for (i = 0; i < bcnt; ++i) { + ext4_bmap_bit_clr(bmap, i); + } } int ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit, - uint32_t *bit_id) + uint32_t *bit_id) { - uint32_t i; - uint32_t bcnt = ebit - sbit; + uint32_t i; + uint32_t bcnt = ebit - sbit; - i = sbit; + i = sbit; - while (i & 7) { + while (i & 7) { - if (!bcnt) - return ENOSPC; + if (!bcnt) + return ENOSPC; - if (ext4_bmap_is_bit_clr(bmap, i)) { - *bit_id = sbit; - return EOK; - } + if (ext4_bmap_is_bit_clr(bmap, i)) { + *bit_id = sbit; + return EOK; + } - i++; - bcnt--; - } + i++; + bcnt--; + } - sbit = i; - bmap += (sbit >> 3); + sbit = i; + bmap += (sbit >> 3); - while (bcnt >= 32) { - if (*(uint32_t *)bmap != 0xFFFFFFFF) - goto finish_it; + while (bcnt >= 32) { + if (*(uint32_t *)bmap != 0xFFFFFFFF) + goto finish_it; - bmap += 4; - bcnt -= 32; - sbit += 32; - } + bmap += 4; + bcnt -= 32; + sbit += 32; + } - while (bcnt >= 16) { - if (*(uint16_t *)bmap != 0xFFFF) - goto finish_it; + while (bcnt >= 16) { + if (*(uint16_t *)bmap != 0xFFFF) + goto finish_it; - bmap += 2; - bcnt -= 16; - sbit += 16; - } + bmap += 2; + bcnt -= 16; + sbit += 16; + } finish_it: - while (bcnt >= 8) { - if (*bmap != 0xFF) { - for (i = 0; i < 8; ++i) { - if (ext4_bmap_is_bit_clr(bmap, i)) { - *bit_id = sbit + i; - return EOK; - } - } - } - - bmap += 1; - bcnt -= 8; - sbit += 8; - } - - for (i = 0; i < bcnt; ++i) { - if (ext4_bmap_is_bit_clr(bmap, i)) { - *bit_id = sbit + i; - return EOK; - } - } - - return ENOSPC; + while (bcnt >= 8) { + if (*bmap != 0xFF) { + for (i = 0; i < 8; ++i) { + if (ext4_bmap_is_bit_clr(bmap, i)) { + *bit_id = sbit + i; + return EOK; + } + } + } + + bmap += 1; + bcnt -= 8; + sbit += 8; + } + + for (i = 0; i < bcnt; ++i) { + if (ext4_bmap_is_bit_clr(bmap, i)) { + *bit_id = sbit + i; + return EOK; + } + } + + return ENOSPC; } /** diff --git a/lwext4/ext4_bitmap.h b/lwext4/ext4_bitmap.h index 63df14d..1299b70 100644 --- a/lwext4/ext4_bitmap.h +++ b/lwext4/ext4_bitmap.h @@ -47,7 +47,7 @@ * @param bit bit to set*/ static inline void ext4_bmap_bit_set(uint8_t *bmap, uint32_t bit) { - *(bmap + (bit >> 3)) |= (1 << (bit & 7)); + *(bmap + (bit >> 3)) |= (1 << (bit & 7)); } /**@brief Clear bitmap bit. @@ -55,7 +55,7 @@ static inline void ext4_bmap_bit_set(uint8_t *bmap, uint32_t bit) * @param bit bit to clear*/ static inline void ext4_bmap_bit_clr(uint8_t *bmap, uint32_t bit) { - *(bmap + (bit >> 3)) &= ~(1 << (bit & 7)); + *(bmap + (bit >> 3)) &= ~(1 << (bit & 7)); } /**@brief Check if the bitmap bit is set. @@ -63,7 +63,7 @@ static inline void ext4_bmap_bit_clr(uint8_t *bmap, uint32_t bit) * @param bit bit to check*/ static inline bool ext4_bmap_is_bit_set(uint8_t *bmap, uint32_t bit) { - return (*(bmap + (bit >> 3)) & (1 << (bit & 7))); + return (*(bmap + (bit >> 3)) & (1 << (bit & 7))); } /**@brief Check if the bitmap bit is clear. @@ -71,7 +71,7 @@ static inline bool ext4_bmap_is_bit_set(uint8_t *bmap, uint32_t bit) * @param bit bit to check*/ static inline bool ext4_bmap_is_bit_clr(uint8_t *bmap, uint32_t bit) { - return !ext4_bmap_is_bit_set(bmap, bit); + return !ext4_bmap_is_bit_set(bmap, bit); } /**@brief Free range of bits in bitmap. @@ -86,7 +86,7 @@ void ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt); * @param bit_id output parameter (first free bit) * @return standard error code*/ int ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit, - uint32_t *bit_id); + uint32_t *bit_id); #endif /* EXT4_BITMAP_H_ */ diff --git a/lwext4/ext4_block_group.c b/lwext4/ext4_block_group.c index 37fcb59..7f068b9 100644 --- a/lwext4/ext4_block_group.c +++ b/lwext4/ext4_block_group.c @@ -76,11 +76,12 @@ static uint16_t const crc16_tab[256] = { uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len) { - while (len--) + while (len--) - crc = (((crc >> 8) & 0xffU) ^ crc16_tab[(crc ^ *buffer++) & 0xffU]) & - 0x0000ffffU; - return crc; + crc = (((crc >> 8) & 0xffU) ^ + crc16_tab[(crc ^ *buffer++) & 0xffU]) & + 0x0000ffffU; + return crc; } /** diff --git a/lwext4/ext4_block_group.h b/lwext4/ext4_block_group.h index 9233333..7d91ad5 100644 --- a/lwext4/ext4_block_group.h +++ b/lwext4/ext4_block_group.h @@ -55,14 +55,14 @@ * @return Address of block with block bitmap */ static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint64_t v = to_le32(bg->block_bitmap_lo); + uint64_t v = to_le32(bg->block_bitmap_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint64_t)to_le32(bg->block_bitmap_hi) << 32; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint64_t)to_le32(bg->block_bitmap_hi) << 32; - return v; + return v; } /**@brief Get address of block with i-node bitmap. @@ -71,15 +71,15 @@ static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg, * @return Address of block with i-node bitmap */ static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint64_t v = to_le32(bg->inode_bitmap_lo); + uint64_t v = to_le32(bg->inode_bitmap_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint64_t)to_le32(bg->inode_bitmap_hi) << 32; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint64_t)to_le32(bg->inode_bitmap_hi) << 32; - return v; + return v; } /**@brief Get address of the first block of the i-node table. @@ -89,14 +89,14 @@ static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg, */ static inline uint64_t ext4_bg_get_inode_table_first_block(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint64_t v = to_le32(bg->inode_table_first_block_lo); + uint64_t v = to_le32(bg->inode_table_first_block_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint64_t)to_le32(bg->inode_table_first_block_hi) << 32; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint64_t)to_le32(bg->inode_table_first_block_hi) << 32; - return v; + return v; } /**@brief Get number of free blocks in block group. @@ -105,14 +105,14 @@ ext4_bg_get_inode_table_first_block(struct ext4_bgroup *bg, * @return Number of free blocks in block group */ static inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint32_t v = to_le16(bg->free_blocks_count_lo); + uint32_t v = to_le16(bg->free_blocks_count_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint32_t)to_le16(bg->free_blocks_count_hi) << 16; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint32_t)to_le16(bg->free_blocks_count_hi) << 16; - return v; + return v; } /**@brief Set number of free blocks in block group. @@ -121,12 +121,12 @@ static inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg, * @param cnt Number of free blocks in block group */ static inline void ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg, - struct ext4_sblock *s, - uint32_t cnt) + struct ext4_sblock *s, + uint32_t cnt) { - bg->free_blocks_count_lo = to_le16((cnt << 16) >> 16); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - bg->free_blocks_count_hi = to_le16(cnt >> 16); + bg->free_blocks_count_lo = to_le16((cnt << 16) >> 16); + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + bg->free_blocks_count_hi = to_le16(cnt >> 16); } /**@brief Get number of free i-nodes in block group. @@ -135,14 +135,14 @@ static inline void ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg, * @return Number of free i-nodes in block group */ static inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint32_t v = to_le16(bg->free_inodes_count_lo); + uint32_t v = to_le16(bg->free_inodes_count_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint32_t)to_le16(bg->free_inodes_count_hi) << 16; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint32_t)to_le16(bg->free_inodes_count_hi) << 16; - return v; + return v; } /**@brief Set number of free i-nodes in block group. @@ -151,12 +151,12 @@ static inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg, * @param cnt Number of free i-nodes in block group */ static inline void ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg, - struct ext4_sblock *s, - uint32_t cnt) + struct ext4_sblock *s, + uint32_t cnt) { - bg->free_inodes_count_lo = to_le16((cnt << 16) >> 16); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - bg->free_inodes_count_hi = to_le16(cnt >> 16); + bg->free_inodes_count_lo = to_le16((cnt << 16) >> 16); + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + bg->free_inodes_count_hi = to_le16(cnt >> 16); } /**@brief Get number of used directories in block group. @@ -165,14 +165,14 @@ static inline void ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg, * @return Number of used directories in block group */ static inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint32_t v = to_le16(bg->used_dirs_count_lo); + uint32_t v = to_le16(bg->used_dirs_count_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint32_t)to_le16(bg->used_dirs_count_hi) << 16; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint32_t)to_le16(bg->used_dirs_count_hi) << 16; - return v; + return v; } /**@brief Set number of used directories in block group. @@ -181,12 +181,12 @@ static inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg, * @param cnt Number of used directories in block group */ static inline void ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg, - struct ext4_sblock *s, - uint32_t cnt) + struct ext4_sblock *s, + uint32_t cnt) { - bg->used_dirs_count_lo = to_le16((cnt << 16) >> 16); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - bg->used_dirs_count_hi = to_le16(cnt >> 16); + bg->used_dirs_count_lo = to_le16((cnt << 16) >> 16); + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + bg->used_dirs_count_hi = to_le16(cnt >> 16); } /**@brief Get number of unused i-nodes. @@ -195,15 +195,15 @@ static inline void ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg, * @return Number of unused i-nodes */ static inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg, - struct ext4_sblock *s) + struct ext4_sblock *s) { - uint32_t v = to_le16(bg->itable_unused_lo); + uint32_t v = to_le16(bg->itable_unused_lo); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - v |= (uint32_t)to_le16(bg->itable_unused_hi) << 16; + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + v |= (uint32_t)to_le16(bg->itable_unused_hi) << 16; - return v; + return v; } /**@brief Set number of unused i-nodes. @@ -212,12 +212,12 @@ static inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg, * @param cnt Number of unused i-nodes */ static inline void ext4_bg_set_itable_unused(struct ext4_bgroup *bg, - struct ext4_sblock *s, - uint32_t cnt) + struct ext4_sblock *s, + uint32_t cnt) { - bg->itable_unused_lo = to_le16((cnt << 16) >> 16); - if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - bg->itable_unused_hi = to_le16(cnt >> 16); + bg->itable_unused_lo = to_le16((cnt << 16) >> 16); + if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + bg->itable_unused_hi = to_le16(cnt >> 16); } /**@brief Set checksum of block group. @@ -226,7 +226,7 @@ static inline void ext4_bg_set_itable_unused(struct ext4_bgroup *bg, */ static inline void ext4_bg_set_checksum(struct ext4_bgroup *bg, uint16_t crc) { - bg->checksum = to_le16(crc); + bg->checksum = to_le16(crc); } /**@brief Check if block group has a flag. @@ -236,7 +236,7 @@ static inline void ext4_bg_set_checksum(struct ext4_bgroup *bg, uint16_t crc) */ static inline bool ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f) { - return to_le16(bg->flags) & f; + return to_le16(bg->flags) & f; } /**@brief Set flag of block group. @@ -245,9 +245,9 @@ static inline bool ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f) */ static inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f) { - uint16_t flags = to_le16(bg->flags); - flags |= f; - bg->flags = to_le16(flags); + uint16_t flags = to_le16(bg->flags); + flags |= f; + bg->flags = to_le16(flags); } /**@brief Clear flag of block group. @@ -256,9 +256,9 @@ static inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f) */ static inline void ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f) { - uint16_t flags = to_le16(bg->flags); - flags &= ~f; - bg->flags = to_le16(flags); + uint16_t flags = to_le16(bg->flags); + flags &= ~f; + bg->flags = to_le16(flags); } /**@brief Calculate CRC16 of the block group. diff --git a/lwext4/ext4_blockdev.c b/lwext4/ext4_blockdev.c index 56b4c34..57e8f89 100644 --- a/lwext4/ext4_blockdev.c +++ b/lwext4/ext4_blockdev.c @@ -44,386 +44,391 @@ int ext4_block_init(struct ext4_blockdev *bdev) { - int rc; - ext4_assert(bdev); + int rc; + ext4_assert(bdev); - ext4_assert(bdev->open && bdev->close && bdev->bread && bdev->bwrite); + ext4_assert(bdev->open && bdev->close && bdev->bread && bdev->bwrite); - /*Low level block init*/ - rc = bdev->open(bdev); - if (rc != EOK) - return rc; + /*Low level block init*/ + rc = bdev->open(bdev); + if (rc != EOK) + return rc; - bdev->flags |= EXT4_BDEV_INITIALIZED; + bdev->flags |= EXT4_BDEV_INITIALIZED; - return EOK; + return EOK; } int ext4_block_bind_bcache(struct ext4_blockdev *bdev, struct ext4_bcache *bc) { - ext4_assert(bdev && bc); - bdev->bc = bc; - return EOK; + ext4_assert(bdev && bc); + bdev->bc = bc; + return EOK; } 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)); + /*Logical block size has to be multiply of physical */ + ext4_assert(!(lb_bsize % bdev->ph_bsize)); - bdev->lg_bsize = lb_bsize; - bdev->lg_bcnt = (bdev->ph_bcnt * bdev->ph_bsize) / lb_bsize; + bdev->lg_bsize = lb_bsize; + bdev->lg_bcnt = (bdev->ph_bcnt * bdev->ph_bsize) / lb_bsize; } int ext4_block_fini(struct ext4_blockdev *bdev) { - ext4_assert(bdev); + ext4_assert(bdev); - bdev->flags &= ~(EXT4_BDEV_INITIALIZED); + bdev->flags &= ~(EXT4_BDEV_INITIALIZED); - /*Low level block fini*/ - return bdev->close(bdev); + /*Low level block fini*/ + return bdev->close(bdev); } int ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b, - uint64_t lba) + uint64_t lba) { - uint64_t pba; - uint32_t pb_cnt; - uint32_t i; - bool is_new; - int r; - - ext4_assert(bdev && b); - - if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) - return EIO; - - if (!(lba < bdev->lg_bcnt)) - return ERANGE; - - b->dirty = 0; - b->lb_id = lba; - - /*If cache is full we have to flush it anyway :(*/ - if (ext4_bcache_is_full(bdev->bc) && bdev->cache_write_back) { - - uint32_t free_candidate = bdev->bc->cnt; - uint32_t min_lru = 0xFFFFFFFF; - - for (i = 0; i < bdev->bc->cnt; ++i) { - /*Check if buffer free was delayed.*/ - if (!bdev->bc->free_delay[i]) - continue; - - /*Check reference counter.*/ - if (bdev->bc->refctr[i]) - continue; - - if (bdev->bc->lru_id[i] < min_lru) { - min_lru = bdev->bc->lru_id[i]; - free_candidate = i; - continue; - } - } - - if (free_candidate < bdev->bc->cnt) { - /*Buffer free was delayed and have no reference. Flush it.*/ - r = ext4_blocks_set_direct( - bdev, bdev->bc->data + bdev->bc->itemsize * free_candidate, - bdev->bc->lba[free_candidate], 1); - if (r != EOK) - return r; - - /*No delayed anymore*/ - bdev->bc->free_delay[free_candidate] = 0; - - /*Reduce reference counter*/ - bdev->bc->ref_blocks--; - } - } - - r = ext4_bcache_alloc(bdev->bc, b, &is_new); - if (r != EOK) - return r; - - if (!is_new) { - /*Block is in cache. Read from physical device is not required*/ - return EOK; - } - - if (!b->data) - return ENOMEM; - - pba = (lba * bdev->lg_bsize) / bdev->ph_bsize; - pb_cnt = bdev->lg_bsize / bdev->ph_bsize; - - r = bdev->bread(bdev, b->data, pba, pb_cnt); - - if (r != EOK) { - ext4_bcache_free(bdev->bc, b, 0); - b->lb_id = 0; - return r; - } - - bdev->bread_ctr++; - return EOK; + uint64_t pba; + uint32_t pb_cnt; + uint32_t i; + bool is_new; + int r; + + ext4_assert(bdev && b); + + if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) + return EIO; + + if (!(lba < bdev->lg_bcnt)) + return ERANGE; + + b->dirty = 0; + b->lb_id = lba; + + /*If cache is full we have to flush it anyway :(*/ + if (ext4_bcache_is_full(bdev->bc) && bdev->cache_write_back) { + + uint32_t free_candidate = bdev->bc->cnt; + uint32_t min_lru = 0xFFFFFFFF; + + for (i = 0; i < bdev->bc->cnt; ++i) { + /*Check if buffer free was delayed.*/ + if (!bdev->bc->free_delay[i]) + continue; + + /*Check reference counter.*/ + if (bdev->bc->refctr[i]) + continue; + + if (bdev->bc->lru_id[i] < min_lru) { + min_lru = bdev->bc->lru_id[i]; + free_candidate = i; + continue; + } + } + + if (free_candidate < bdev->bc->cnt) { + /*Buffer free was delayed and have no reference. Flush + * it.*/ + r = ext4_blocks_set_direct( + bdev, bdev->bc->data + + bdev->bc->itemsize * free_candidate, + bdev->bc->lba[free_candidate], 1); + if (r != EOK) + return r; + + /*No delayed anymore*/ + bdev->bc->free_delay[free_candidate] = 0; + + /*Reduce reference counter*/ + bdev->bc->ref_blocks--; + } + } + + r = ext4_bcache_alloc(bdev->bc, b, &is_new); + if (r != EOK) + return r; + + if (!is_new) { + /*Block is in cache. Read from physical device is not required*/ + return EOK; + } + + if (!b->data) + return ENOMEM; + + pba = (lba * bdev->lg_bsize) / bdev->ph_bsize; + pb_cnt = bdev->lg_bsize / bdev->ph_bsize; + + r = bdev->bread(bdev, b->data, pba, pb_cnt); + + if (r != EOK) { + ext4_bcache_free(bdev->bc, b, 0); + b->lb_id = 0; + return r; + } + + bdev->bread_ctr++; + return EOK; } int ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b) { - uint64_t pba; - uint32_t pb_cnt; - int r; - - ext4_assert(bdev && b); - - if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) - return EIO; - - /*No need to write.*/ - if (!b->dirty && !bdev->bc->dirty[b->cache_id]) { - ext4_bcache_free(bdev->bc, b, 0); - return EOK; - } - - /*Free cache delay mode*/ - if (bdev->cache_write_back) { - - /*Free cache block and mark as free delayed*/ - return ext4_bcache_free(bdev->bc, b, bdev->cache_write_back); - } - - if (bdev->bc->refctr[b->cache_id] > 1) { - bdev->bc->dirty[b->cache_id] = true; - return ext4_bcache_free(bdev->bc, b, 0); - } - - pba = (b->lb_id * bdev->lg_bsize) / bdev->ph_bsize; - pb_cnt = bdev->lg_bsize / bdev->ph_bsize; - - r = bdev->bwrite(bdev, b->data, pba, pb_cnt); - bdev->bc->dirty[b->cache_id] = false; - if (r != EOK) { - b->dirty = false; - ext4_bcache_free(bdev->bc, b, 0); - return r; - } - - bdev->bwrite_ctr++; - b->dirty = false; - ext4_bcache_free(bdev->bc, b, 0); - return EOK; + uint64_t pba; + uint32_t pb_cnt; + int r; + + ext4_assert(bdev && b); + + if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) + return EIO; + + /*No need to write.*/ + if (!b->dirty && !bdev->bc->dirty[b->cache_id]) { + ext4_bcache_free(bdev->bc, b, 0); + return EOK; + } + + /*Free cache delay mode*/ + if (bdev->cache_write_back) { + + /*Free cache block and mark as free delayed*/ + return ext4_bcache_free(bdev->bc, b, bdev->cache_write_back); + } + + if (bdev->bc->refctr[b->cache_id] > 1) { + bdev->bc->dirty[b->cache_id] = true; + return ext4_bcache_free(bdev->bc, b, 0); + } + + pba = (b->lb_id * bdev->lg_bsize) / bdev->ph_bsize; + pb_cnt = bdev->lg_bsize / bdev->ph_bsize; + + r = bdev->bwrite(bdev, b->data, pba, pb_cnt); + bdev->bc->dirty[b->cache_id] = false; + if (r != EOK) { + b->dirty = false; + ext4_bcache_free(bdev->bc, b, 0); + return r; + } + + bdev->bwrite_ctr++; + b->dirty = false; + ext4_bcache_free(bdev->bc, b, 0); + return EOK; } int ext4_blocks_get_direct(struct ext4_blockdev *bdev, void *buf, uint64_t lba, - uint32_t cnt) + uint32_t cnt) { - uint64_t pba; - uint32_t pb_cnt; + uint64_t pba; + uint32_t pb_cnt; - ext4_assert(bdev && 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->ph_bsize; + pb_cnt = bdev->lg_bsize / bdev->ph_bsize; - bdev->bread_ctr++; - return bdev->bread(bdev, buf, pba, pb_cnt * cnt); + bdev->bread_ctr++; + return bdev->bread(bdev, buf, pba, pb_cnt * cnt); } int ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf, - uint64_t lba, uint32_t cnt) + uint64_t lba, uint32_t cnt) { - uint64_t pba; - uint32_t pb_cnt; + uint64_t pba; + uint32_t pb_cnt; - ext4_assert(bdev && 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->ph_bsize; + pb_cnt = bdev->lg_bsize / bdev->ph_bsize; - bdev->bwrite_ctr++; + bdev->bwrite_ctr++; - return bdev->bwrite(bdev, buf, pba, pb_cnt * cnt); + return bdev->bwrite(bdev, buf, pba, pb_cnt * cnt); } int ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off, - const void *buf, uint32_t len) + const void *buf, uint32_t len) { - uint64_t block_idx; - uint64_t block_end; - uint32_t blen; - uint32_t unalg; - int r = EOK; + uint64_t block_idx; + uint64_t block_end; + uint32_t blen; + uint32_t unalg; + int r = EOK; - const uint8_t *p = (void *)buf; + const uint8_t *p = (void *)buf; - ext4_assert(bdev && buf); + ext4_assert(bdev && buf); - if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) - return EIO; + if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) + return EIO; - block_idx = off / bdev->ph_bsize; - block_end = block_idx + len / bdev->ph_bsize; + block_idx = off / bdev->ph_bsize; + block_end = block_idx + len / bdev->ph_bsize; - if (!(block_end < bdev->ph_bcnt)) - return EINVAL; /*Ups. Out of range operation*/ + if (!(block_end < bdev->ph_bcnt)) + return EINVAL; /*Ups. Out of range operation*/ - /*OK lets deal with the first possible unaligned block*/ - unalg = (off & (bdev->ph_bsize - 1)); - if (unalg) { + /*OK lets deal with the first possible unaligned block*/ + unalg = (off & (bdev->ph_bsize - 1)); + if (unalg) { - uint32_t wlen = - (bdev->ph_bsize - unalg) > len ? len : (bdev->ph_bsize - unalg); + uint32_t wlen = (bdev->ph_bsize - unalg) > len + ? len + : (bdev->ph_bsize - unalg); - r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); + r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); - if (r != EOK) - return r; + if (r != EOK) + return r; - memcpy(bdev->ph_bbuf + unalg, p, wlen); + memcpy(bdev->ph_bbuf + unalg, p, wlen); - r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1); - if (r != EOK) - return r; + r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1); + if (r != EOK) + return r; - p += wlen; - len -= wlen; - block_idx++; - } + p += wlen; + len -= wlen; + block_idx++; + } - /*Aligned data*/ - blen = len / bdev->ph_bsize; - r = bdev->bwrite(bdev, p, block_idx, blen); + /*Aligned data*/ + blen = len / bdev->ph_bsize; + r = bdev->bwrite(bdev, p, block_idx, blen); - if (r != EOK) - return r; + if (r != EOK) + return r; - p += bdev->ph_bsize * blen; - len -= bdev->ph_bsize * blen; + p += bdev->ph_bsize * blen; + len -= bdev->ph_bsize * blen; - block_idx += blen; + block_idx += blen; - /*Rest of the data*/ - if (len) { - r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); - if (r != EOK) - return r; + /*Rest of the data*/ + if (len) { + r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); + if (r != EOK) + return r; - memcpy(bdev->ph_bbuf, p, len); + memcpy(bdev->ph_bbuf, p, len); - r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1); + r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1); - if (r != EOK) - return r; - } + if (r != EOK) + return r; + } - return r; + return r; } int ext4_block_readbytes(struct ext4_blockdev *bdev, uint64_t off, void *buf, - uint32_t len) + uint32_t len) { - uint64_t block_idx; - uint64_t block_end; - uint32_t blen; - uint32_t unalg; - int r = EOK; + uint64_t block_idx; + uint64_t block_end; + uint32_t blen; + uint32_t unalg; + int r = EOK; - uint8_t *p = (void *)buf; + uint8_t *p = (void *)buf; - ext4_assert(bdev && buf); + ext4_assert(bdev && buf); - if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) - return EIO; + if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) + return EIO; - block_idx = off / bdev->ph_bsize; - block_end = block_idx + len / bdev->ph_bsize; + block_idx = off / bdev->ph_bsize; + block_end = block_idx + len / bdev->ph_bsize; - if (!(block_end < bdev->ph_bcnt)) - return EINVAL; /*Ups. Out of range operation*/ + if (!(block_end < bdev->ph_bcnt)) + return EINVAL; /*Ups. Out of range operation*/ - /*OK lets deal with the first possible unaligned block*/ - unalg = (off & (bdev->ph_bsize - 1)); - if (unalg) { + /*OK lets deal with the first possible unaligned block*/ + unalg = (off & (bdev->ph_bsize - 1)); + if (unalg) { - uint32_t rlen = - (bdev->ph_bsize - unalg) > len ? len : (bdev->ph_bsize - unalg); + uint32_t rlen = (bdev->ph_bsize - unalg) > len + ? len + : (bdev->ph_bsize - unalg); - r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); - if (r != EOK) - return r; + r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); + if (r != EOK) + return r; - memcpy(p, bdev->ph_bbuf + unalg, rlen); + memcpy(p, bdev->ph_bbuf + unalg, rlen); - p += rlen; - len -= rlen; - block_idx++; - } + p += rlen; + len -= rlen; + block_idx++; + } - /*Aligned data*/ - blen = len / bdev->ph_bsize; + /*Aligned data*/ + blen = len / bdev->ph_bsize; - r = bdev->bread(bdev, p, block_idx, blen); + r = bdev->bread(bdev, p, block_idx, blen); - if (r != EOK) - return r; + if (r != EOK) + return r; - p += bdev->ph_bsize * blen; - len -= bdev->ph_bsize * blen; + p += bdev->ph_bsize * blen; + len -= bdev->ph_bsize * blen; - block_idx += blen; + block_idx += blen; - /*Rest of the data*/ - if (len) { - r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); - if (r != EOK) - return r; + /*Rest of the data*/ + if (len) { + r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1); + if (r != EOK) + return r; - memcpy(p, bdev->ph_bbuf, len); - } + memcpy(p, bdev->ph_bbuf, len); + } - return r; + return r; } int ext4_block_cache_write_back(struct ext4_blockdev *bdev, uint8_t on_off) { - int r; - uint32_t i; - - if (on_off) - bdev->cache_write_back++; - - if (!on_off && bdev->cache_write_back) - bdev->cache_write_back--; - - /*Flush all delayed cache blocks*/ - if (!bdev->cache_write_back) { - for (i = 0; i < bdev->bc->cnt; ++i) { - - /*Check if buffer free was delayed.*/ - if (!bdev->bc->free_delay[i]) - continue; - - /*Check reference counter.*/ - if (bdev->bc->refctr[i]) - continue; - - /*Buffer free was delayed and have no reference. Flush it.*/ - r = ext4_blocks_set_direct(bdev, - bdev->bc->data + bdev->bc->itemsize * i, - bdev->bc->lba[i], 1); - if (r != EOK) - return r; - - /*No delayed anymore*/ - bdev->bc->free_delay[i] = 0; - - /*Reduce reference counter*/ - bdev->bc->ref_blocks--; - } - } - return EOK; + int r; + uint32_t i; + + if (on_off) + bdev->cache_write_back++; + + if (!on_off && bdev->cache_write_back) + bdev->cache_write_back--; + + /*Flush all delayed cache blocks*/ + if (!bdev->cache_write_back) { + for (i = 0; i < bdev->bc->cnt; ++i) { + + /*Check if buffer free was delayed.*/ + if (!bdev->bc->free_delay[i]) + continue; + + /*Check reference counter.*/ + if (bdev->bc->refctr[i]) + continue; + + /*Buffer free was delayed and have no reference. Flush + * it.*/ + r = ext4_blocks_set_direct( + bdev, bdev->bc->data + bdev->bc->itemsize * i, + bdev->bc->lba[i], 1); + if (r != EOK) + return r; + + /*No delayed anymore*/ + bdev->bc->free_delay[i] = 0; + + /*Reduce reference counter*/ + bdev->bc->ref_blocks--; + } + } + return EOK; } /** diff --git a/lwext4/ext4_blockdev.h b/lwext4/ext4_blockdev.h index 59ba2b6..a525219 100644 --- a/lwext4/ext4_blockdev.h +++ b/lwext4/ext4_blockdev.h @@ -49,73 +49,73 @@ /**@brief Definition of the simple block device.*/ struct ext4_blockdev { - /**@brief Open device function - * @param bdev block device.*/ - int (*open)(struct ext4_blockdev *bdev); + /**@brief Open device function + * @param bdev block device.*/ + int (*open)(struct ext4_blockdev *bdev); - /**@brief Block read function. - * @param bdev block device - * @param buf output buffer - * @param blk_id block id - * @param blk_cnt block count*/ - int (*bread)(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id, - uint32_t blk_cnt); + /**@brief Block read function. + * @param bdev block device + * @param buf output buffer + * @param blk_id block id + * @param blk_cnt block count*/ + int (*bread)(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id, + uint32_t blk_cnt); - /**@brief Block write function. - * @param buf input buffer - * @param blk_id block id - * @param blk_cnt block count*/ - int (*bwrite)(struct ext4_blockdev *bdev, const void *buf, uint64_t blk_id, - uint32_t blk_cnt); + /**@brief Block write function. + * @param buf input buffer + * @param blk_id block id + * @param blk_cnt block count*/ + int (*bwrite)(struct ext4_blockdev *bdev, const void *buf, + uint64_t blk_id, uint32_t blk_cnt); - /**@brief Close device function. - * @param bdev block device.*/ - int (*close)(struct ext4_blockdev *bdev); + /**@brief Close device function. + * @param bdev block device.*/ + int (*close)(struct ext4_blockdev *bdev); - /**@brief Block cache.*/ - struct ext4_bcache *bc; + /**@brief Block cache.*/ + struct ext4_bcache *bc; - /**@brief Block size (bytes): physical*/ - uint32_t ph_bsize; + /**@brief Block size (bytes): physical*/ + uint32_t ph_bsize; - /**@brief Block count: physical*/ - uint64_t ph_bcnt; + /**@brief Block count: physical*/ + uint64_t ph_bcnt; - /**@brief Block size buffer: physical*/ - uint8_t *ph_bbuf; + /**@brief Block size buffer: physical*/ + uint8_t *ph_bbuf; - /**@brief Block size (bytes) logical*/ - uint32_t lg_bsize; + /**@brief Block size (bytes) logical*/ + uint32_t lg_bsize; - /**@brief Block count: physical*/ - uint64_t lg_bcnt; + /**@brief Block count: physical*/ + uint64_t lg_bcnt; - /**@brief Flags of block device*/ - uint32_t flags; + /**@brief Flags of block device*/ + uint32_t flags; - /**@brief Cache write back mode reference counter*/ - uint32_t cache_write_back; + /**@brief Cache write back mode reference counter*/ + uint32_t cache_write_back; - /**@brief Physical read counter*/ - uint32_t bread_ctr; + /**@brief Physical read counter*/ + uint32_t bread_ctr; - /**@brief Physical write counter*/ - uint32_t bwrite_ctr; + /**@brief Physical write counter*/ + uint32_t bwrite_ctr; }; /**@brief Static initialization of the block device.*/ #define EXT4_BLOCKDEV_STATIC_INSTANCE(__name, __bsize, __bcnt, __open, \ - __bread, __bwrite, __close) \ - static uint8_t __name##_ph_bbuf[(__bsize)]; \ - static struct ext4_blockdev __name = { \ - .open = __open, \ - .bread = __bread, \ - .bwrite = __bwrite, \ - .close = __close, \ - .ph_bsize = __bsize, \ - .ph_bcnt = __bcnt, \ - .ph_bbuf = __name##_ph_bbuf, \ - } + __bread, __bwrite, __close) \ + static uint8_t __name##_ph_bbuf[(__bsize)]; \ + static struct ext4_blockdev __name = { \ + .open = __open, \ + .bread = __bread, \ + .bwrite = __bwrite, \ + .close = __close, \ + .ph_bsize = __bsize, \ + .ph_bcnt = __bcnt, \ + .ph_bbuf = __name##_ph_bbuf, \ + } /**@brief Block device initialization. * @param bdev block device descriptor @@ -147,7 +147,7 @@ void ext4_block_set_lb_size(struct ext4_blockdev *bdev, uint64_t lb_bsize); * @param lba logical block address * @return standard error code*/ int ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b, - uint64_t lba); + uint64_t lba); /**@brief Block set procedure (through cache). * @param bdev block device descriptor @@ -161,7 +161,7 @@ int ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b); * @param lba logical block address * @return standard error code*/ int ext4_blocks_get_direct(struct ext4_blockdev *bdev, void *buf, uint64_t lba, - uint32_t cnt); + uint32_t cnt); /**@brief Block write procedure (without cache) * @param bdev block device descriptor @@ -169,7 +169,7 @@ int ext4_blocks_get_direct(struct ext4_blockdev *bdev, void *buf, uint64_t lba, * @param lba logical block address * @return standard error code*/ int ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf, - uint64_t lba, uint32_t cnt); + uint64_t lba, uint32_t cnt); /**@brief Write to block device (by direct address). * @param bdev block device descriptor @@ -178,7 +178,7 @@ int ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf, * @param len length of the write buffer * @return standard error code*/ int ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off, - const void *buf, uint32_t len); + const void *buf, uint32_t len); /**@brief Read freom block device (by direct address). * @param bdev block device descriptor @@ -187,7 +187,7 @@ int ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off, * @param len length of the write buffer * @return standard error code*/ int ext4_block_readbytes(struct ext4_blockdev *bdev, uint64_t off, void *buf, - uint32_t len); + uint32_t len); /**@brief Enable/disable write back cache mode * @param bdev block device descriptor diff --git a/lwext4/ext4_config.h b/lwext4/ext4_config.h index b68785f..67fd3bf 100644 --- a/lwext4/ext4_config.h +++ b/lwext4/ext4_config.h @@ -61,7 +61,7 @@ #define CONFIG_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_SUPP #define CONFIG_FEATURE_INCOMPAT_SUPP \ - (EXT2_FEATURE_INCOMPAT_SUPP | FEATURE_INCOMPAT_IGNORED) + (EXT2_FEATURE_INCOMPAT_SUPP | FEATURE_INCOMPAT_IGNORED) #define CONFIG_FEATURE_RO_COMPAT_SUPP EXT2_FEATURE_RO_COMPAT_SUPP #elif CONFIG_EXT_FEATURE_SET_LVL == F_SET_EXT3 @@ -72,7 +72,7 @@ #define CONFIG_FEATURE_COMPAT_SUPP EXT3_FEATURE_COMPAT_SUPP #define CONFIG_FEATURE_INCOMPAT_SUPP \ - (EXT3_FEATURE_INCOMPAT_SUPP | FEATURE_INCOMPAT_IGNORED) + (EXT3_FEATURE_INCOMPAT_SUPP | FEATURE_INCOMPAT_IGNORED) #define CONFIG_FEATURE_RO_COMPAT_SUPP EXT3_FEATURE_RO_COMPAT_SUPP #elif CONFIG_EXT_FEATURE_SET_LVL == F_SET_EXT4 @@ -83,7 +83,7 @@ #define CONFIG_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_SUPP #define CONFIG_FEATURE_INCOMPAT_SUPP \ - (EXT4_FEATURE_INCOMPAT_SUPP | FEATURE_INCOMPAT_IGNORED) + (EXT4_FEATURE_INCOMPAT_SUPP | FEATURE_INCOMPAT_IGNORED) #define CONFIG_FEATURE_RO_COMPAT_SUPP EXT4_FEATURE_RO_COMPAT_SUPP #else diff --git a/lwext4/ext4_crc32c.c b/lwext4/ext4_crc32c.c index d333701..676fc46 100644 --- a/lwext4/ext4_crc32c.c +++ b/lwext4/ext4_crc32c.c @@ -112,12 +112,12 @@ static const uint32_t crc32Table[256] = { uint32_t ext4_crc32c(uint32_t crc, const void *buffer, uint32_t length) { - const uint8_t *p = buffer; + const uint8_t *p = buffer; - while (length--) - crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8); + while (length--) + crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8); - return crc; + return crc; } /** diff --git a/lwext4/ext4_debug.h b/lwext4/ext4_debug.h index 9eed22d..71f3da8 100644 --- a/lwext4/ext4_debug.h +++ b/lwext4/ext4_debug.h @@ -90,11 +90,11 @@ uint32_t ext4_dmask_get(void); #if CONFIG_DEBUG_PRINTF /**@brief Debug printf.*/ #define ext4_dprintf(m, ...) \ - do { \ - if (m & ext4_dmask_get()) \ - printf(__VA_ARGS__); \ - fflush(stdout); \ - } while (0) + do { \ + if (m & ext4_dmask_get()) \ + printf(__VA_ARGS__); \ + fflush(stdout); \ + } while (0) #else #define ext4_dprintf(m, ...) #endif @@ -102,12 +102,12 @@ uint32_t ext4_dmask_get(void); #if CONFIG_DEBUG_ASSERT /**@brief Debug assertion.*/ #define ext4_assert(_v) \ - do { \ - if (!(_v)) { \ - printf("Assertion failed:\nmodule: %s\nline: %d\n", \ - __FILE__, __LINE__); \ - } \ - } while (0) + do { \ + if (!(_v)) { \ + printf("Assertion failed:\nmodule: %s\nline: %d\n", \ + __FILE__, __LINE__); \ + } \ + } while (0) #else #define ext4_assert(_v) #endif diff --git a/lwext4/ext4_dir.c b/lwext4/ext4_dir.c index 47c699a..7113685 100644 --- a/lwext4/ext4_dir.c +++ b/lwext4/ext4_dir.c @@ -55,36 +55,36 @@ * @return Error code
*/
static int ext4_dir_iterator_set(struct ext4_directory_iterator *it,
- uint32_t block_size)
+ uint32_t block_size)
{
- it->current = NULL;
+ it->current = NULL;
- uint32_t offset_in_block = it->current_offset % block_size;
+ uint32_t offset_in_block = it->current_offset % block_size;
- /* Ensure proper alignment */
- if ((offset_in_block % 4) != 0)
- return EIO;
+ /* Ensure proper alignment */
+ if ((offset_in_block % 4) != 0)
+ return EIO;
- /* Ensure that the core of the entry does not overflow the block */
- if (offset_in_block > block_size - 8)
- return EIO;
+ /* Ensure that the core of the entry does not overflow the block */
+ if (offset_in_block > block_size - 8)
+ return EIO;
- struct ext4_directory_entry_ll *entry =
- (void *)(it->current_block.data + offset_in_block);
+ struct ext4_directory_entry_ll *entry =
+ (void *)(it->current_block.data + offset_in_block);
- /* Ensure that the whole entry does not overflow the block */
- uint16_t length = ext4_dir_entry_ll_get_entry_length(entry);
- if (offset_in_block + length > block_size)
- return EIO;
+ /* Ensure that the whole entry does not overflow the block */
+ uint16_t length = ext4_dir_entry_ll_get_entry_length(entry);
+ if (offset_in_block + length > block_size)
+ return EIO;
- /* Ensure the name length is not too large */
- if (ext4_dir_entry_ll_get_name_length(&it->inode_ref->fs->sb, entry) >
- length - 8)
- return EIO;
+ /* Ensure the name length is not too large */
+ if (ext4_dir_entry_ll_get_name_length(&it->inode_ref->fs->sb, entry) >
+ length - 8)
+ return EIO;
- /* Everything OK - "publish" the entry */
- it->current = entry;
- return EOK;
+ /* Everything OK - "publish" the entry */
+ it->current = entry;
+ return EOK;
}
/**@brief Seek to next valid directory entry.
@@ -94,463 +94,479 @@ static int ext4_dir_iterator_set(struct ext4_directory_iterator *it, * @return Error code
*/
static int ext4_dir_iterator_seek(struct ext4_directory_iterator *it,
- uint64_t pos)
+ uint64_t pos)
{
- uint64_t size =
- ext4_inode_get_size(&it->inode_ref->fs->sb, it->inode_ref->inode);
-
- /* The iterator is not valid until we seek to the desired position */
- it->current = NULL;
-
- /* Are we at the end? */
- if (pos >= size) {
- if (it->current_block.lb_id) {
-
- int rc =
- ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
- it->current_block.lb_id = 0;
-
- if (rc != EOK)
- return rc;
- }
-
- it->current_offset = pos;
- return EOK;
- }
-
- /* Compute next block address */
- uint32_t block_size = ext4_sb_get_block_size(&it->inode_ref->fs->sb);
- uint64_t current_block_idx = it->current_offset / block_size;
- uint64_t next_block_idx = pos / block_size;
-
- /*
- * If we don't have a block or are moving across block boundary,
- * we need to get another block
- */
- if ((it->current_block.lb_id == 0) ||
- (current_block_idx != next_block_idx)) {
- if (it->current_block.lb_id) {
- int rc =
- ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
- it->current_block.lb_id = 0;
-
- if (rc != EOK)
- return rc;
- }
-
- uint32_t next_block_phys_idx;
- int rc = ext4_fs_get_inode_data_block_index(
- it->inode_ref, next_block_idx, &next_block_phys_idx);
- if (rc != EOK)
- return rc;
-
- rc = ext4_block_get(it->inode_ref->fs->bdev, &it->current_block,
- next_block_phys_idx);
- if (rc != EOK) {
- it->current_block.lb_id = 0;
- return rc;
- }
- }
-
- it->current_offset = pos;
-
- return ext4_dir_iterator_set(it, block_size);
+ uint64_t size =
+ ext4_inode_get_size(&it->inode_ref->fs->sb, it->inode_ref->inode);
+
+ /* The iterator is not valid until we seek to the desired position */
+ it->current = NULL;
+
+ /* Are we at the end? */
+ if (pos >= size) {
+ if (it->current_block.lb_id) {
+
+ int rc = ext4_block_set(it->inode_ref->fs->bdev,
+ &it->current_block);
+ it->current_block.lb_id = 0;
+
+ if (rc != EOK)
+ return rc;
+ }
+
+ it->current_offset = pos;
+ return EOK;
+ }
+
+ /* Compute next block address */
+ uint32_t block_size = ext4_sb_get_block_size(&it->inode_ref->fs->sb);
+ uint64_t current_block_idx = it->current_offset / block_size;
+ uint64_t next_block_idx = pos / block_size;
+
+ /*
+ * If we don't have a block or are moving across block boundary,
+ * we need to get another block
+ */
+ if ((it->current_block.lb_id == 0) ||
+ (current_block_idx != next_block_idx)) {
+ if (it->current_block.lb_id) {
+ int rc = ext4_block_set(it->inode_ref->fs->bdev,
+ &it->current_block);
+ it->current_block.lb_id = 0;
+
+ if (rc != EOK)
+ return rc;
+ }
+
+ uint32_t next_block_phys_idx;
+ int rc = ext4_fs_get_inode_data_block_index(
+ it->inode_ref, next_block_idx, &next_block_phys_idx);
+ if (rc != EOK)
+ return rc;
+
+ rc = ext4_block_get(it->inode_ref->fs->bdev, &it->current_block,
+ next_block_phys_idx);
+ if (rc != EOK) {
+ it->current_block.lb_id = 0;
+ return rc;
+ }
+ }
+
+ it->current_offset = pos;
+
+ return ext4_dir_iterator_set(it, block_size);
}
int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
- struct ext4_inode_ref *inode_ref, uint64_t pos)
+ struct ext4_inode_ref *inode_ref, uint64_t pos)
{
- it->inode_ref = inode_ref;
- it->current = 0;
- it->current_offset = 0;
- it->current_block.lb_id = 0;
+ it->inode_ref = inode_ref;
+ it->current = 0;
+ it->current_offset = 0;
+ it->current_block.lb_id = 0;
- return ext4_dir_iterator_seek(it, pos);
+ return ext4_dir_iterator_seek(it, pos);
}
int ext4_dir_iterator_next(struct ext4_directory_iterator *it)
{
- int r = EOK;
- uint16_t skip;
+ int r = EOK;
+ uint16_t skip;
- while (r == EOK) {
- skip = ext4_dir_entry_ll_get_entry_length(it->current);
- r = ext4_dir_iterator_seek(it, it->current_offset + skip);
+ while (r == EOK) {
+ skip = ext4_dir_entry_ll_get_entry_length(it->current);
+ r = ext4_dir_iterator_seek(it, it->current_offset + skip);
- if (!it->current)
- break;
- /*Skip NULL referenced entry*/
- if (it->current->inode != 0)
- break;
- }
+ if (!it->current)
+ break;
+ /*Skip NULL referenced entry*/
+ if (it->current->inode != 0)
+ break;
+ }
- return r;
+ return r;
}
int ext4_dir_iterator_fini(struct ext4_directory_iterator *it)
{
- it->current = 0;
+ it->current = 0;
- if (it->current_block.lb_id)
- return ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
+ if (it->current_block.lb_id)
+ return ext4_block_set(it->inode_ref->fs->bdev,
+ &it->current_block);
- return EOK;
+ return EOK;
}
void ext4_dir_write_entry(struct ext4_sblock *sb,
- struct ext4_directory_entry_ll *entry,
- uint16_t entry_len, struct ext4_inode_ref *child,
- const char *name, size_t name_len)
+ struct ext4_directory_entry_ll *entry,
+ uint16_t entry_len, struct ext4_inode_ref *child,
+ const char *name, size_t name_len)
{
- /* Check maximum entry length */
- ext4_assert(entry_len <= ext4_sb_get_block_size(sb));
-
- /* Set basic attributes */
- ext4_dir_entry_ll_set_inode(entry, child->index);
- ext4_dir_entry_ll_set_entry_length(entry, entry_len);
- ext4_dir_entry_ll_set_name_length(sb, entry, name_len);
-
- /* Write name */
- memcpy(entry->name, name, name_len);
-
- /* Set type of entry */
- if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY))
- ext4_dir_entry_ll_set_inode_type(sb, entry,
- EXT4_DIRECTORY_FILETYPE_DIR);
- else
- ext4_dir_entry_ll_set_inode_type(sb, entry,
- EXT4_DIRECTORY_FILETYPE_REG_FILE);
+ /* Check maximum entry length */
+ ext4_assert(entry_len <= ext4_sb_get_block_size(sb));
+
+ /* Set basic attributes */
+ ext4_dir_entry_ll_set_inode(entry, child->index);
+ ext4_dir_entry_ll_set_entry_length(entry, entry_len);
+ ext4_dir_entry_ll_set_name_length(sb, entry, name_len);
+
+ /* Write name */
+ memcpy(entry->name, name, name_len);
+
+ /* Set type of entry */
+ if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY))
+ ext4_dir_entry_ll_set_inode_type(sb, entry,
+ EXT4_DIRECTORY_FILETYPE_DIR);
+ else
+ ext4_dir_entry_ll_set_inode_type(
+ sb, entry, EXT4_DIRECTORY_FILETYPE_REG_FILE);
}
int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
- uint32_t name_len, struct ext4_inode_ref *child)
+ uint32_t name_len, struct ext4_inode_ref *child)
{
- struct ext4_fs *fs = parent->fs;
+ struct ext4_fs *fs = parent->fs;
#if CONFIG_DIR_INDEX_ENABLE
- /* Index adding (if allowed) */
- if ((ext4_sb_has_feature_compatible(&fs->sb,
- EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
- (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
- int rc = ext4_dir_dx_add_entry(parent, child, name);
-
- /* Check if index is not corrupted */
- if (rc != EXT4_ERR_BAD_DX_DIR) {
- if (rc != EOK)
- return rc;
-
- return EOK;
- }
-
- /* Needed to clear dir index flag if corrupted */
- ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
- parent->dirty = true;
- }
+ /* Index adding (if allowed) */
+ if ((ext4_sb_has_feature_compatible(&fs->sb,
+ EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
+ (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
+ int rc = ext4_dir_dx_add_entry(parent, child, name);
+
+ /* Check if index is not corrupted */
+ if (rc != EXT4_ERR_BAD_DX_DIR) {
+ if (rc != EOK)
+ return rc;
+
+ return EOK;
+ }
+
+ /* Needed to clear dir index flag if corrupted */
+ ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
+ parent->dirty = true;
+ }
#endif
- /* Linear algorithm */
- uint32_t iblock = 0;
- uint32_t fblock = 0;
- uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
- uint32_t inode_size = ext4_inode_get_size(&fs->sb, parent->inode);
- uint32_t total_blocks = inode_size / block_size;
-
- /* Find block, where is space for new entry and try to add */
- bool success = false;
- for (iblock = 0; iblock < total_blocks; ++iblock) {
- int rc = ext4_fs_get_inode_data_block_index(parent, iblock, &fblock);
- if (rc != EOK)
- return rc;
-
- struct ext4_block block;
- rc = ext4_block_get(fs->bdev, &block, fblock);
- if (rc != EOK)
- return rc;
-
- /* If adding is successful, function can finish */
- rc = ext4_dir_try_insert_entry(&fs->sb, &block, child, name, name_len);
- if (rc == EOK)
- success = true;
-
- rc = ext4_block_set(fs->bdev, &block);
- if (rc != EOK)
- return rc;
-
- if (success)
- return EOK;
- }
-
- /* No free block found - needed to allocate next data block */
-
- iblock = 0;
- fblock = 0;
- int rc = ext4_fs_append_inode_block(parent, &fblock, &iblock);
- if (rc != EOK)
- return rc;
-
- /* Load new block */
- struct ext4_block new_block;
-
- rc = ext4_block_get(fs->bdev, &new_block, fblock);
- if (rc != EOK)
- return rc;
-
- /* Fill block with zeroes */
- memset(new_block.data, 0, block_size);
- struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
- ext4_dir_write_entry(&fs->sb, block_entry, block_size, child, name,
- name_len);
-
- /* Save new block */
- new_block.dirty = true;
- rc = ext4_block_set(fs->bdev, &new_block);
-
- return rc;
+ /* Linear algorithm */
+ uint32_t iblock = 0;
+ uint32_t fblock = 0;
+ uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
+ uint32_t inode_size = ext4_inode_get_size(&fs->sb, parent->inode);
+ uint32_t total_blocks = inode_size / block_size;
+
+ /* Find block, where is space for new entry and try to add */
+ bool success = false;
+ for (iblock = 0; iblock < total_blocks; ++iblock) {
+ int rc =
+ ext4_fs_get_inode_data_block_index(parent, iblock, &fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_block block;
+ rc = ext4_block_get(fs->bdev, &block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* If adding is successful, function can finish */
+ rc = ext4_dir_try_insert_entry(&fs->sb, &block, child, name,
+ name_len);
+ if (rc == EOK)
+ success = true;
+
+ rc = ext4_block_set(fs->bdev, &block);
+ if (rc != EOK)
+ return rc;
+
+ if (success)
+ return EOK;
+ }
+
+ /* No free block found - needed to allocate next data block */
+
+ iblock = 0;
+ fblock = 0;
+ int rc = ext4_fs_append_inode_block(parent, &fblock, &iblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Load new block */
+ struct ext4_block new_block;
+
+ rc = ext4_block_get(fs->bdev, &new_block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Fill block with zeroes */
+ memset(new_block.data, 0, block_size);
+ struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
+ ext4_dir_write_entry(&fs->sb, block_entry, block_size, child, name,
+ name_len);
+
+ /* Save new block */
+ new_block.dirty = true;
+ rc = ext4_block_set(fs->bdev, &new_block);
+
+ return rc;
}
int ext4_dir_find_entry(struct ext4_directory_search_result *result,
- struct ext4_inode_ref *parent, const char *name,
- uint32_t name_len)
+ struct ext4_inode_ref *parent, const char *name,
+ uint32_t name_len)
{
- struct ext4_sblock *sb = &parent->fs->sb;
+ struct ext4_sblock *sb = &parent->fs->sb;
#if CONFIG_DIR_INDEX_ENABLE
- /* Index search */
- if ((ext4_sb_has_feature_compatible(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
- (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
- int rc = ext4_dir_dx_find_entry(result, parent, name_len, name);
-
- /* Check if index is not corrupted */
- if (rc != EXT4_ERR_BAD_DX_DIR) {
- if (rc != EOK)
- return rc;
-
- return EOK;
- }
-
- /* Needed to clear dir index flag if corrupted */
- ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
- parent->dirty = true;
- }
+ /* Index search */
+ if ((ext4_sb_has_feature_compatible(sb,
+ EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
+ (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
+ int rc = ext4_dir_dx_find_entry(result, parent, name_len, name);
+
+ /* Check if index is not corrupted */
+ if (rc != EXT4_ERR_BAD_DX_DIR) {
+ if (rc != EOK)
+ return rc;
+
+ return EOK;
+ }
+
+ /* Needed to clear dir index flag if corrupted */
+ ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
+ parent->dirty = true;
+ }
#endif
- /* Linear algorithm */
-
- uint32_t iblock;
- uint32_t fblock;
- uint32_t block_size = ext4_sb_get_block_size(sb);
- uint32_t inode_size = ext4_inode_get_size(sb, parent->inode);
- uint32_t total_blocks = inode_size / block_size;
-
- /* Walk through all data blocks */
- for (iblock = 0; iblock < total_blocks; ++iblock) {
- /* Load block address */
- int rc = ext4_fs_get_inode_data_block_index(parent, iblock, &fblock);
- if (rc != EOK)
- return rc;
-
- /* Load data block */
- struct ext4_block block;
- rc = ext4_block_get(parent->fs->bdev, &block, fblock);
- if (rc != EOK)
- return rc;
-
- /* Try to find entry in block */
- struct ext4_directory_entry_ll *res_entry;
- rc = ext4_dir_find_in_block(&block, sb, name_len, name, &res_entry);
- if (rc == EOK) {
- result->block = block;
- result->dentry = res_entry;
- return EOK;
- }
-
- /* Entry not found - put block and continue to the next block */
-
- rc = ext4_block_set(parent->fs->bdev, &block);
- if (rc != EOK)
- return rc;
- }
-
- /* Entry was not found */
-
- result->block.lb_id = 0;
- result->dentry = NULL;
-
- return ENOENT;
+ /* Linear algorithm */
+
+ uint32_t iblock;
+ uint32_t fblock;
+ uint32_t block_size = ext4_sb_get_block_size(sb);
+ uint32_t inode_size = ext4_inode_get_size(sb, parent->inode);
+ uint32_t total_blocks = inode_size / block_size;
+
+ /* Walk through all data blocks */
+ for (iblock = 0; iblock < total_blocks; ++iblock) {
+ /* Load block address */
+ int rc =
+ ext4_fs_get_inode_data_block_index(parent, iblock, &fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Load data block */
+ struct ext4_block block;
+ rc = ext4_block_get(parent->fs->bdev, &block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Try to find entry in block */
+ struct ext4_directory_entry_ll *res_entry;
+ rc = ext4_dir_find_in_block(&block, sb, name_len, name,
+ &res_entry);
+ if (rc == EOK) {
+ result->block = block;
+ result->dentry = res_entry;
+ return EOK;
+ }
+
+ /* Entry not found - put block and continue to the next block */
+
+ rc = ext4_block_set(parent->fs->bdev, &block);
+ if (rc != EOK)
+ return rc;
+ }
+
+ /* Entry was not found */
+
+ result->block.lb_id = 0;
+ result->dentry = NULL;
+
+ return ENOENT;
}
int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
- uint32_t name_len)
+ uint32_t name_len)
{
- /* Check if removing from directory */
- if (!ext4_inode_is_type(&parent->fs->sb, parent->inode,
- EXT4_INODE_MODE_DIRECTORY))
- return ENOTDIR;
-
- /* Try to find entry */
- struct ext4_directory_search_result result;
- int rc = ext4_dir_find_entry(&result, parent, name, name_len);
- if (rc != EOK)
- return rc;
-
- /* Invalidate entry */
- ext4_dir_entry_ll_set_inode(result.dentry, 0);
-
- /* Store entry position in block */
- uint32_t pos = (uint8_t *)result.dentry - result.block.data;
-
- /*
- * If entry is not the first in block, it must be merged
- * with previous entry
- */
- if (pos != 0) {
- uint32_t offset = 0;
-
- /* Start from the first entry in block */
- struct ext4_directory_entry_ll *tmp_dentry = (void *)result.block.data;
- uint16_t tmp_dentry_length =
- ext4_dir_entry_ll_get_entry_length(tmp_dentry);
-
- /* Find direct predecessor of removed entry */
- while ((offset + tmp_dentry_length) < pos) {
- offset += ext4_dir_entry_ll_get_entry_length(tmp_dentry);
- tmp_dentry = (void *)(result.block.data + offset);
- tmp_dentry_length = ext4_dir_entry_ll_get_entry_length(tmp_dentry);
- }
-
- ext4_assert(tmp_dentry_length + offset == pos);
-
- /* Add to removed entry length to predecessor's length */
- uint16_t del_entry_length =
- ext4_dir_entry_ll_get_entry_length(result.dentry);
- ext4_dir_entry_ll_set_entry_length(tmp_dentry, tmp_dentry_length +
- del_entry_length);
- }
-
- result.block.dirty = true;
-
- return ext4_dir_destroy_result(parent, &result);
+ /* Check if removing from directory */
+ if (!ext4_inode_is_type(&parent->fs->sb, parent->inode,
+ EXT4_INODE_MODE_DIRECTORY))
+ return ENOTDIR;
+
+ /* Try to find entry */
+ struct ext4_directory_search_result result;
+ int rc = ext4_dir_find_entry(&result, parent, name, name_len);
+ if (rc != EOK)
+ return rc;
+
+ /* Invalidate entry */
+ ext4_dir_entry_ll_set_inode(result.dentry, 0);
+
+ /* Store entry position in block */
+ uint32_t pos = (uint8_t *)result.dentry - result.block.data;
+
+ /*
+ * If entry is not the first in block, it must be merged
+ * with previous entry
+ */
+ if (pos != 0) {
+ uint32_t offset = 0;
+
+ /* Start from the first entry in block */
+ struct ext4_directory_entry_ll *tmp_dentry =
+ (void *)result.block.data;
+ uint16_t tmp_dentry_length =
+ ext4_dir_entry_ll_get_entry_length(tmp_dentry);
+
+ /* Find direct predecessor of removed entry */
+ while ((offset + tmp_dentry_length) < pos) {
+ offset +=
+ ext4_dir_entry_ll_get_entry_length(tmp_dentry);
+ tmp_dentry = (void *)(result.block.data + offset);
+ tmp_dentry_length =
+ ext4_dir_entry_ll_get_entry_length(tmp_dentry);
+ }
+
+ ext4_assert(tmp_dentry_length + offset == pos);
+
+ /* Add to removed entry length to predecessor's length */
+ uint16_t del_entry_length =
+ ext4_dir_entry_ll_get_entry_length(result.dentry);
+ ext4_dir_entry_ll_set_entry_length(
+ tmp_dentry, tmp_dentry_length + del_entry_length);
+ }
+
+ result.block.dirty = true;
+
+ return ext4_dir_destroy_result(parent, &result);
}
int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
- struct ext4_block *target_block,
- struct ext4_inode_ref *child, const char *name,
- uint32_t name_len)
+ struct ext4_block *target_block,
+ struct ext4_inode_ref *child, const char *name,
+ uint32_t name_len)
{
- /* Compute required length entry and align it to 4 bytes */
- uint32_t block_size = ext4_sb_get_block_size(sb);
- uint16_t required_len = sizeof(struct ext4_fake_directory_entry) + name_len;
-
- if ((required_len % 4) != 0)
- required_len += 4 - (required_len % 4);
-
- /* Initialize pointers, stop means to upper bound */
- struct ext4_directory_entry_ll *dentry = (void *)target_block->data;
- struct ext4_directory_entry_ll *stop =
- (void *)(target_block->data + block_size);
-
- /*
- * Walk through the block and check for invalid entries
- * or entries with free space for new entry
- */
- while (dentry < stop) {
- uint32_t inode = ext4_dir_entry_ll_get_inode(dentry);
- uint16_t rec_len = ext4_dir_entry_ll_get_entry_length(dentry);
-
- /* If invalid and large enough entry, use it */
- if ((inode == 0) && (rec_len >= required_len)) {
- ext4_dir_write_entry(sb, dentry, rec_len, child, name, name_len);
- target_block->dirty = true;
-
- return EOK;
- }
-
- /* Valid entry, try to split it */
- if (inode != 0) {
- uint16_t used_name_len =
- ext4_dir_entry_ll_get_name_length(sb, dentry);
-
- uint16_t used_space =
- sizeof(struct ext4_fake_directory_entry) + used_name_len;
-
- if ((used_name_len % 4) != 0)
- used_space += 4 - (used_name_len % 4);
-
- uint16_t free_space = rec_len - used_space;
-
- /* There is free space for new entry */
- if (free_space >= required_len) {
- /* Cut tail of current entry */
- ext4_dir_entry_ll_set_entry_length(dentry, used_space);
- struct ext4_directory_entry_ll *new_entry =
- (void *)((uint8_t *)dentry + used_space);
- ext4_dir_write_entry(sb, new_entry, free_space, child, name,
- name_len);
-
- target_block->dirty = true;
- return EOK;
- }
- }
-
- /* Jump to the next entry */
- dentry = (void *)((uint8_t *)dentry + rec_len);
- }
-
- /* No free space found for new entry */
- return ENOSPC;
+ /* Compute required length entry and align it to 4 bytes */
+ uint32_t block_size = ext4_sb_get_block_size(sb);
+ uint16_t required_len =
+ sizeof(struct ext4_fake_directory_entry) + name_len;
+
+ if ((required_len % 4) != 0)
+ required_len += 4 - (required_len % 4);
+
+ /* Initialize pointers, stop means to upper bound */
+ struct ext4_directory_entry_ll *dentry = (void *)target_block->data;
+ struct ext4_directory_entry_ll *stop =
+ (void *)(target_block->data + block_size);
+
+ /*
+ * Walk through the block and check for invalid entries
+ * or entries with free space for new entry
+ */
+ while (dentry < stop) {
+ uint32_t inode = ext4_dir_entry_ll_get_inode(dentry);
+ uint16_t rec_len = ext4_dir_entry_ll_get_entry_length(dentry);
+
+ /* If invalid and large enough entry, use it */
+ if ((inode == 0) && (rec_len >= required_len)) {
+ ext4_dir_write_entry(sb, dentry, rec_len, child, name,
+ name_len);
+ target_block->dirty = true;
+
+ return EOK;
+ }
+
+ /* Valid entry, try to split it */
+ if (inode != 0) {
+ uint16_t used_name_len =
+ ext4_dir_entry_ll_get_name_length(sb, dentry);
+
+ uint16_t used_space =
+ sizeof(struct ext4_fake_directory_entry) +
+ used_name_len;
+
+ if ((used_name_len % 4) != 0)
+ used_space += 4 - (used_name_len % 4);
+
+ uint16_t free_space = rec_len - used_space;
+
+ /* There is free space for new entry */
+ if (free_space >= required_len) {
+ /* Cut tail of current entry */
+ ext4_dir_entry_ll_set_entry_length(dentry,
+ used_space);
+ struct ext4_directory_entry_ll *new_entry =
+ (void *)((uint8_t *)dentry + used_space);
+ ext4_dir_write_entry(sb, new_entry, free_space,
+ child, name, name_len);
+
+ target_block->dirty = true;
+ return EOK;
+ }
+ }
+
+ /* Jump to the next entry */
+ dentry = (void *)((uint8_t *)dentry + rec_len);
+ }
+
+ /* No free space found for new entry */
+ return ENOSPC;
}
int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
- size_t name_len, const char *name,
- struct ext4_directory_entry_ll **res_entry)
+ size_t name_len, const char *name,
+ struct ext4_directory_entry_ll **res_entry)
{
- /* Start from the first entry in block */
- struct ext4_directory_entry_ll *dentry =
- (struct ext4_directory_entry_ll *)block->data;
-
- /* Set upper bound for cycling */
- uint8_t *addr_limit = block->data + ext4_sb_get_block_size(sb);
-
- /* Walk through the block and check entries */
- while ((uint8_t *)dentry < addr_limit) {
- /* Termination condition */
- if ((uint8_t *)dentry + name_len > addr_limit)
- break;
-
- /* Valid entry - check it */
- if (dentry->inode != 0) {
- /* For more efficient compare only lengths firstly*/
- if (ext4_dir_entry_ll_get_name_length(sb, dentry) == name_len) {
- /* Compare names */
- if (memcmp((uint8_t *)name, dentry->name, name_len) == 0) {
- *res_entry = dentry;
- return EOK;
- }
- }
- }
-
- uint16_t dentry_len = ext4_dir_entry_ll_get_entry_length(dentry);
-
- /* Corrupted entry */
- if (dentry_len == 0)
- return EINVAL;
-
- /* Jump to next entry */
- dentry =
- (struct ext4_directory_entry_ll *)((uint8_t *)dentry + dentry_len);
- }
-
- /* Entry not found */
- return ENOENT;
+ /* Start from the first entry in block */
+ struct ext4_directory_entry_ll *dentry =
+ (struct ext4_directory_entry_ll *)block->data;
+
+ /* Set upper bound for cycling */
+ uint8_t *addr_limit = block->data + ext4_sb_get_block_size(sb);
+
+ /* Walk through the block and check entries */
+ while ((uint8_t *)dentry < addr_limit) {
+ /* Termination condition */
+ if ((uint8_t *)dentry + name_len > addr_limit)
+ break;
+
+ /* Valid entry - check it */
+ if (dentry->inode != 0) {
+ /* For more efficient compare only lengths firstly*/
+ if (ext4_dir_entry_ll_get_name_length(sb, dentry) ==
+ name_len) {
+ /* Compare names */
+ if (memcmp((uint8_t *)name, dentry->name,
+ name_len) == 0) {
+ *res_entry = dentry;
+ return EOK;
+ }
+ }
+ }
+
+ uint16_t dentry_len =
+ ext4_dir_entry_ll_get_entry_length(dentry);
+
+ /* Corrupted entry */
+ if (dentry_len == 0)
+ return EINVAL;
+
+ /* Jump to next entry */
+ dentry = (struct ext4_directory_entry_ll *)((uint8_t *)dentry +
+ dentry_len);
+ }
+
+ /* Entry not found */
+ return ENOENT;
}
int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
- struct ext4_directory_search_result *result)
+ struct ext4_directory_search_result *result)
{
- if (result->block.lb_id)
- return ext4_block_set(parent->fs->bdev, &result->block);
+ if (result->block.lb_id)
+ return ext4_block_set(parent->fs->bdev, &result->block);
- return EOK;
+ return EOK;
}
/**
diff --git a/lwext4/ext4_dir.h b/lwext4/ext4_dir.h index 15ca85e..d185a0b 100644 --- a/lwext4/ext4_dir.h +++ b/lwext4/ext4_dir.h @@ -56,7 +56,7 @@ static inline uint32_t
ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de)
{
- return to_le32(de->inode);
+ return to_le32(de->inode);
}
/**@brief Set i-node number to directory entry.
@@ -66,7 +66,7 @@ ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de) static inline void
ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de, uint32_t inode)
{
- de->inode = to_le32(inode);
+ de->inode = to_le32(inode);
}
/**@brief Get directory entry length.
@@ -76,7 +76,7 @@ ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de, uint32_t inode) static inline uint16_t
ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de)
{
- return to_le16(de->entry_length);
+ return to_le16(de->entry_length);
}
/**@brief Set directory entry length.
@@ -85,9 +85,9 @@ ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de) */
static inline void
ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de,
- uint16_t len)
+ uint16_t len)
{
- de->entry_length = to_le16(len);
+ de->entry_length = to_le16(len);
}
/**@brief Get directory entry name length.
@@ -97,15 +97,15 @@ ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de, */
static inline uint16_t
ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb,
- struct ext4_directory_entry_ll *de)
+ struct ext4_directory_entry_ll *de)
{
- uint16_t v = de->name_length;
+ uint16_t v = de->name_length;
- if ((ext4_get32(sb, rev_level) == 0) &&
- (ext4_get32(sb, minor_rev_level) < 5))
- v |= ((uint16_t)de->in.name_length_high) << 8;
+ if ((ext4_get32(sb, rev_level) == 0) &&
+ (ext4_get32(sb, minor_rev_level) < 5))
+ v |= ((uint16_t)de->in.name_length_high) << 8;
- return v;
+ return v;
}
/**@brief Set directory entry name length.
@@ -116,11 +116,11 @@ ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb, static inline void ext4_dir_entry_ll_set_name_length(
struct ext4_sblock *sb, struct ext4_directory_entry_ll *de, uint16_t len)
{
- de->name_length = (len << 8) >> 8;
+ de->name_length = (len << 8) >> 8;
- if ((ext4_get32(sb, rev_level) == 0) &&
- (ext4_get32(sb, minor_rev_level) < 5))
- de->in.name_length_high = len >> 8;
+ if ((ext4_get32(sb, rev_level) == 0) &&
+ (ext4_get32(sb, minor_rev_level) < 5))
+ de->in.name_length_high = len >> 8;
}
/**@brief Get i-node type of directory entry.
@@ -130,13 +130,13 @@ static inline void ext4_dir_entry_ll_set_name_length( */
static inline uint8_t
ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb,
- struct ext4_directory_entry_ll *de)
+ struct ext4_directory_entry_ll *de)
{
- if ((ext4_get32(sb, rev_level) > 0) ||
- (ext4_get32(sb, minor_rev_level) >= 5))
- return de->in.inode_type;
+ if ((ext4_get32(sb, rev_level) > 0) ||
+ (ext4_get32(sb, minor_rev_level) >= 5))
+ return de->in.inode_type;
- return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
+ return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
}
/**@brief Set i-node type of directory entry.
* @param sb Superblock
@@ -147,9 +147,9 @@ ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb, static inline void ext4_dir_entry_ll_set_inode_type(
struct ext4_sblock *sb, struct ext4_directory_entry_ll *de, uint8_t type)
{
- if ((ext4_get32(sb, rev_level) > 0) ||
- (ext4_get32(sb, minor_rev_level) >= 5))
- de->in.inode_type = type;
+ if ((ext4_get32(sb, rev_level) > 0) ||
+ (ext4_get32(sb, minor_rev_level) >= 5))
+ de->in.inode_type = type;
}
/**@brief Initialize directory iterator.
@@ -160,7 +160,7 @@ static inline void ext4_dir_entry_ll_set_inode_type( * @return Error code
*/
int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
- struct ext4_inode_ref *inode_ref, uint64_t pos);
+ struct ext4_inode_ref *inode_ref, uint64_t pos);
/**@brief Jump to the next valid entry
* @param it Initialized iterator
@@ -184,9 +184,9 @@ int ext4_dir_iterator_fini(struct ext4_directory_iterator *it); * @param name_len Length of entry name
*/
void ext4_dir_write_entry(struct ext4_sblock *sb,
- struct ext4_directory_entry_ll *entry,
- uint16_t entry_len, struct ext4_inode_ref *child,
- const char *name, size_t name_len);
+ struct ext4_directory_entry_ll *entry,
+ uint16_t entry_len, struct ext4_inode_ref *child,
+ const char *name, size_t name_len);
/**@brief Add new entry to the directory.
* @param parent Directory i-node
@@ -195,7 +195,7 @@ void ext4_dir_write_entry(struct ext4_sblock *sb, * @return Error code
*/
int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
- uint32_t name_len, struct ext4_inode_ref *child);
+ uint32_t name_len, struct ext4_inode_ref *child);
/**@brief Find directory entry with passed name.
* @param result Result structure to be returned if entry found
@@ -205,8 +205,8 @@ int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name, * @return Error code
*/
int ext4_dir_find_entry(struct ext4_directory_search_result *result,
- struct ext4_inode_ref *parent, const char *name,
- uint32_t name_len);
+ struct ext4_inode_ref *parent, const char *name,
+ uint32_t name_len);
/**@brief Remove directory entry.
* @param parent Directory i-node
@@ -215,7 +215,7 @@ int ext4_dir_find_entry(struct ext4_directory_search_result *result, * @return Error code
*/
int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
- uint32_t name_len);
+ uint32_t name_len);
/**@brief Try to insert entry to concrete data block.
* @param sb Superblock
@@ -226,9 +226,9 @@ int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name, * @return Error code
*/
int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
- struct ext4_block *target_block,
- struct ext4_inode_ref *child, const char *name,
- uint32_t name_len);
+ struct ext4_block *target_block,
+ struct ext4_inode_ref *child, const char *name,
+ uint32_t name_len);
/**@brief Try to find entry in block by name.
* @param block Block containing entries
@@ -239,8 +239,8 @@ int ext4_dir_try_insert_entry(struct ext4_sblock *sb, * @return Error code
*/
int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
- size_t name_len, const char *name,
- struct ext4_directory_entry_ll **res_entry);
+ size_t name_len, const char *name,
+ struct ext4_directory_entry_ll **res_entry);
/**@brief Simple function to release allocated data from result.
* @param parent Parent inode
@@ -249,7 +249,7 @@ int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb, *
*/
int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
- struct ext4_directory_search_result *result);
+ struct ext4_directory_search_result *result);
#endif /* EXT4_DIR_H_ */
diff --git a/lwext4/ext4_dir_idx.c b/lwext4/ext4_dir_idx.c index b35bb63..5f9fc44 100644 --- a/lwext4/ext4_dir_idx.c +++ b/lwext4/ext4_dir_idx.c @@ -52,7 +52,7 @@ static inline uint8_t ext4_dir_dx_root_info_get_hash_version(
struct ext4_directory_dx_root_info *root_info)
{
- return root_info->hash_version;
+ return root_info->hash_version;
}
/**@brief Set hash version, that will be used in directory index.
@@ -62,7 +62,7 @@ static inline uint8_t ext4_dir_dx_root_info_get_hash_version( static inline void ext4_dir_dx_root_info_set_hash_version(
struct ext4_directory_dx_root_info *root_info, uint8_t v)
{
- root_info->hash_version = v;
+ root_info->hash_version = v;
}
/**@brief Get length of root_info structure in bytes.
@@ -72,7 +72,7 @@ static inline void ext4_dir_dx_root_info_set_hash_version( static inline uint8_t ext4_dir_dx_root_info_get_info_length(
struct ext4_directory_dx_root_info *root_info)
{
- return root_info->info_length;
+ return root_info->info_length;
}
/**@brief Set length of root_info structure in bytes.
@@ -82,7 +82,7 @@ static inline uint8_t ext4_dir_dx_root_info_get_info_length( static inline void ext4_dir_dx_root_info_set_info_length(
struct ext4_directory_dx_root_info *root_info, uint8_t len)
{
- root_info->info_length = len;
+ root_info->info_length = len;
}
/**@brief Get number of indirect levels of HTree.
@@ -92,7 +92,7 @@ static inline void ext4_dir_dx_root_info_set_info_length( static inline uint8_t ext4_dir_dx_root_info_get_indirect_levels(
struct ext4_directory_dx_root_info *root_info)
{
- return root_info->indirect_levels;
+ return root_info->indirect_levels;
}
/**@brief Set number of indirect levels of HTree.
@@ -102,7 +102,7 @@ static inline uint8_t ext4_dir_dx_root_info_get_indirect_levels( static inline void ext4_dir_dx_root_info_set_indirect_levels(
struct ext4_directory_dx_root_info *root_info, uint8_t lvl)
{
- root_info->indirect_levels = lvl;
+ root_info->indirect_levels = lvl;
}
/**@brief Get maximum number of index node entries.
@@ -112,7 +112,7 @@ static inline void ext4_dir_dx_root_info_set_indirect_levels( static inline uint16_t
ext4_dir_dx_countlimit_get_limit(struct ext4_directory_dx_countlimit *climit)
{
- return to_le16(climit->limit);
+ return to_le16(climit->limit);
}
/**@brief Set maximum number of index node entries.
@@ -121,9 +121,9 @@ ext4_dir_dx_countlimit_get_limit(struct ext4_directory_dx_countlimit *climit) */
static inline void
ext4_dir_dx_countlimit_set_limit(struct ext4_directory_dx_countlimit *climit,
- uint16_t limit)
+ uint16_t limit)
{
- climit->limit = to_le16(limit);
+ climit->limit = to_le16(limit);
}
/**@brief Get current number of index node entries.
@@ -133,7 +133,7 @@ ext4_dir_dx_countlimit_set_limit(struct ext4_directory_dx_countlimit *climit, static inline uint16_t
ext4_dir_dx_countlimit_get_count(struct ext4_directory_dx_countlimit *climit)
{
- return to_le16(climit->count);
+ return to_le16(climit->count);
}
/**@brief Set current number of index node entries.
@@ -142,9 +142,9 @@ ext4_dir_dx_countlimit_get_count(struct ext4_directory_dx_countlimit *climit) */
static inline void
ext4_dir_dx_countlimit_set_count(struct ext4_directory_dx_countlimit *climit,
- uint16_t count)
+ uint16_t count)
{
- climit->count = to_le16(count);
+ climit->count = to_le16(count);
}
/**@brief Get hash value of index entry.
@@ -154,7 +154,7 @@ ext4_dir_dx_countlimit_set_count(struct ext4_directory_dx_countlimit *climit, static inline uint32_t
ext4_dir_dx_entry_get_hash(struct ext4_directory_dx_entry *entry)
{
- return to_le32(entry->hash);
+ return to_le32(entry->hash);
}
/**@brief Set hash value of index entry.
@@ -164,7 +164,7 @@ ext4_dir_dx_entry_get_hash(struct ext4_directory_dx_entry *entry) static inline void
ext4_dir_dx_entry_set_hash(struct ext4_directory_dx_entry *entry, uint32_t hash)
{
- entry->hash = to_le32(hash);
+ entry->hash = to_le32(hash);
}
/**@brief Get block address where child node is located.
@@ -174,7 +174,7 @@ ext4_dir_dx_entry_set_hash(struct ext4_directory_dx_entry *entry, uint32_t hash) static inline uint32_t
ext4_dir_dx_entry_get_block(struct ext4_directory_dx_entry *entry)
{
- return to_le32(entry->block);
+ return to_le32(entry->block);
}
/**@brief Set block address where child node is located.
@@ -183,100 +183,101 @@ ext4_dir_dx_entry_get_block(struct ext4_directory_dx_entry *entry) */
static inline void
ext4_dir_dx_entry_set_block(struct ext4_directory_dx_entry *entry,
- uint32_t block)
+ uint32_t block)
{
- entry->block = to_le32(block);
+ entry->block = to_le32(block);
}
/**@brief Sort entry item.*/
struct ext4_dx_sort_entry {
- uint32_t hash;
- uint32_t rec_len;
- void *dentry;
+ uint32_t hash;
+ uint32_t rec_len;
+ void *dentry;
};
static int ext4_dir_dx_hash_string(struct ext4_hash_info *hinfo, int len,
- const char *name)
+ const char *name)
{
- return ext2_htree_hash(name, len, hinfo->seed, hinfo->hash_version,
- &hinfo->hash, &hinfo->minor_hash);
+ return ext2_htree_hash(name, len, hinfo->seed, hinfo->hash_version,
+ &hinfo->hash, &hinfo->minor_hash);
}
/****************************************************************************/
int ext4_dir_dx_init(struct ext4_inode_ref *dir)
{
- /* Load block 0, where will be index root located */
- uint32_t fblock;
- int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock);
- if (rc != EOK)
- return rc;
-
- struct ext4_block block;
- rc = ext4_block_get(dir->fs->bdev, &block, fblock);
- if (rc != EOK)
- return rc;
-
- /* Initialize pointers to data structures */
- struct ext4_directory_dx_root *root = (void *)block.data;
- struct ext4_directory_dx_root_info *info = &(root->info);
-
- /* Initialize root info structure */
- uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version);
-
- ext4_dir_dx_root_info_set_hash_version(info, hash_version);
- ext4_dir_dx_root_info_set_indirect_levels(info, 0);
- ext4_dir_dx_root_info_set_info_length(info, 8);
-
- /* Set limit and current number of entries */
- struct ext4_directory_dx_countlimit *countlimit =
- (struct ext4_directory_dx_countlimit *)&root->entries;
-
- ext4_dir_dx_countlimit_set_count(countlimit, 1);
-
- uint32_t block_size = ext4_sb_get_block_size(&dir->fs->sb);
- uint32_t entry_space = block_size -
- 2 * sizeof(struct ext4_directory_dx_dot_entry) -
- sizeof(struct ext4_directory_dx_root_info);
- uint16_t root_limit = entry_space / sizeof(struct ext4_directory_dx_entry);
- ext4_dir_dx_countlimit_set_limit(countlimit, root_limit);
-
- /* Append new block, where will be new entries inserted in the future */
- uint32_t iblock;
- rc = ext4_fs_append_inode_block(dir, &fblock, &iblock);
- if (rc != EOK) {
- ext4_block_set(dir->fs->bdev, &block);
- return rc;
- }
-
- struct ext4_block new_block;
-
- rc = ext4_block_get(dir->fs->bdev, &new_block, fblock);
- if (rc != EOK) {
- ext4_block_set(dir->fs->bdev, &block);
- return rc;
- }
-
- /* Fill the whole block with empty entry */
- struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
-
- ext4_dir_entry_ll_set_entry_length(block_entry, block_size);
- ext4_dir_entry_ll_set_inode(block_entry, 0);
-
- new_block.dirty = true;
- rc = ext4_block_set(dir->fs->bdev, &new_block);
- if (rc != EOK) {
- ext4_block_set(dir->fs->bdev, &block);
- return rc;
- }
-
- /* Connect new block to the only entry in index */
- struct ext4_directory_dx_entry *entry = root->entries;
- ext4_dir_dx_entry_set_block(entry, iblock);
-
- block.dirty = true;
-
- return ext4_block_set(dir->fs->bdev, &block);
+ /* Load block 0, where will be index root located */
+ uint32_t fblock;
+ int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_block block;
+ rc = ext4_block_get(dir->fs->bdev, &block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Initialize pointers to data structures */
+ struct ext4_directory_dx_root *root = (void *)block.data;
+ struct ext4_directory_dx_root_info *info = &(root->info);
+
+ /* Initialize root info structure */
+ uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version);
+
+ ext4_dir_dx_root_info_set_hash_version(info, hash_version);
+ ext4_dir_dx_root_info_set_indirect_levels(info, 0);
+ ext4_dir_dx_root_info_set_info_length(info, 8);
+
+ /* Set limit and current number of entries */
+ struct ext4_directory_dx_countlimit *countlimit =
+ (struct ext4_directory_dx_countlimit *)&root->entries;
+
+ ext4_dir_dx_countlimit_set_count(countlimit, 1);
+
+ uint32_t block_size = ext4_sb_get_block_size(&dir->fs->sb);
+ uint32_t entry_space = block_size -
+ 2 * sizeof(struct ext4_directory_dx_dot_entry) -
+ sizeof(struct ext4_directory_dx_root_info);
+ uint16_t root_limit =
+ entry_space / sizeof(struct ext4_directory_dx_entry);
+ ext4_dir_dx_countlimit_set_limit(countlimit, root_limit);
+
+ /* Append new block, where will be new entries inserted in the future */
+ uint32_t iblock;
+ rc = ext4_fs_append_inode_block(dir, &fblock, &iblock);
+ if (rc != EOK) {
+ ext4_block_set(dir->fs->bdev, &block);
+ return rc;
+ }
+
+ struct ext4_block new_block;
+
+ rc = ext4_block_get(dir->fs->bdev, &new_block, fblock);
+ if (rc != EOK) {
+ ext4_block_set(dir->fs->bdev, &block);
+ return rc;
+ }
+
+ /* Fill the whole block with empty entry */
+ struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
+
+ ext4_dir_entry_ll_set_entry_length(block_entry, block_size);
+ ext4_dir_entry_ll_set_inode(block_entry, 0);
+
+ new_block.dirty = true;
+ rc = ext4_block_set(dir->fs->bdev, &new_block);
+ if (rc != EOK) {
+ ext4_block_set(dir->fs->bdev, &block);
+ return rc;
+ }
+
+ /* Connect new block to the only entry in index */
+ struct ext4_directory_dx_entry *entry = root->entries;
+ ext4_dir_dx_entry_set_block(entry, iblock);
+
+ block.dirty = true;
+
+ return ext4_block_set(dir->fs->bdev, &block);
}
/**@brief Initialize hash info structure necessary for index operations.
@@ -288,55 +289,56 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) * @return Standard error code
*/
static int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo,
- struct ext4_block *root_block,
- struct ext4_sblock *sb, size_t name_len,
- const char *name)
+ struct ext4_block *root_block,
+ struct ext4_sblock *sb, size_t name_len,
+ const char *name)
{
- struct ext4_directory_dx_root *root =
- (struct ext4_directory_dx_root *)root_block->data;
-
- if ((root->info.hash_version != EXT2_HTREE_LEGACY) &&
- (root->info.hash_version != EXT2_HTREE_HALF_MD4) &&
- (root->info.hash_version != EXT2_HTREE_TEA))
- return EXT4_ERR_BAD_DX_DIR;
-
- /* Check unused flags */
- if (root->info.unused_flags != 0)
- return EXT4_ERR_BAD_DX_DIR;
-
- /* Check indirect levels */
- if (root->info.indirect_levels > 1)
- return EXT4_ERR_BAD_DX_DIR;
-
- /* Check if node limit is correct */
- uint32_t block_size = ext4_sb_get_block_size(sb);
- uint32_t entry_space = block_size;
- entry_space -= 2 * sizeof(struct ext4_directory_dx_dot_entry);
- entry_space -= sizeof(struct ext4_directory_dx_root_info);
- entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
-
- uint16_t limit = ext4_dir_dx_countlimit_get_limit(
- (struct ext4_directory_dx_countlimit *)&root->entries);
- if (limit != entry_space)
- return EXT4_ERR_BAD_DX_DIR;
-
- /* Check hash version and modify if necessary */
- hinfo->hash_version = ext4_dir_dx_root_info_get_hash_version(&root->info);
- if ((hinfo->hash_version <= EXT2_HTREE_TEA) &&
- (ext4_sb_check_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
- /* Use unsigned hash */
- hinfo->hash_version += 3;
- }
-
- /* Load hash seed from superblock */
-
- hinfo->seed = ext4_get8(sb, hash_seed);
-
- /* Compute hash value of name */
- if (name)
- return ext4_dir_dx_hash_string(hinfo, name_len, name);
-
- return EOK;
+ struct ext4_directory_dx_root *root =
+ (struct ext4_directory_dx_root *)root_block->data;
+
+ if ((root->info.hash_version != EXT2_HTREE_LEGACY) &&
+ (root->info.hash_version != EXT2_HTREE_HALF_MD4) &&
+ (root->info.hash_version != EXT2_HTREE_TEA))
+ return EXT4_ERR_BAD_DX_DIR;
+
+ /* Check unused flags */
+ if (root->info.unused_flags != 0)
+ return EXT4_ERR_BAD_DX_DIR;
+
+ /* Check indirect levels */
+ if (root->info.indirect_levels > 1)
+ return EXT4_ERR_BAD_DX_DIR;
+
+ /* Check if node limit is correct */
+ uint32_t block_size = ext4_sb_get_block_size(sb);
+ uint32_t entry_space = block_size;
+ entry_space -= 2 * sizeof(struct ext4_directory_dx_dot_entry);
+ entry_space -= sizeof(struct ext4_directory_dx_root_info);
+ entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
+
+ uint16_t limit = ext4_dir_dx_countlimit_get_limit(
+ (struct ext4_directory_dx_countlimit *)&root->entries);
+ if (limit != entry_space)
+ return EXT4_ERR_BAD_DX_DIR;
+
+ /* Check hash version and modify if necessary */
+ hinfo->hash_version =
+ ext4_dir_dx_root_info_get_hash_version(&root->info);
+ if ((hinfo->hash_version <= EXT2_HTREE_TEA) &&
+ (ext4_sb_check_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
+ /* Use unsigned hash */
+ hinfo->hash_version += 3;
+ }
+
+ /* Load hash seed from superblock */
+
+ hinfo->seed = ext4_get8(sb, hash_seed);
+
+ /* Compute hash value of name */
+ if (name)
+ return ext4_dir_dx_hash_string(hinfo, name_len, name);
+
+ return EOK;
}
/**@brief Walk through index tree and load leaf with corresponding hash value.
@@ -348,95 +350,99 @@ static int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo, * @return Standard error code
*/
static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo,
- struct ext4_inode_ref *inode_ref,
- struct ext4_block *root_block,
- struct ext4_directory_dx_block **dx_block,
- struct ext4_directory_dx_block *dx_blocks)
+ struct ext4_inode_ref *inode_ref,
+ struct ext4_block *root_block,
+ struct ext4_directory_dx_block **dx_block,
+ struct ext4_directory_dx_block *dx_blocks)
{
- struct ext4_directory_dx_block *tmp_dx_block = dx_blocks;
- struct ext4_directory_dx_root *root =
- (struct ext4_directory_dx_root *)root_block->data;
- struct ext4_directory_dx_entry *entries =
- (struct ext4_directory_dx_entry *)&root->entries;
-
- uint16_t limit = ext4_dir_dx_countlimit_get_limit(
- (struct ext4_directory_dx_countlimit *)entries);
- uint8_t indirect_level =
- ext4_dir_dx_root_info_get_indirect_levels(&root->info);
-
- struct ext4_block *tmp_block = root_block;
- struct ext4_directory_dx_entry *p;
- struct ext4_directory_dx_entry *q;
- struct ext4_directory_dx_entry *m;
- struct ext4_directory_dx_entry *at;
-
- /* Walk through the index tree */
- while (true) {
- uint16_t count = ext4_dir_dx_countlimit_get_count(
- (struct ext4_directory_dx_countlimit *)entries);
- if ((count == 0) || (count > limit))
- return EXT4_ERR_BAD_DX_DIR;
-
- /* Do binary search in every node */
- p = entries + 1;
- q = entries + count - 1;
-
- while (p <= q) {
- m = p + (q - p) / 2;
- if (ext4_dir_dx_entry_get_hash(m) > hinfo->hash)
- q = m - 1;
- else
- p = m + 1;
- }
-
- at = p - 1;
-
- /* Write results */
-
- memcpy(&tmp_dx_block->block, tmp_block, sizeof(struct ext4_block));
- tmp_dx_block->entries = entries;
- tmp_dx_block->position = at;
-
- /* Is algorithm in the leaf? */
- if (indirect_level == 0) {
- *dx_block = tmp_dx_block;
- return EOK;
- }
-
- /* Goto child node */
- uint32_t next_block = ext4_dir_dx_entry_get_block(at);
-
- indirect_level--;
-
- uint32_t fblock;
- int rc =
- ext4_fs_get_inode_data_block_index(inode_ref, next_block, &fblock);
- if (rc != EOK)
- return rc;
-
- rc = ext4_block_get(inode_ref->fs->bdev, tmp_block, fblock);
- if (rc != EOK)
- return rc;
-
- entries = ((struct ext4_directory_dx_node *)tmp_block->data)->entries;
- limit = ext4_dir_dx_countlimit_get_limit(
- (struct ext4_directory_dx_countlimit *)entries);
-
- uint16_t entry_space = ext4_sb_get_block_size(&inode_ref->fs->sb) -
- sizeof(struct ext4_fake_directory_entry);
-
- entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
-
- if (limit != entry_space) {
- ext4_block_set(inode_ref->fs->bdev, tmp_block);
- return EXT4_ERR_BAD_DX_DIR;
- }
-
- ++tmp_dx_block;
- }
-
- /* Unreachable */
- return EOK;
+ struct ext4_directory_dx_block *tmp_dx_block = dx_blocks;
+ struct ext4_directory_dx_root *root =
+ (struct ext4_directory_dx_root *)root_block->data;
+ struct ext4_directory_dx_entry *entries =
+ (struct ext4_directory_dx_entry *)&root->entries;
+
+ uint16_t limit = ext4_dir_dx_countlimit_get_limit(
+ (struct ext4_directory_dx_countlimit *)entries);
+ uint8_t indirect_level =
+ ext4_dir_dx_root_info_get_indirect_levels(&root->info);
+
+ struct ext4_block *tmp_block = root_block;
+ struct ext4_directory_dx_entry *p;
+ struct ext4_directory_dx_entry *q;
+ struct ext4_directory_dx_entry *m;
+ struct ext4_directory_dx_entry *at;
+
+ /* Walk through the index tree */
+ while (true) {
+ uint16_t count = ext4_dir_dx_countlimit_get_count(
+ (struct ext4_directory_dx_countlimit *)entries);
+ if ((count == 0) || (count > limit))
+ return EXT4_ERR_BAD_DX_DIR;
+
+ /* Do binary search in every node */
+ p = entries + 1;
+ q = entries + count - 1;
+
+ while (p <= q) {
+ m = p + (q - p) / 2;
+ if (ext4_dir_dx_entry_get_hash(m) > hinfo->hash)
+ q = m - 1;
+ else
+ p = m + 1;
+ }
+
+ at = p - 1;
+
+ /* Write results */
+
+ memcpy(&tmp_dx_block->block, tmp_block,
+ sizeof(struct ext4_block));
+ tmp_dx_block->entries = entries;
+ tmp_dx_block->position = at;
+
+ /* Is algorithm in the leaf? */
+ if (indirect_level == 0) {
+ *dx_block = tmp_dx_block;
+ return EOK;
+ }
+
+ /* Goto child node */
+ uint32_t next_block = ext4_dir_dx_entry_get_block(at);
+
+ indirect_level--;
+
+ uint32_t fblock;
+ int rc = ext4_fs_get_inode_data_block_index(
+ inode_ref, next_block, &fblock);
+ if (rc != EOK)
+ return rc;
+
+ rc = ext4_block_get(inode_ref->fs->bdev, tmp_block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ entries =
+ ((struct ext4_directory_dx_node *)tmp_block->data)->entries;
+ limit = ext4_dir_dx_countlimit_get_limit(
+ (struct ext4_directory_dx_countlimit *)entries);
+
+ uint16_t entry_space =
+ ext4_sb_get_block_size(&inode_ref->fs->sb) -
+ sizeof(struct ext4_fake_directory_entry);
+
+ entry_space =
+ entry_space / sizeof(struct ext4_directory_dx_entry);
+
+ if (limit != entry_space) {
+ ext4_block_set(inode_ref->fs->bdev, tmp_block);
+ return EXT4_ERR_BAD_DX_DIR;
+ }
+
+ ++tmp_dx_block;
+ }
+
+ /* Unreachable */
+ return EOK;
}
/**@brief Check if the the next block would be checked during entry search.
@@ -447,200 +453,203 @@ static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo, * @return Standard Error code
*/
static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref,
- uint32_t hash,
- struct ext4_directory_dx_block *dx_block,
- struct ext4_directory_dx_block *dx_blocks)
+ uint32_t hash,
+ struct ext4_directory_dx_block *dx_block,
+ struct ext4_directory_dx_block *dx_blocks)
{
- uint32_t num_handles = 0;
- struct ext4_directory_dx_block *p = dx_block;
-
- /* Try to find data block with next bunch of entries */
- while (true) {
- p->position++;
- uint16_t count = ext4_dir_dx_countlimit_get_count(
- (struct ext4_directory_dx_countlimit *)p->entries);
-
- if (p->position < p->entries + count)
- break;
-
- if (p == dx_blocks)
- return EOK;
-
- num_handles++;
- p--;
- }
-
- /* Check hash collision (if not occurred - no next block cannot be used)*/
- uint32_t current_hash = ext4_dir_dx_entry_get_hash(p->position);
- if ((hash & 1) == 0) {
- if ((current_hash & ~1) != hash)
- return 0;
- }
-
- /* Fill new path */
- while (num_handles--) {
- uint32_t block_idx = ext4_dir_dx_entry_get_block(p->position);
- uint32_t block_addr;
-
- int rc = ext4_fs_get_inode_data_block_index(inode_ref, block_idx,
- &block_addr);
- if (rc != EOK)
- return rc;
-
- struct ext4_block block;
- rc = ext4_block_get(inode_ref->fs->bdev, &block, block_addr);
- if (rc != EOK)
- return rc;
-
- p++;
-
- /* Don't forget to put old block (prevent memory leak) */
- rc = ext4_block_set(inode_ref->fs->bdev, &p->block);
- if (rc != EOK)
- return rc;
-
- memcpy(&p->block, &p->block, sizeof(block));
- p->entries = ((struct ext4_directory_dx_node *)block.data)->entries;
- p->position = p->entries;
- }
-
- return ENOENT;
+ uint32_t num_handles = 0;
+ struct ext4_directory_dx_block *p = dx_block;
+
+ /* Try to find data block with next bunch of entries */
+ while (true) {
+ p->position++;
+ uint16_t count = ext4_dir_dx_countlimit_get_count(
+ (struct ext4_directory_dx_countlimit *)p->entries);
+
+ if (p->position < p->entries + count)
+ break;
+
+ if (p == dx_blocks)
+ return EOK;
+
+ num_handles++;
+ p--;
+ }
+
+ /* Check hash collision (if not occurred - no next block cannot be
+ * used)*/
+ uint32_t current_hash = ext4_dir_dx_entry_get_hash(p->position);
+ if ((hash & 1) == 0) {
+ if ((current_hash & ~1) != hash)
+ return 0;
+ }
+
+ /* Fill new path */
+ while (num_handles--) {
+ uint32_t block_idx = ext4_dir_dx_entry_get_block(p->position);
+ uint32_t block_addr;
+
+ int rc = ext4_fs_get_inode_data_block_index(
+ inode_ref, block_idx, &block_addr);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_block block;
+ rc = ext4_block_get(inode_ref->fs->bdev, &block, block_addr);
+ if (rc != EOK)
+ return rc;
+
+ p++;
+
+ /* Don't forget to put old block (prevent memory leak) */
+ rc = ext4_block_set(inode_ref->fs->bdev, &p->block);
+ if (rc != EOK)
+ return rc;
+
+ memcpy(&p->block, &p->block, sizeof(block));
+ p->entries =
+ ((struct ext4_directory_dx_node *)block.data)->entries;
+ p->position = p->entries;
+ }
+
+ return ENOENT;
}
int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result,
- struct ext4_inode_ref *inode_ref, size_t name_len,
- const char *name)
+ struct ext4_inode_ref *inode_ref, size_t name_len,
+ const char *name)
{
- /* Load direct block 0 (index root) */
- uint32_t root_block_addr;
- int rc2;
- int rc = ext4_fs_get_inode_data_block_index(inode_ref, 0, &root_block_addr);
- if (rc != EOK)
- return rc;
-
- struct ext4_fs *fs = inode_ref->fs;
-
- struct ext4_block root_block;
- rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
- if (rc != EOK)
- return rc;
-
- /* Initialize hash info (compute hash value) */
- struct ext4_hash_info hinfo;
- rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb, name_len, name);
- if (rc != EOK) {
- ext4_block_set(fs->bdev, &root_block);
- return EXT4_ERR_BAD_DX_DIR;
- }
-
- /*
- * Hardcoded number 2 means maximum height of index tree,
- * specified in the Linux driver.
- */
- struct ext4_directory_dx_block dx_blocks[2];
- struct ext4_directory_dx_block *dx_block;
- struct ext4_directory_dx_block *tmp;
-
- rc = ext4_dir_dx_get_leaf(&hinfo, inode_ref, &root_block, &dx_block,
- dx_blocks);
- if (rc != EOK) {
- ext4_block_set(fs->bdev, &root_block);
- return EXT4_ERR_BAD_DX_DIR;
- }
-
- do {
- /* Load leaf block */
- uint32_t leaf_block_idx =
- ext4_dir_dx_entry_get_block(dx_block->position);
- uint32_t leaf_block_addr;
-
- rc = ext4_fs_get_inode_data_block_index(inode_ref, leaf_block_idx,
- &leaf_block_addr);
- if (rc != EOK)
- goto cleanup;
-
- struct ext4_block leaf_block;
- rc = ext4_block_get(fs->bdev, &leaf_block, leaf_block_addr);
- if (rc != EOK)
- goto cleanup;
-
- /* Linear search inside block */
- struct ext4_directory_entry_ll *res_dentry;
- rc = ext4_dir_find_in_block(&leaf_block, &fs->sb, name_len, name,
- &res_dentry);
-
- /* Found => return it */
- if (rc == EOK) {
- result->block = leaf_block;
- result->dentry = res_dentry;
- goto cleanup;
- }
-
- /* Not found, leave untouched */
- rc2 = ext4_block_set(fs->bdev, &leaf_block);
- if (rc2 != EOK)
- goto cleanup;
-
- if (rc != ENOENT)
- goto cleanup;
-
- /* check if the next block could be checked */
- rc = ext4_dir_dx_next_block(inode_ref, hinfo.hash, dx_block,
- &dx_blocks[0]);
- if (rc < 0)
- goto cleanup;
- } while (rc == ENOENT);
-
- /* Entry not found */
- rc = ENOENT;
+ /* Load direct block 0 (index root) */
+ uint32_t root_block_addr;
+ int rc2;
+ int rc =
+ ext4_fs_get_inode_data_block_index(inode_ref, 0, &root_block_addr);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_fs *fs = inode_ref->fs;
+
+ struct ext4_block root_block;
+ rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
+ if (rc != EOK)
+ return rc;
+
+ /* Initialize hash info (compute hash value) */
+ struct ext4_hash_info hinfo;
+ rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb, name_len, name);
+ if (rc != EOK) {
+ ext4_block_set(fs->bdev, &root_block);
+ return EXT4_ERR_BAD_DX_DIR;
+ }
+
+ /*
+ * Hardcoded number 2 means maximum height of index tree,
+ * specified in the Linux driver.
+ */
+ struct ext4_directory_dx_block dx_blocks[2];
+ struct ext4_directory_dx_block *dx_block;
+ struct ext4_directory_dx_block *tmp;
+
+ rc = ext4_dir_dx_get_leaf(&hinfo, inode_ref, &root_block, &dx_block,
+ dx_blocks);
+ if (rc != EOK) {
+ ext4_block_set(fs->bdev, &root_block);
+ return EXT4_ERR_BAD_DX_DIR;
+ }
+
+ do {
+ /* Load leaf block */
+ uint32_t leaf_block_idx =
+ ext4_dir_dx_entry_get_block(dx_block->position);
+ uint32_t leaf_block_addr;
+
+ rc = ext4_fs_get_inode_data_block_index(
+ inode_ref, leaf_block_idx, &leaf_block_addr);
+ if (rc != EOK)
+ goto cleanup;
+
+ struct ext4_block leaf_block;
+ rc = ext4_block_get(fs->bdev, &leaf_block, leaf_block_addr);
+ if (rc != EOK)
+ goto cleanup;
+
+ /* Linear search inside block */
+ struct ext4_directory_entry_ll *res_dentry;
+ rc = ext4_dir_find_in_block(&leaf_block, &fs->sb, name_len,
+ name, &res_dentry);
+
+ /* Found => return it */
+ if (rc == EOK) {
+ result->block = leaf_block;
+ result->dentry = res_dentry;
+ goto cleanup;
+ }
+
+ /* Not found, leave untouched */
+ rc2 = ext4_block_set(fs->bdev, &leaf_block);
+ if (rc2 != EOK)
+ goto cleanup;
+
+ if (rc != ENOENT)
+ goto cleanup;
+
+ /* check if the next block could be checked */
+ rc = ext4_dir_dx_next_block(inode_ref, hinfo.hash, dx_block,
+ &dx_blocks[0]);
+ if (rc < 0)
+ goto cleanup;
+ } while (rc == ENOENT);
+
+ /* Entry not found */
+ rc = ENOENT;
cleanup:
- /* The whole path must be released (preventing memory leak) */
- tmp = dx_blocks;
+ /* The whole path must be released (preventing memory leak) */
+ tmp = dx_blocks;
- while (tmp <= dx_block) {
- rc2 = ext4_block_set(fs->bdev, &tmp->block);
- if (rc == EOK && rc2 != EOK)
- rc = rc2;
- ++tmp;
- }
+ while (tmp <= dx_block) {
+ rc2 = ext4_block_set(fs->bdev, &tmp->block);
+ if (rc == EOK && rc2 != EOK)
+ rc = rc2;
+ ++tmp;
+ }
- return rc;
+ return rc;
}
#if CONFIG_DIR_INDEX_COMB_SORT
#define SWAP_ENTRY(se1, se2) \
- do { \
- struct ext4_dx_sort_entry tmp = se1; \
- se1 = se2; \
- se2 = tmp; \
- \
+ do { \
+ struct ext4_dx_sort_entry tmp = se1; \
+ se1 = se2; \
+ se2 = tmp; \
+ \
} while (0)
static void comb_sort(struct ext4_dx_sort_entry *se, uint32_t count)
{
- struct ext4_dx_sort_entry *p, *q, *top = se + count - 1;
- bool more;
- /* Combsort */
- while (count > 2) {
- count = (count * 10) / 13;
- if (count - 9 < 2)
- count = 11;
- for (p = top, q = p - count; q >= se; p--, q--)
- if (p->hash < q->hash)
- SWAP_ENTRY(*p, *q);
- }
- /* Bubblesort */
- do {
- more = 0;
- q = top;
- while (q-- > se) {
- if (q[1].hash >= q[0].hash)
- continue;
- SWAP_ENTRY(*(q + 1), *q);
- more = 1;
- }
- } while (more);
+ struct ext4_dx_sort_entry *p, *q, *top = se + count - 1;
+ bool more;
+ /* Combsort */
+ while (count > 2) {
+ count = (count * 10) / 13;
+ if (count - 9 < 2)
+ count = 11;
+ for (p = top, q = p - count; q >= se; p--, q--)
+ if (p->hash < q->hash)
+ SWAP_ENTRY(*p, *q);
+ }
+ /* Bubblesort */
+ do {
+ more = 0;
+ q = top;
+ while (q-- > se) {
+ if (q[1].hash >= q[0].hash)
+ continue;
+ SWAP_ENTRY(*(q + 1), *q);
+ more = 1;
+ }
+ } while (more);
}
#else
@@ -655,16 +664,16 @@ static void comb_sort(struct ext4_dx_sort_entry *se, uint32_t count) */
static int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2)
{
- struct ext4_dx_sort_entry *entry1 = (void *)arg1;
- struct ext4_dx_sort_entry *entry2 = (void *)arg2;
+ struct ext4_dx_sort_entry *entry1 = (void *)arg1;
+ struct ext4_dx_sort_entry *entry2 = (void *)arg2;
- if (entry1->hash == entry2->hash)
- return 0;
+ if (entry1->hash == entry2->hash)
+ return 0;
- if (entry1->hash < entry2->hash)
- return -1;
- else
- return 1;
+ if (entry1->hash < entry2->hash)
+ return -1;
+ else
+ return 1;
}
#endif
@@ -677,27 +686,27 @@ static int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2) */
static void
ext4_dir_dx_insert_entry(struct ext4_directory_dx_block *index_block,
- uint32_t hash, uint32_t iblock)
+ uint32_t hash, uint32_t iblock)
{
- struct ext4_directory_dx_entry *old_index_entry = index_block->position;
- struct ext4_directory_dx_entry *new_index_entry = old_index_entry + 1;
+ struct ext4_directory_dx_entry *old_index_entry = index_block->position;
+ struct ext4_directory_dx_entry *new_index_entry = old_index_entry + 1;
- struct ext4_directory_dx_countlimit *countlimit =
- (struct ext4_directory_dx_countlimit *)index_block->entries;
- uint32_t count = ext4_dir_dx_countlimit_get_count(countlimit);
+ struct ext4_directory_dx_countlimit *countlimit =
+ (struct ext4_directory_dx_countlimit *)index_block->entries;
+ uint32_t count = ext4_dir_dx_countlimit_get_count(countlimit);
- struct ext4_directory_dx_entry *start_index = index_block->entries;
- size_t bytes =
- (uint8_t *)(start_index + count) - (uint8_t *)(new_index_entry);
+ struct ext4_directory_dx_entry *start_index = index_block->entries;
+ size_t bytes =
+ (uint8_t *)(start_index + count) - (uint8_t *)(new_index_entry);
- memmove(new_index_entry + 1, new_index_entry, bytes);
+ memmove(new_index_entry + 1, new_index_entry, bytes);
- ext4_dir_dx_entry_set_block(new_index_entry, iblock);
- ext4_dir_dx_entry_set_hash(new_index_entry, hash);
+ ext4_dir_dx_entry_set_block(new_index_entry, iblock);
+ ext4_dir_dx_entry_set_hash(new_index_entry, hash);
- ext4_dir_dx_countlimit_set_count(countlimit, count + 1);
+ ext4_dir_dx_countlimit_set_count(countlimit, count + 1);
- index_block->block.dirty = true;
+ index_block->block.dirty = true;
}
/**@brief Split directory entries to two parts preventing node overflow.
@@ -708,169 +717,176 @@ ext4_dir_dx_insert_entry(struct ext4_directory_dx_block *index_block, * @param new_data_block Output value for newly allocated data block
*/
static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref,
- struct ext4_hash_info *hinfo,
- struct ext4_block *old_data_block,
- struct ext4_directory_dx_block *index_block,
- struct ext4_block *new_data_block)
+ struct ext4_hash_info *hinfo,
+ struct ext4_block *old_data_block,
+ struct ext4_directory_dx_block *index_block,
+ struct ext4_block *new_data_block)
{
- int rc = EOK;
+ int rc = EOK;
- /* Allocate buffer for directory entries */
- uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
+ /* Allocate buffer for directory entries */
+ uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
- uint8_t *entry_buffer = malloc(block_size);
- if (entry_buffer == NULL)
- return ENOMEM;
+ uint8_t *entry_buffer = malloc(block_size);
+ if (entry_buffer == NULL)
+ return ENOMEM;
- /* dot entry has the smallest size available */
- uint32_t max_entry_count =
- block_size / sizeof(struct ext4_directory_dx_dot_entry);
+ /* dot entry has the smallest size available */
+ uint32_t max_entry_count =
+ block_size / sizeof(struct ext4_directory_dx_dot_entry);
- /* Allocate sort entry */
- struct ext4_dx_sort_entry *sort_array =
- malloc(max_entry_count * sizeof(struct ext4_dx_sort_entry));
+ /* Allocate sort entry */
+ struct ext4_dx_sort_entry *sort_array =
+ malloc(max_entry_count * sizeof(struct ext4_dx_sort_entry));
- if (sort_array == NULL) {
- free(entry_buffer);
- return ENOMEM;
- }
+ if (sort_array == NULL) {
+ free(entry_buffer);
+ return ENOMEM;
+ }
- uint32_t idx = 0;
- uint32_t real_size = 0;
+ uint32_t idx = 0;
+ uint32_t real_size = 0;
- /* Initialize hinfo */
- struct ext4_hash_info tmp_hinfo;
- memcpy(&tmp_hinfo, hinfo, sizeof(struct ext4_hash_info));
+ /* Initialize hinfo */
+ struct ext4_hash_info tmp_hinfo;
+ memcpy(&tmp_hinfo, hinfo, sizeof(struct ext4_hash_info));
- /* Load all valid entries to the buffer */
- struct ext4_directory_entry_ll *dentry = (void *)old_data_block->data;
- uint8_t *entry_buffer_ptr = entry_buffer;
- while ((void *)dentry < (void *)(old_data_block->data + block_size)) {
- /* Read only valid entries */
- if (ext4_dir_entry_ll_get_inode(dentry) && dentry->name_length) {
- uint8_t len =
- ext4_dir_entry_ll_get_name_length(&inode_ref->fs->sb, dentry);
+ /* Load all valid entries to the buffer */
+ struct ext4_directory_entry_ll *dentry = (void *)old_data_block->data;
+ uint8_t *entry_buffer_ptr = entry_buffer;
+ while ((void *)dentry < (void *)(old_data_block->data + block_size)) {
+ /* Read only valid entries */
+ if (ext4_dir_entry_ll_get_inode(dentry) &&
+ dentry->name_length) {
+ uint8_t len = ext4_dir_entry_ll_get_name_length(
+ &inode_ref->fs->sb, dentry);
- rc = ext4_dir_dx_hash_string(&tmp_hinfo, len, (char *)dentry->name);
- if (rc != EOK) {
- free(sort_array);
- free(entry_buffer);
- return rc;
- }
+ rc = ext4_dir_dx_hash_string(&tmp_hinfo, len,
+ (char *)dentry->name);
+ if (rc != EOK) {
+ free(sort_array);
+ free(entry_buffer);
+ return rc;
+ }
- uint32_t rec_len = 8 + len;
+ uint32_t rec_len = 8 + len;
- if ((rec_len % 4) != 0)
- rec_len += 4 - (rec_len % 4);
+ if ((rec_len % 4) != 0)
+ rec_len += 4 - (rec_len % 4);
- memcpy(entry_buffer_ptr, dentry, rec_len);
+ memcpy(entry_buffer_ptr, dentry, rec_len);
- sort_array[idx].dentry = entry_buffer_ptr;
- sort_array[idx].rec_len = rec_len;
- sort_array[idx].hash = tmp_hinfo.hash;
+ sort_array[idx].dentry = entry_buffer_ptr;
+ sort_array[idx].rec_len = rec_len;
+ sort_array[idx].hash = tmp_hinfo.hash;
- entry_buffer_ptr += rec_len;
- real_size += rec_len;
- idx++;
- }
+ entry_buffer_ptr += rec_len;
+ real_size += rec_len;
+ idx++;
+ }
- dentry = (void *)((uint8_t *)dentry +
- ext4_dir_entry_ll_get_entry_length(dentry));
- }
+ dentry = (void *)((uint8_t *)dentry +
+ ext4_dir_entry_ll_get_entry_length(dentry));
+ }
/* Sort all entries */
#if CONFIG_DIR_INDEX_COMB_SORT
- comb_sort(sort_array, idx);
+ comb_sort(sort_array, idx);
#else
- qsort(sort_array, idx, sizeof(struct ext4_dx_sort_entry),
- ext4_dir_dx_entry_comparator);
+ qsort(sort_array, idx, sizeof(struct ext4_dx_sort_entry),
+ ext4_dir_dx_entry_comparator);
#endif
- /* Allocate new block for store the second part of entries */
- uint32_t new_fblock;
- uint32_t new_iblock;
- rc = ext4_fs_append_inode_block(inode_ref, &new_fblock, &new_iblock);
- if (rc != EOK) {
- free(sort_array);
- free(entry_buffer);
- return rc;
- }
-
- /* Load new block */
- struct ext4_block new_data_block_tmp;
- rc = ext4_block_get(inode_ref->fs->bdev, &new_data_block_tmp, new_fblock);
- if (rc != EOK) {
- free(sort_array);
- free(entry_buffer);
- return rc;
- }
-
- /*
- * Distribute entries to two blocks (by size)
- * - compute the half
- */
- uint32_t new_hash = 0;
- uint32_t current_size = 0;
- uint32_t mid = 0;
- uint32_t i;
- for (i = 0; i < idx; ++i) {
- if ((current_size + sort_array[i].rec_len) > (block_size / 2)) {
- new_hash = sort_array[i].hash;
- mid = i;
- break;
- }
-
- current_size += sort_array[i].rec_len;
- }
-
- /* Check hash collision */
- uint32_t continued = 0;
- if (new_hash == sort_array[mid - 1].hash)
- continued = 1;
-
- uint32_t offset = 0;
- void *ptr;
-
- /* First part - to the old block */
- for (i = 0; i < mid; ++i) {
- ptr = old_data_block->data + offset;
- memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
-
- struct ext4_directory_entry_ll *tmp = ptr;
- if (i < (mid - 1))
- ext4_dir_entry_ll_set_entry_length(tmp, sort_array[i].rec_len);
- else
- ext4_dir_entry_ll_set_entry_length(tmp, block_size - offset);
-
- offset += sort_array[i].rec_len;
- }
-
- /* Second part - to the new block */
- offset = 0;
- for (i = mid; i < idx; ++i) {
- ptr = new_data_block_tmp.data + offset;
- memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
-
- struct ext4_directory_entry_ll *tmp = ptr;
- if (i < (idx - 1))
- ext4_dir_entry_ll_set_entry_length(tmp, sort_array[i].rec_len);
- else
- ext4_dir_entry_ll_set_entry_length(tmp, block_size - offset);
-
- offset += sort_array[i].rec_len;
- }
-
- /* Do some steps to finish operation */
- old_data_block->dirty = true;
- new_data_block_tmp.dirty = true;
-
- free(sort_array);
- free(entry_buffer);
-
- ext4_dir_dx_insert_entry(index_block, new_hash + continued, new_iblock);
-
- *new_data_block = new_data_block_tmp;
-
- return EOK;
+ /* Allocate new block for store the second part of entries */
+ uint32_t new_fblock;
+ uint32_t new_iblock;
+ rc = ext4_fs_append_inode_block(inode_ref, &new_fblock, &new_iblock);
+ if (rc != EOK) {
+ free(sort_array);
+ free(entry_buffer);
+ return rc;
+ }
+
+ /* Load new block */
+ struct ext4_block new_data_block_tmp;
+ rc = ext4_block_get(inode_ref->fs->bdev, &new_data_block_tmp,
+ new_fblock);
+ if (rc != EOK) {
+ free(sort_array);
+ free(entry_buffer);
+ return rc;
+ }
+
+ /*
+ * Distribute entries to two blocks (by size)
+ * - compute the half
+ */
+ uint32_t new_hash = 0;
+ uint32_t current_size = 0;
+ uint32_t mid = 0;
+ uint32_t i;
+ for (i = 0; i < idx; ++i) {
+ if ((current_size + sort_array[i].rec_len) > (block_size / 2)) {
+ new_hash = sort_array[i].hash;
+ mid = i;
+ break;
+ }
+
+ current_size += sort_array[i].rec_len;
+ }
+
+ /* Check hash collision */
+ uint32_t continued = 0;
+ if (new_hash == sort_array[mid - 1].hash)
+ continued = 1;
+
+ uint32_t offset = 0;
+ void *ptr;
+
+ /* First part - to the old block */
+ for (i = 0; i < mid; ++i) {
+ ptr = old_data_block->data + offset;
+ memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
+
+ struct ext4_directory_entry_ll *tmp = ptr;
+ if (i < (mid - 1))
+ ext4_dir_entry_ll_set_entry_length(
+ tmp, sort_array[i].rec_len);
+ else
+ ext4_dir_entry_ll_set_entry_length(tmp,
+ block_size - offset);
+
+ offset += sort_array[i].rec_len;
+ }
+
+ /* Second part - to the new block */
+ offset = 0;
+ for (i = mid; i < idx; ++i) {
+ ptr = new_data_block_tmp.data + offset;
+ memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
+
+ struct ext4_directory_entry_ll *tmp = ptr;
+ if (i < (idx - 1))
+ ext4_dir_entry_ll_set_entry_length(
+ tmp, sort_array[i].rec_len);
+ else
+ ext4_dir_entry_ll_set_entry_length(tmp,
+ block_size - offset);
+
+ offset += sort_array[i].rec_len;
+ }
+
+ /* Do some steps to finish operation */
+ old_data_block->dirty = true;
+ new_data_block_tmp.dirty = true;
+
+ free(sort_array);
+ free(entry_buffer);
+
+ ext4_dir_dx_insert_entry(index_block, new_hash + continued, new_iblock);
+
+ *new_data_block = new_data_block_tmp;
+
+ return EOK;
}
/**@brief Split index node and maybe some parent nodes in the tree hierarchy.
@@ -881,271 +897,300 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, */
static int
ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref,
- struct ext4_directory_dx_block *dx_blocks,
- struct ext4_directory_dx_block *dx_block,
- struct ext4_directory_dx_block **new_dx_block)
+ struct ext4_directory_dx_block *dx_blocks,
+ struct ext4_directory_dx_block *dx_block,
+ struct ext4_directory_dx_block **new_dx_block)
{
- struct ext4_directory_dx_entry *entries;
-
- if (dx_block == dx_blocks)
- entries =
- ((struct ext4_directory_dx_root *)dx_block->block.data)->entries;
- else
- entries =
- ((struct ext4_directory_dx_node *)dx_block->block.data)->entries;
-
- struct ext4_directory_dx_countlimit *countlimit =
- (struct ext4_directory_dx_countlimit *)entries;
-
- uint16_t leaf_limit = ext4_dir_dx_countlimit_get_limit(countlimit);
- uint16_t leaf_count = ext4_dir_dx_countlimit_get_count(countlimit);
-
- /* Check if is necessary to split index block */
- if (leaf_limit == leaf_count) {
- size_t levels = dx_block - dx_blocks;
-
- struct ext4_directory_dx_entry *root_entries =
- ((struct ext4_directory_dx_root *)dx_blocks[0].block.data)->entries;
-
- struct ext4_directory_dx_countlimit *root_countlimit =
- (struct ext4_directory_dx_countlimit *)root_entries;
- uint16_t root_limit = ext4_dir_dx_countlimit_get_limit(root_countlimit);
- uint16_t root_count = ext4_dir_dx_countlimit_get_count(root_countlimit);
-
- /* Linux limitation */
- if ((levels > 0) && (root_limit == root_count))
- return ENOSPC;
-
- /* Add new block to directory */
- uint32_t new_fblock;
- uint32_t new_iblock;
- int rc =
- ext4_fs_append_inode_block(inode_ref, &new_fblock, &new_iblock);
- if (rc != EOK)
- return rc;
-
- /* load new block */
- struct ext4_block new_block;
- rc = ext4_block_get(inode_ref->fs->bdev, &new_block, new_fblock);
- if (rc != EOK)
- return rc;
-
- struct ext4_directory_dx_node *new_node = (void *)new_block.data;
- struct ext4_directory_dx_entry *new_entries = new_node->entries;
-
- memset(&new_node->fake, 0, sizeof(struct ext4_fake_directory_entry));
-
- uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
-
- new_node->fake.entry_length = block_size;
-
- /* Split leaf node */
- if (levels > 0) {
- uint32_t count_left = leaf_count / 2;
- uint32_t count_right = leaf_count - count_left;
- uint32_t hash_right =
- ext4_dir_dx_entry_get_hash(entries + count_left);
-
- /* Copy data to new node */
- memcpy((void *)new_entries, (void *)(entries + count_left),
- count_right * sizeof(struct ext4_directory_dx_entry));
-
- /* Initialize new node */
- struct ext4_directory_dx_countlimit *left_countlimit =
- (struct ext4_directory_dx_countlimit *)entries;
- struct ext4_directory_dx_countlimit *right_countlimit =
- (struct ext4_directory_dx_countlimit *)new_entries;
-
- ext4_dir_dx_countlimit_set_count(left_countlimit, count_left);
- ext4_dir_dx_countlimit_set_count(right_countlimit, count_right);
-
- uint32_t entry_space =
- block_size - sizeof(struct ext4_fake_directory_entry);
- uint32_t node_limit =
- entry_space / sizeof(struct ext4_directory_dx_entry);
- ext4_dir_dx_countlimit_set_limit(right_countlimit, node_limit);
-
- /* Which index block is target for new entry */
- uint32_t position_index = (dx_block->position - dx_block->entries);
- if (position_index >= count_left) {
- dx_block->block.dirty = true;
-
- struct ext4_block block_tmp = dx_block->block;
-
- dx_block->block = new_block;
-
- dx_block->position = new_entries + position_index - count_left;
- dx_block->entries = new_entries;
-
- new_block = block_tmp;
- }
-
- /* Finally insert new entry */
- ext4_dir_dx_insert_entry(dx_blocks, hash_right, new_iblock);
- dx_blocks[0].block.dirty = true;
- dx_blocks[1].block.dirty = true;
-
- new_block.dirty = true;
- return ext4_block_set(inode_ref->fs->bdev, &new_block);
- } else {
- /* Create second level index */
-
- /* Copy data from root to child block */
- memcpy((void *)new_entries, (void *)entries,
- leaf_count * sizeof(struct ext4_directory_dx_entry));
-
- struct ext4_directory_dx_countlimit *new_countlimit =
- (struct ext4_directory_dx_countlimit *)new_entries;
-
- uint32_t entry_space =
- block_size - sizeof(struct ext4_fake_directory_entry);
- uint32_t node_limit =
- entry_space / sizeof(struct ext4_directory_dx_entry);
- ext4_dir_dx_countlimit_set_limit(new_countlimit, node_limit);
-
- /* Set values in root node */
- struct ext4_directory_dx_countlimit *new_root_countlimit =
- (struct ext4_directory_dx_countlimit *)entries;
-
- ext4_dir_dx_countlimit_set_count(new_root_countlimit, 1);
- ext4_dir_dx_entry_set_block(entries, new_iblock);
-
- ((struct ext4_directory_dx_root *)dx_blocks[0].block.data)
- ->info.indirect_levels = 1;
-
- /* Add new entry to the path */
- dx_block = dx_blocks + 1;
- dx_block->position = dx_blocks->position - entries + new_entries;
- dx_block->entries = new_entries;
- dx_block->block = new_block;
-
- *new_dx_block = dx_block;
-
- dx_blocks[0].block.dirty = true;
- dx_blocks[1].block.dirty = true;
- }
- }
-
- return EOK;
+ struct ext4_directory_dx_entry *entries;
+
+ if (dx_block == dx_blocks)
+ entries =
+ ((struct ext4_directory_dx_root *)dx_block->block.data)
+ ->entries;
+ else
+ entries =
+ ((struct ext4_directory_dx_node *)dx_block->block.data)
+ ->entries;
+
+ struct ext4_directory_dx_countlimit *countlimit =
+ (struct ext4_directory_dx_countlimit *)entries;
+
+ uint16_t leaf_limit = ext4_dir_dx_countlimit_get_limit(countlimit);
+ uint16_t leaf_count = ext4_dir_dx_countlimit_get_count(countlimit);
+
+ /* Check if is necessary to split index block */
+ if (leaf_limit == leaf_count) {
+ size_t levels = dx_block - dx_blocks;
+
+ struct ext4_directory_dx_entry *root_entries =
+ ((struct ext4_directory_dx_root *)dx_blocks[0].block.data)
+ ->entries;
+
+ struct ext4_directory_dx_countlimit *root_countlimit =
+ (struct ext4_directory_dx_countlimit *)root_entries;
+ uint16_t root_limit =
+ ext4_dir_dx_countlimit_get_limit(root_countlimit);
+ uint16_t root_count =
+ ext4_dir_dx_countlimit_get_count(root_countlimit);
+
+ /* Linux limitation */
+ if ((levels > 0) && (root_limit == root_count))
+ return ENOSPC;
+
+ /* Add new block to directory */
+ uint32_t new_fblock;
+ uint32_t new_iblock;
+ int rc = ext4_fs_append_inode_block(inode_ref, &new_fblock,
+ &new_iblock);
+ if (rc != EOK)
+ return rc;
+
+ /* load new block */
+ struct ext4_block new_block;
+ rc =
+ ext4_block_get(inode_ref->fs->bdev, &new_block, new_fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_directory_dx_node *new_node =
+ (void *)new_block.data;
+ struct ext4_directory_dx_entry *new_entries = new_node->entries;
+
+ memset(&new_node->fake, 0,
+ sizeof(struct ext4_fake_directory_entry));
+
+ uint32_t block_size =
+ ext4_sb_get_block_size(&inode_ref->fs->sb);
+
+ new_node->fake.entry_length = block_size;
+
+ /* Split leaf node */
+ if (levels > 0) {
+ uint32_t count_left = leaf_count / 2;
+ uint32_t count_right = leaf_count - count_left;
+ uint32_t hash_right =
+ ext4_dir_dx_entry_get_hash(entries + count_left);
+
+ /* Copy data to new node */
+ memcpy((void *)new_entries,
+ (void *)(entries + count_left),
+ count_right *
+ sizeof(struct ext4_directory_dx_entry));
+
+ /* Initialize new node */
+ struct ext4_directory_dx_countlimit *left_countlimit =
+ (struct ext4_directory_dx_countlimit *)entries;
+ struct ext4_directory_dx_countlimit *right_countlimit =
+ (struct ext4_directory_dx_countlimit *)new_entries;
+
+ ext4_dir_dx_countlimit_set_count(left_countlimit,
+ count_left);
+ ext4_dir_dx_countlimit_set_count(right_countlimit,
+ count_right);
+
+ uint32_t entry_space =
+ block_size -
+ sizeof(struct ext4_fake_directory_entry);
+ uint32_t node_limit =
+ entry_space /
+ sizeof(struct ext4_directory_dx_entry);
+ ext4_dir_dx_countlimit_set_limit(right_countlimit,
+ node_limit);
+
+ /* Which index block is target for new entry */
+ uint32_t position_index =
+ (dx_block->position - dx_block->entries);
+ if (position_index >= count_left) {
+ dx_block->block.dirty = true;
+
+ struct ext4_block block_tmp = dx_block->block;
+
+ dx_block->block = new_block;
+
+ dx_block->position =
+ new_entries + position_index - count_left;
+ dx_block->entries = new_entries;
+
+ new_block = block_tmp;
+ }
+
+ /* Finally insert new entry */
+ ext4_dir_dx_insert_entry(dx_blocks, hash_right,
+ new_iblock);
+ dx_blocks[0].block.dirty = true;
+ dx_blocks[1].block.dirty = true;
+
+ new_block.dirty = true;
+ return ext4_block_set(inode_ref->fs->bdev, &new_block);
+ } else {
+ /* Create second level index */
+
+ /* Copy data from root to child block */
+ memcpy((void *)new_entries, (void *)entries,
+ leaf_count *
+ sizeof(struct ext4_directory_dx_entry));
+
+ struct ext4_directory_dx_countlimit *new_countlimit =
+ (struct ext4_directory_dx_countlimit *)new_entries;
+
+ uint32_t entry_space =
+ block_size -
+ sizeof(struct ext4_fake_directory_entry);
+ uint32_t node_limit =
+ entry_space /
+ sizeof(struct ext4_directory_dx_entry);
+ ext4_dir_dx_countlimit_set_limit(new_countlimit,
+ node_limit);
+
+ /* Set values in root node */
+ struct ext4_directory_dx_countlimit
+ *new_root_countlimit =
+ (struct ext4_directory_dx_countlimit *)entries;
+
+ ext4_dir_dx_countlimit_set_count(new_root_countlimit,
+ 1);
+ ext4_dir_dx_entry_set_block(entries, new_iblock);
+
+ ((struct ext4_directory_dx_root *)dx_blocks[0]
+ .block.data)
+ ->info.indirect_levels = 1;
+
+ /* Add new entry to the path */
+ dx_block = dx_blocks + 1;
+ dx_block->position =
+ dx_blocks->position - entries + new_entries;
+ dx_block->entries = new_entries;
+ dx_block->block = new_block;
+
+ *new_dx_block = dx_block;
+
+ dx_blocks[0].block.dirty = true;
+ dx_blocks[1].block.dirty = true;
+ }
+ }
+
+ return EOK;
}
int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
- struct ext4_inode_ref *child, const char *name)
+ struct ext4_inode_ref *child, const char *name)
{
- int rc2 = EOK;
-
- /* Get direct block 0 (index root) */
- uint32_t root_block_addr;
- int rc = ext4_fs_get_inode_data_block_index(parent, 0, &root_block_addr);
- if (rc != EOK)
- return rc;
-
- struct ext4_fs *fs = parent->fs;
- struct ext4_block root_block;
-
- rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
- if (rc != EOK)
- return rc;
-
- /* Initialize hinfo structure (mainly compute hash) */
- uint32_t name_len = strlen(name);
- struct ext4_hash_info hinfo;
- rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb, name_len, name);
- if (rc != EOK) {
- ext4_block_set(fs->bdev, &root_block);
- return EXT4_ERR_BAD_DX_DIR;
- }
-
- /*
- * Hardcoded number 2 means maximum height of index
- * tree defined in Linux.
- */
- struct ext4_directory_dx_block dx_blocks[2];
- struct ext4_directory_dx_block *dx_block;
- struct ext4_directory_dx_block *dx_it;
-
- rc =
- ext4_dir_dx_get_leaf(&hinfo, parent, &root_block, &dx_block, dx_blocks);
- if (rc != EOK) {
- rc = EXT4_ERR_BAD_DX_DIR;
- goto release_index;
- }
-
- /* Try to insert to existing data block */
- uint32_t leaf_block_idx = ext4_dir_dx_entry_get_block(dx_block->position);
- uint32_t leaf_block_addr;
- rc = ext4_fs_get_inode_data_block_index(parent, leaf_block_idx,
- &leaf_block_addr);
- if (rc != EOK)
- goto release_index;
-
- /*
- * Check if there is needed to split index node
- * (and recursively also parent nodes)
- */
- rc = ext4_dir_dx_split_index(parent, dx_blocks, dx_block, &dx_block);
- if (rc != EOK)
- goto release_target_index;
-
- struct ext4_block target_block;
- rc = ext4_block_get(fs->bdev, &target_block, leaf_block_addr);
- if (rc != EOK)
- goto release_index;
-
- /* Check if insert operation passed */
- rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child, name,
- name_len);
- if (rc == EOK)
- goto release_target_index;
-
- /* Split entries to two blocks (includes sorting by hash value) */
- struct ext4_block new_block;
- rc = ext4_dir_dx_split_data(parent, &hinfo, &target_block, dx_block,
- &new_block);
- if (rc != EOK) {
- rc2 = rc;
- goto release_target_index;
- }
-
- /* Where to save new entry */
- uint32_t new_block_hash =
- ext4_dir_dx_entry_get_hash(dx_block->position + 1);
- if (hinfo.hash >= new_block_hash)
- rc = ext4_dir_try_insert_entry(&fs->sb, &new_block, child, name,
- name_len);
- else
- rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child, name,
- name_len);
-
- /* Cleanup */
- rc = ext4_block_set(fs->bdev, &new_block);
- if (rc != EOK)
- return rc;
+ int rc2 = EOK;
+
+ /* Get direct block 0 (index root) */
+ uint32_t root_block_addr;
+ int rc =
+ ext4_fs_get_inode_data_block_index(parent, 0, &root_block_addr);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_fs *fs = parent->fs;
+ struct ext4_block root_block;
+
+ rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
+ if (rc != EOK)
+ return rc;
+
+ /* Initialize hinfo structure (mainly compute hash) */
+ uint32_t name_len = strlen(name);
+ struct ext4_hash_info hinfo;
+ rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb, name_len, name);
+ if (rc != EOK) {
+ ext4_block_set(fs->bdev, &root_block);
+ return EXT4_ERR_BAD_DX_DIR;
+ }
+
+ /*
+ * Hardcoded number 2 means maximum height of index
+ * tree defined in Linux.
+ */
+ struct ext4_directory_dx_block dx_blocks[2];
+ struct ext4_directory_dx_block *dx_block;
+ struct ext4_directory_dx_block *dx_it;
+
+ rc = ext4_dir_dx_get_leaf(&hinfo, parent, &root_block, &dx_block,
+ dx_blocks);
+ if (rc != EOK) {
+ rc = EXT4_ERR_BAD_DX_DIR;
+ goto release_index;
+ }
+
+ /* Try to insert to existing data block */
+ uint32_t leaf_block_idx =
+ ext4_dir_dx_entry_get_block(dx_block->position);
+ uint32_t leaf_block_addr;
+ rc = ext4_fs_get_inode_data_block_index(parent, leaf_block_idx,
+ &leaf_block_addr);
+ if (rc != EOK)
+ goto release_index;
+
+ /*
+ * Check if there is needed to split index node
+ * (and recursively also parent nodes)
+ */
+ rc = ext4_dir_dx_split_index(parent, dx_blocks, dx_block, &dx_block);
+ if (rc != EOK)
+ goto release_target_index;
+
+ struct ext4_block target_block;
+ rc = ext4_block_get(fs->bdev, &target_block, leaf_block_addr);
+ if (rc != EOK)
+ goto release_index;
+
+ /* Check if insert operation passed */
+ rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child, name,
+ name_len);
+ if (rc == EOK)
+ goto release_target_index;
+
+ /* Split entries to two blocks (includes sorting by hash value) */
+ struct ext4_block new_block;
+ rc = ext4_dir_dx_split_data(parent, &hinfo, &target_block, dx_block,
+ &new_block);
+ if (rc != EOK) {
+ rc2 = rc;
+ goto release_target_index;
+ }
+
+ /* Where to save new entry */
+ uint32_t new_block_hash =
+ ext4_dir_dx_entry_get_hash(dx_block->position + 1);
+ if (hinfo.hash >= new_block_hash)
+ rc = ext4_dir_try_insert_entry(&fs->sb, &new_block, child, name,
+ name_len);
+ else
+ rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child,
+ name, name_len);
+
+ /* Cleanup */
+ rc = ext4_block_set(fs->bdev, &new_block);
+ if (rc != EOK)
+ return rc;
/* Cleanup operations */
release_target_index:
- rc2 = rc;
+ rc2 = rc;
- rc = ext4_block_set(fs->bdev, &target_block);
- if (rc != EOK)
- return rc;
+ rc = ext4_block_set(fs->bdev, &target_block);
+ if (rc != EOK)
+ return rc;
release_index:
- if (rc != EOK)
- rc2 = rc;
+ if (rc != EOK)
+ rc2 = rc;
- dx_it = dx_blocks;
+ dx_it = dx_blocks;
- while (dx_it <= dx_block) {
- rc = ext4_block_set(fs->bdev, &dx_it->block);
- if (rc != EOK)
- return rc;
+ while (dx_it <= dx_block) {
+ rc = ext4_block_set(fs->bdev, &dx_it->block);
+ if (rc != EOK)
+ return rc;
- dx_it++;
- }
+ dx_it++;
+ }
- return rc2;
+ return rc2;
}
/**
diff --git a/lwext4/ext4_dir_idx.h b/lwext4/ext4_dir_idx.h index bb901db..ab61ee8 100644 --- a/lwext4/ext4_dir_idx.h +++ b/lwext4/ext4_dir_idx.h @@ -63,8 +63,8 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir); * @return Error code
*/
int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result,
- struct ext4_inode_ref *inode_ref, size_t name_len,
- const char *name);
+ struct ext4_inode_ref *inode_ref, size_t name_len,
+ const char *name);
/**@brief Add new entry to indexed directory
* @param parent Directory i-node
@@ -73,7 +73,7 @@ int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result, * @return Error code
*/
int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
- struct ext4_inode_ref *child, const char *name);
+ struct ext4_inode_ref *child, const char *name);
#endif /* EXT4_DIR_IDX_H_ */
diff --git a/lwext4/ext4_extent.c b/lwext4/ext4_extent.c index 9b86a5c..27a751d 100644 --- a/lwext4/ext4_extent.c +++ b/lwext4/ext4_extent.c @@ -51,114 +51,114 @@ uint32_t ext4_extent_get_first_block(struct ext4_extent *extent)
{
- return to_le32(extent->first_block);
+ return to_le32(extent->first_block);
}
void ext4_extent_set_first_block(struct ext4_extent *extent, uint32_t iblock)
{
- extent->first_block = to_le32(iblock);
+ extent->first_block = to_le32(iblock);
}
uint16_t ext4_extent_get_block_count(struct ext4_extent *extent)
{
- return to_le16(extent->block_count);
+ return to_le16(extent->block_count);
}
void ext4_extent_set_block_count(struct ext4_extent *extent, uint16_t count)
{
- extent->block_count = to_le16(count);
+ extent->block_count = to_le16(count);
}
uint64_t ext4_extent_get_start(struct ext4_extent *extent)
{
- return ((uint64_t)to_le16(extent->start_hi)) << 32 |
- ((uint64_t)to_le32(extent->start_lo));
+ return ((uint64_t)to_le16(extent->start_hi)) << 32 |
+ ((uint64_t)to_le32(extent->start_lo));
}
void ext4_extent_set_start(struct ext4_extent *extent, uint64_t fblock)
{
- extent->start_lo = to_le32((fblock << 32) >> 32);
- extent->start_hi = to_le16((uint16_t)(fblock >> 32));
+ extent->start_lo = to_le32((fblock << 32) >> 32);
+ extent->start_hi = to_le16((uint16_t)(fblock >> 32));
}
uint32_t ext4_extent_index_get_first_block(struct ext4_extent_index *index)
{
- return to_le32(index->first_block);
+ return to_le32(index->first_block);
}
void ext4_extent_index_set_first_block(struct ext4_extent_index *index,
- uint32_t iblock)
+ uint32_t iblock)
{
- index->first_block = to_le32(iblock);
+ index->first_block = to_le32(iblock);
}
uint64_t ext4_extent_index_get_leaf(struct ext4_extent_index *index)
{
- return ((uint64_t)to_le16(index->leaf_hi)) << 32 |
- ((uint64_t)to_le32(index->leaf_lo));
+ return ((uint64_t)to_le16(index->leaf_hi)) << 32 |
+ ((uint64_t)to_le32(index->leaf_lo));
}
void ext4_extent_index_set_leaf(struct ext4_extent_index *index,
- uint64_t fblock)
+ uint64_t fblock)
{
- index->leaf_lo = to_le32((fblock << 32) >> 32);
- index->leaf_hi = to_le16((uint16_t)(fblock >> 32));
+ index->leaf_lo = to_le32((fblock << 32) >> 32);
+ index->leaf_hi = to_le16((uint16_t)(fblock >> 32));
}
uint16_t ext4_extent_header_get_magic(struct ext4_extent_header *header)
{
- return to_le16(header->magic);
+ return to_le16(header->magic);
}
void ext4_extent_header_set_magic(struct ext4_extent_header *header,
- uint16_t magic)
+ uint16_t magic)
{
- header->magic = to_le16(magic);
+ header->magic = to_le16(magic);
}
uint16_t ext4_extent_header_get_entries_count(struct ext4_extent_header *header)
{
- return to_le16(header->entries_count);
+ return to_le16(header->entries_count);
}
void ext4_extent_header_set_entries_count(struct ext4_extent_header *header,
- uint16_t count)
+ uint16_t count)
{
- header->entries_count = to_le16(count);
+ header->entries_count = to_le16(count);
}
uint16_t
ext4_extent_header_get_max_entries_count(struct ext4_extent_header *header)
{
- return to_le16(header->max_entries_count);
+ return to_le16(header->max_entries_count);
}
void ext4_extent_header_set_max_entries_count(struct ext4_extent_header *header,
- uint16_t max_count)
+ uint16_t max_count)
{
- header->max_entries_count = to_le16(max_count);
+ header->max_entries_count = to_le16(max_count);
}
uint16_t ext4_extent_header_get_depth(struct ext4_extent_header *header)
{
- return to_le16(header->depth);
+ return to_le16(header->depth);
}
void ext4_extent_header_set_depth(struct ext4_extent_header *header,
- uint16_t depth)
+ uint16_t depth)
{
- header->depth = to_le16(depth);
+ header->depth = to_le16(depth);
}
uint32_t ext4_extent_header_get_generation(struct ext4_extent_header *header)
{
- return to_le32(header->generation);
+ return to_le32(header->generation);
}
void ext4_extent_header_set_generation(struct ext4_extent_header *header,
- uint32_t generation)
+ uint32_t generation)
{
- header->generation = to_le32(generation);
+ header->generation = to_le32(generation);
}
/**@brief Binary search in extent index node.
@@ -166,32 +166,32 @@ void ext4_extent_header_set_generation(struct ext4_extent_header *header, * @param index Output value - found index will be set here
* @param iblock Logical block number to find in index node */
static void ext4_extent_binsearch_idx(struct ext4_extent_header *header,
- struct ext4_extent_index **index,
- uint32_t iblock)
+ struct ext4_extent_index **index,
+ uint32_t iblock)
{
- struct ext4_extent_index *r;
- struct ext4_extent_index *l;
- struct ext4_extent_index *m;
+ struct ext4_extent_index *r;
+ struct ext4_extent_index *l;
+ struct ext4_extent_index *m;
- uint16_t entries_count = ext4_extent_header_get_entries_count(header);
+ uint16_t entries_count = ext4_extent_header_get_entries_count(header);
- /* Initialize bounds */
- l = EXT4_EXTENT_FIRST_INDEX(header) + 1;
- r = EXT4_EXTENT_FIRST_INDEX(header) + entries_count - 1;
+ /* Initialize bounds */
+ l = EXT4_EXTENT_FIRST_INDEX(header) + 1;
+ r = EXT4_EXTENT_FIRST_INDEX(header) + entries_count - 1;
- /* Do binary search */
- while (l <= r) {
- m = l + (r - l) / 2;
- uint32_t first_block = ext4_extent_index_get_first_block(m);
+ /* Do binary search */
+ while (l <= r) {
+ m = l + (r - l) / 2;
+ uint32_t first_block = ext4_extent_index_get_first_block(m);
- if (iblock < first_block)
- r = m - 1;
- else
- l = m + 1;
- }
+ if (iblock < first_block)
+ r = m - 1;
+ else
+ l = m + 1;
+ }
- /* Set output value */
- *index = l - 1;
+ /* Set output value */
+ *index = l - 1;
}
/**@brief Binary search in extent leaf node.
@@ -200,109 +200,109 @@ static void ext4_extent_binsearch_idx(struct ext4_extent_header *header, * or NULL if node is empty
* @param iblock Logical block number to find in leaf node */
static void ext4_extent_binsearch(struct ext4_extent_header *header,
- struct ext4_extent **extent, uint32_t iblock)
+ struct ext4_extent **extent, uint32_t iblock)
{
- struct ext4_extent *r;
- struct ext4_extent *l;
- struct ext4_extent *m;
-
- uint16_t entries_count = ext4_extent_header_get_entries_count(header);
-
- if (entries_count == 0) {
- /* this leaf is empty */
- *extent = NULL;
- return;
- }
-
- /* Initialize bounds */
- l = EXT4_EXTENT_FIRST(header) + 1;
- r = EXT4_EXTENT_FIRST(header) + entries_count - 1;
-
- /* Do binary search */
- while (l <= r) {
- m = l + (r - l) / 2;
- uint32_t first_block = ext4_extent_get_first_block(m);
-
- if (iblock < first_block)
- r = m - 1;
- else
- l = m + 1;
- }
-
- /* Set output value */
- *extent = l - 1;
+ struct ext4_extent *r;
+ struct ext4_extent *l;
+ struct ext4_extent *m;
+
+ uint16_t entries_count = ext4_extent_header_get_entries_count(header);
+
+ if (entries_count == 0) {
+ /* this leaf is empty */
+ *extent = NULL;
+ return;
+ }
+
+ /* Initialize bounds */
+ l = EXT4_EXTENT_FIRST(header) + 1;
+ r = EXT4_EXTENT_FIRST(header) + entries_count - 1;
+
+ /* Do binary search */
+ while (l <= r) {
+ m = l + (r - l) / 2;
+ uint32_t first_block = ext4_extent_get_first_block(m);
+
+ if (iblock < first_block)
+ r = m - 1;
+ else
+ l = m + 1;
+ }
+
+ /* Set output value */
+ *extent = l - 1;
}
int ext4_extent_find_block(struct ext4_inode_ref *inode_ref, uint32_t iblock,
- uint32_t *fblock)
+ uint32_t *fblock)
{
- int rc;
- /* Compute bound defined by i-node size */
- uint64_t inode_size =
- ext4_inode_get_size(&inode_ref->fs->sb, inode_ref->inode);
-
- uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
-
- uint32_t last_idx = (inode_size - 1) / block_size;
-
- /* Check if requested iblock is not over size of i-node */
- if (iblock > last_idx) {
- *fblock = 0;
- return EOK;
- }
-
- struct ext4_block block;
- block.lb_id = 0;
-
- /* Walk through extent tree */
- struct ext4_extent_header *header =
- ext4_inode_get_extent_header(inode_ref->inode);
-
- while (ext4_extent_header_get_depth(header) != 0) {
- /* Search index in node */
- struct ext4_extent_index *index;
- ext4_extent_binsearch_idx(header, &index, iblock);
-
- /* Load child node and set values for the next iteration */
- uint64_t child = ext4_extent_index_get_leaf(index);
-
- if (block.lb_id) {
- rc = ext4_block_set(inode_ref->fs->bdev, &block);
- if (rc != EOK)
- return rc;
- }
-
- int rc = ext4_block_get(inode_ref->fs->bdev, &block, child);
- if (rc != EOK)
- return rc;
-
- header = (struct ext4_extent_header *)block.data;
- }
-
- /* Search extent in the leaf block */
- struct ext4_extent *extent = NULL;
- ext4_extent_binsearch(header, &extent, iblock);
-
- /* Prevent empty leaf */
- if (extent == NULL) {
- *fblock = 0;
- } else {
- /* Compute requested physical block address */
- uint32_t phys_block;
- uint32_t first = ext4_extent_get_first_block(extent);
- phys_block = ext4_extent_get_start(extent) + iblock - first;
-
- *fblock = phys_block;
- }
-
- /* Cleanup */
- if (block.lb_id) {
- rc = ext4_block_set(inode_ref->fs->bdev, &block);
- if (rc != EOK)
- return rc;
- }
-
- return EOK;
+ int rc;
+ /* Compute bound defined by i-node size */
+ uint64_t inode_size =
+ ext4_inode_get_size(&inode_ref->fs->sb, inode_ref->inode);
+
+ uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
+
+ uint32_t last_idx = (inode_size - 1) / block_size;
+
+ /* Check if requested iblock is not over size of i-node */
+ if (iblock > last_idx) {
+ *fblock = 0;
+ return EOK;
+ }
+
+ struct ext4_block block;
+ block.lb_id = 0;
+
+ /* Walk through extent tree */
+ struct ext4_extent_header *header =
+ ext4_inode_get_extent_header(inode_ref->inode);
+
+ while (ext4_extent_header_get_depth(header) != 0) {
+ /* Search index in node */
+ struct ext4_extent_index *index;
+ ext4_extent_binsearch_idx(header, &index, iblock);
+
+ /* Load child node and set values for the next iteration */
+ uint64_t child = ext4_extent_index_get_leaf(index);
+
+ if (block.lb_id) {
+ rc = ext4_block_set(inode_ref->fs->bdev, &block);
+ if (rc != EOK)
+ return rc;
+ }
+
+ int rc = ext4_block_get(inode_ref->fs->bdev, &block, child);
+ if (rc != EOK)
+ return rc;
+
+ header = (struct ext4_extent_header *)block.data;
+ }
+
+ /* Search extent in the leaf block */
+ struct ext4_extent *extent = NULL;
+ ext4_extent_binsearch(header, &extent, iblock);
+
+ /* Prevent empty leaf */
+ if (extent == NULL) {
+ *fblock = 0;
+ } else {
+ /* Compute requested physical block address */
+ uint32_t phys_block;
+ uint32_t first = ext4_extent_get_first_block(extent);
+ phys_block = ext4_extent_get_start(extent) + iblock - first;
+
+ *fblock = phys_block;
+ }
+
+ /* Cleanup */
+ if (block.lb_id) {
+ rc = ext4_block_set(inode_ref->fs->bdev, &block);
+ if (rc != EOK)
+ return rc;
+ }
+
+ return EOK;
}
/**@brief Find extent for specified iblock.
@@ -313,80 +313,83 @@ int ext4_extent_find_block(struct ext4_inode_ref *inode_ref, uint32_t iblock, * @param ret_path Output value for loaded path from extent tree
* @return Error code */
static int ext4_extent_find_extent(struct ext4_inode_ref *inode_ref,
- uint32_t iblock,
- struct ext4_extent_path **ret_path)
+ uint32_t iblock,
+ struct ext4_extent_path **ret_path)
{
- struct ext4_extent_header *eh =
- ext4_inode_get_extent_header(inode_ref->inode);
+ struct ext4_extent_header *eh =
+ ext4_inode_get_extent_header(inode_ref->inode);
- uint16_t depth = ext4_extent_header_get_depth(eh);
- uint16_t i;
- struct ext4_extent_path *tmp_path;
+ uint16_t depth = ext4_extent_header_get_depth(eh);
+ uint16_t i;
+ struct ext4_extent_path *tmp_path;
- /* Added 2 for possible tree growing */
- tmp_path = malloc(sizeof(struct ext4_extent_path) * (depth + 2));
- if (tmp_path == NULL)
- return ENOMEM;
+ /* Added 2 for possible tree growing */
+ tmp_path = malloc(sizeof(struct ext4_extent_path) * (depth + 2));
+ if (tmp_path == NULL)
+ return ENOMEM;
- /* Initialize structure for algorithm start */
- tmp_path[0].block = inode_ref->block;
- tmp_path[0].header = eh;
+ /* Initialize structure for algorithm start */
+ tmp_path[0].block = inode_ref->block;
+ tmp_path[0].header = eh;
- /* Walk through the extent tree */
- uint16_t pos = 0;
- int rc;
- while (ext4_extent_header_get_depth(eh) != 0) {
- /* Search index in index node by iblock */
- ext4_extent_binsearch_idx(tmp_path[pos].header, &tmp_path[pos].index,
- iblock);
+ /* Walk through the extent tree */
+ uint16_t pos = 0;
+ int rc;
+ while (ext4_extent_header_get_depth(eh) != 0) {
+ /* Search index in index node by iblock */
+ ext4_extent_binsearch_idx(tmp_path[pos].header,
+ &tmp_path[pos].index, iblock);
- tmp_path[pos].depth = depth;
- tmp_path[pos].extent = NULL;
+ tmp_path[pos].depth = depth;
+ tmp_path[pos].extent = NULL;
- ext4_assert(tmp_path[pos].index != 0);
+ ext4_assert(tmp_path[pos].index != 0);
- /* Load information for the next iteration */
- uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index);
+ /* Load information for the next iteration */
+ uint64_t fblock =
+ ext4_extent_index_get_leaf(tmp_path[pos].index);
- struct ext4_block block;
- rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
- if (rc != EOK)
- goto cleanup;
+ struct ext4_block block;
+ rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
+ if (rc != EOK)
+ goto cleanup;
- pos++;
+ pos++;
- eh = (struct ext4_extent_header *)block.data;
- tmp_path[pos].block = block;
- tmp_path[pos].header = eh;
- }
+ eh = (struct ext4_extent_header *)block.data;
+ tmp_path[pos].block = block;
+ tmp_path[pos].header = eh;
+ }
- tmp_path[pos].depth = 0;
- tmp_path[pos].extent = NULL;
- tmp_path[pos].index = NULL;
+ tmp_path[pos].depth = 0;
+ tmp_path[pos].extent = NULL;
+ tmp_path[pos].index = NULL;
- /* Find extent in the leaf node */
- ext4_extent_binsearch(tmp_path[pos].header, &tmp_path[pos].extent, iblock);
- *ret_path = tmp_path;
+ /* Find extent in the leaf node */
+ ext4_extent_binsearch(tmp_path[pos].header, &tmp_path[pos].extent,
+ iblock);
+ *ret_path = tmp_path;
- return EOK;
+ return EOK;
cleanup:
- /*
- * Put loaded blocks
- * From 1: 0 is a block with inode data
- */
- for (i = 1; i < tmp_path->depth; ++i) {
- if (tmp_path[i].block.lb_id) {
- int r = ext4_block_set(inode_ref->fs->bdev, &tmp_path[i].block);
- if (r != EOK)
- rc = r;
- }
- }
-
- /* Destroy temporary data structure */
- free(tmp_path);
-
- return rc;
+ /*
+ * Put loaded blocks
+ * From 1: 0 is a block with inode data
+ */
+ for (i = 1; i < tmp_path->depth; ++i) {
+ if (tmp_path[i].block.lb_id) {
+ int r = ext4_block_set(inode_ref->fs->bdev,
+ &tmp_path[i].block);
+ if (r != EOK)
+ rc = r;
+ }
+ }
+
+ /* Destroy temporary data structure */
+ free(tmp_path);
+
+ return rc;
}
/**@brief Release extent and all data blocks covered by the extent.
@@ -394,13 +397,13 @@ cleanup: * @param extent Extent to release
* @return Error code */
static int ext4_extent_release(struct ext4_inode_ref *inode_ref,
- struct ext4_extent *extent)
+ struct ext4_extent *extent)
{
- /* Compute number of the first physical block to release */
- uint64_t start = ext4_extent_get_start(extent);
- uint16_t block_count = ext4_extent_get_block_count(extent);
+ /* Compute number of the first physical block to release */
+ uint64_t start = ext4_extent_get_start(extent);
+ uint16_t block_count = ext4_extent_get_block_count(extent);
- return ext4_balloc_free_blocks(inode_ref, start, block_count);
+ return ext4_balloc_free_blocks(inode_ref, start, block_count);
}
/** Recursively release the whole branch of the extent tree.
@@ -411,185 +414,192 @@ static int ext4_extent_release(struct ext4_inode_ref *inode_ref, * with the whole subtree
* @return Error code */
static int ext4_extent_release_branch(struct ext4_inode_ref *inode_ref,
- struct ext4_extent_index *index)
+ struct ext4_extent_index *index)
{
- uint32_t fblock = ext4_extent_index_get_leaf(index);
- uint32_t i;
- struct ext4_block block;
- int rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
- if (rc != EOK)
- return rc;
-
- struct ext4_extent_header *header = (void *)block.data;
-
- if (ext4_extent_header_get_depth(header)) {
- /* The node is non-leaf, do recursion */
- struct ext4_extent_index *idx = EXT4_EXTENT_FIRST_INDEX(header);
-
- /* Release all subbranches */
- for (i = 0; i < ext4_extent_header_get_entries_count(header);
- ++i, ++idx) {
- rc = ext4_extent_release_branch(inode_ref, idx);
- if (rc != EOK)
- return rc;
- }
- } else {
- /* Leaf node reached */
- struct ext4_extent *ext = EXT4_EXTENT_FIRST(header);
-
- /* Release all extents and stop recursion */
- for (i = 0; i < ext4_extent_header_get_entries_count(header);
- ++i, ++ext) {
- rc = ext4_extent_release(inode_ref, ext);
- if (rc != EOK)
- return rc;
- }
- }
-
- /* Release data block where the node was stored */
-
- rc = ext4_block_set(inode_ref->fs->bdev, &block);
- if (rc != EOK)
- return rc;
-
- return ext4_balloc_free_block(inode_ref, fblock);
+ uint32_t fblock = ext4_extent_index_get_leaf(index);
+ uint32_t i;
+ struct ext4_block block;
+ int rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_extent_header *header = (void *)block.data;
+
+ if (ext4_extent_header_get_depth(header)) {
+ /* The node is non-leaf, do recursion */
+ struct ext4_extent_index *idx = EXT4_EXTENT_FIRST_INDEX(header);
+
+ /* Release all subbranches */
+ for (i = 0; i < ext4_extent_header_get_entries_count(header);
+ ++i, ++idx) {
+ rc = ext4_extent_release_branch(inode_ref, idx);
+ if (rc != EOK)
+ return rc;
+ }
+ } else {
+ /* Leaf node reached */
+ struct ext4_extent *ext = EXT4_EXTENT_FIRST(header);
+
+ /* Release all extents and stop recursion */
+ for (i = 0; i < ext4_extent_header_get_entries_count(header);
+ ++i, ++ext) {
+ rc = ext4_extent_release(inode_ref, ext);
+ if (rc != EOK)
+ return rc;
+ }
+ }
+
+ /* Release data block where the node was stored */
+
+ rc = ext4_block_set(inode_ref->fs->bdev, &block);
+ if (rc != EOK)
+ return rc;
+
+ return ext4_balloc_free_block(inode_ref, fblock);
}
int ext4_extent_release_blocks_from(struct ext4_inode_ref *inode_ref,
- uint32_t iblock_from)
+ uint32_t iblock_from)
{
- /* Find the first extent to modify */
- struct ext4_extent_path *path;
- uint16_t i;
- int rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
- if (rc != EOK)
- return rc;
-
- /* Jump to last item of the path (extent) */
- struct ext4_extent_path *path_ptr = path;
- while (path_ptr->depth != 0)
- path_ptr++;
-
- ext4_assert(path_ptr->extent != NULL);
-
- /* First extent maybe released partially */
- uint32_t first_iblock = ext4_extent_get_first_block(path_ptr->extent);
- uint32_t first_fblock =
- ext4_extent_get_start(path_ptr->extent) + iblock_from - first_iblock;
-
- uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
-
- uint16_t delete_count =
- block_count - (ext4_extent_get_start(path_ptr->extent) - first_fblock);
-
- /* Release all blocks */
- rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
- if (rc != EOK)
- goto cleanup;
-
- /* Correct counter */
- block_count -= delete_count;
- ext4_extent_set_block_count(path_ptr->extent, block_count);
-
- /* Initialize the following loop */
- uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
- struct ext4_extent *tmp_ext = path_ptr->extent + 1;
- struct ext4_extent *stop_ext =
- EXT4_EXTENT_FIRST(path_ptr->header) + entries;
-
- /* If first extent empty, release it */
- if (block_count == 0)
- entries--;
-
- /* Release all successors of the first extent in the same node */
- while (tmp_ext < stop_ext) {
- first_fblock = ext4_extent_get_start(tmp_ext);
- delete_count = ext4_extent_get_block_count(tmp_ext);
-
- rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
- if (rc != EOK)
- goto cleanup;
-
- entries--;
- tmp_ext++;
- }
-
- ext4_extent_header_set_entries_count(path_ptr->header, entries);
- path_ptr->block.dirty = true;
-
- /* If leaf node is empty, parent entry must be modified */
- bool remove_parent_record = false;
-
- /* Don't release root block (including inode data) !!! */
- if ((path_ptr != path) && (entries == 0)) {
- rc = ext4_balloc_free_block(inode_ref, path_ptr->block.lb_id);
- if (rc != EOK)
- goto cleanup;
-
- remove_parent_record = true;
- }
-
- /* Jump to the parent */
- --path_ptr;
-
- /* Release all successors in all tree levels */
- while (path_ptr >= path) {
- entries = ext4_extent_header_get_entries_count(path_ptr->header);
- struct ext4_extent_index *index = path_ptr->index + 1;
- struct ext4_extent_index *stop =
- EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
-
- /* Correct entries count because of changes in the previous iteration */
- if (remove_parent_record)
- entries--;
-
- /* Iterate over all entries and release the whole subtrees */
- while (index < stop) {
- rc = ext4_extent_release_branch(inode_ref, index);
- if (rc != EOK)
- goto cleanup;
-
- ++index;
- --entries;
- }
-
- ext4_extent_header_set_entries_count(path_ptr->header, entries);
- path_ptr->block.dirty = true;
-
- /* Free the node if it is empty */
- if ((entries == 0) && (path_ptr != path)) {
- rc = ext4_balloc_free_block(inode_ref, path_ptr->block.lb_id);
- if (rc != EOK)
- goto cleanup;
-
- /* Mark parent to be checked */
- remove_parent_record = true;
- } else
- remove_parent_record = false;
-
- --path_ptr;
- }
-
- if (!entries)
- ext4_extent_header_set_depth(path->header, 0);
+ /* Find the first extent to modify */
+ struct ext4_extent_path *path;
+ uint16_t i;
+ int rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
+ if (rc != EOK)
+ return rc;
+
+ /* Jump to last item of the path (extent) */
+ struct ext4_extent_path *path_ptr = path;
+ while (path_ptr->depth != 0)
+ path_ptr++;
+
+ ext4_assert(path_ptr->extent != NULL);
+
+ /* First extent maybe released partially */
+ uint32_t first_iblock = ext4_extent_get_first_block(path_ptr->extent);
+ uint32_t first_fblock = ext4_extent_get_start(path_ptr->extent) +
+ iblock_from - first_iblock;
+
+ uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
+
+ uint16_t delete_count =
+ block_count -
+ (ext4_extent_get_start(path_ptr->extent) - first_fblock);
+
+ /* Release all blocks */
+ rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
+ if (rc != EOK)
+ goto cleanup;
+
+ /* Correct counter */
+ block_count -= delete_count;
+ ext4_extent_set_block_count(path_ptr->extent, block_count);
+
+ /* Initialize the following loop */
+ uint16_t entries =
+ ext4_extent_header_get_entries_count(path_ptr->header);
+ struct ext4_extent *tmp_ext = path_ptr->extent + 1;
+ struct ext4_extent *stop_ext =
+ EXT4_EXTENT_FIRST(path_ptr->header) + entries;
+
+ /* If first extent empty, release it */
+ if (block_count == 0)
+ entries--;
+
+ /* Release all successors of the first extent in the same node */
+ while (tmp_ext < stop_ext) {
+ first_fblock = ext4_extent_get_start(tmp_ext);
+ delete_count = ext4_extent_get_block_count(tmp_ext);
+
+ rc = ext4_balloc_free_blocks(inode_ref, first_fblock,
+ delete_count);
+ if (rc != EOK)
+ goto cleanup;
+
+ entries--;
+ tmp_ext++;
+ }
+
+ ext4_extent_header_set_entries_count(path_ptr->header, entries);
+ path_ptr->block.dirty = true;
+
+ /* If leaf node is empty, parent entry must be modified */
+ bool remove_parent_record = false;
+
+ /* Don't release root block (including inode data) !!! */
+ if ((path_ptr != path) && (entries == 0)) {
+ rc = ext4_balloc_free_block(inode_ref, path_ptr->block.lb_id);
+ if (rc != EOK)
+ goto cleanup;
+
+ remove_parent_record = true;
+ }
+
+ /* Jump to the parent */
+ --path_ptr;
+
+ /* Release all successors in all tree levels */
+ while (path_ptr >= path) {
+ entries =
+ ext4_extent_header_get_entries_count(path_ptr->header);
+ struct ext4_extent_index *index = path_ptr->index + 1;
+ struct ext4_extent_index *stop =
+ EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
+
+ /* Correct entries count because of changes in the previous
+ * iteration */
+ if (remove_parent_record)
+ entries--;
+
+ /* Iterate over all entries and release the whole subtrees */
+ while (index < stop) {
+ rc = ext4_extent_release_branch(inode_ref, index);
+ if (rc != EOK)
+ goto cleanup;
+
+ ++index;
+ --entries;
+ }
+
+ ext4_extent_header_set_entries_count(path_ptr->header, entries);
+ path_ptr->block.dirty = true;
+
+ /* Free the node if it is empty */
+ if ((entries == 0) && (path_ptr != path)) {
+ rc = ext4_balloc_free_block(inode_ref,
+ path_ptr->block.lb_id);
+ if (rc != EOK)
+ goto cleanup;
+
+ /* Mark parent to be checked */
+ remove_parent_record = true;
+ } else
+ remove_parent_record = false;
+
+ --path_ptr;
+ }
+
+ if (!entries)
+ ext4_extent_header_set_depth(path->header, 0);
cleanup:
- /*
- * Put loaded blocks
- * starting from 1: 0 is a block with inode data
- */
- for (i = 1; i <= path->depth; ++i) {
- if (path[i].block.lb_id) {
- int r = ext4_block_set(inode_ref->fs->bdev, &path[i].block);
- if (r != EOK)
- rc = r;
- }
- }
-
- /* Destroy temporary data structure */
- free(path);
-
- return rc;
+ /*
+ * Put loaded blocks
+ * starting from 1: 0 is a block with inode data
+ */
+ for (i = 1; i <= path->depth; ++i) {
+ if (path[i].block.lb_id) {
+ int r =
+ ext4_block_set(inode_ref->fs->bdev, &path[i].block);
+ if (r != EOK)
+ rc = r;
+ }
+ }
+
+ /* Destroy temporary data structure */
+ free(path);
+
+ return rc;
}
/**@brief Append new extent to the i-node and do some splitting if necessary.
@@ -600,335 +610,373 @@ cleanup: * @param iblock Logical index of block to append extent for
* @return Error code */
static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref,
- struct ext4_extent_path *path,
- uint32_t iblock)
+ struct ext4_extent_path *path,
+ uint32_t iblock)
{
- struct ext4_extent_path *path_ptr = path + path->depth;
-
- uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
-
- /* Start splitting */
- while (path_ptr > path) {
- uint16_t entries =
- ext4_extent_header_get_entries_count(path_ptr->header);
- uint16_t limit =
- ext4_extent_header_get_max_entries_count(path_ptr->header);
-
- if (entries == limit) {
- /* Full node - allocate block for new one */
- uint32_t fblock;
- int rc = ext4_balloc_alloc_block(inode_ref, &fblock);
- if (rc != EOK)
- return rc;
-
- struct ext4_block block;
- rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
- if (rc != EOK) {
- ext4_balloc_free_block(inode_ref, fblock);
- return rc;
- }
-
- /* Put back not modified old block */
- rc = ext4_block_set(inode_ref->fs->bdev, &path_ptr->block);
- if (rc != EOK) {
- ext4_balloc_free_block(inode_ref, fblock);
- return rc;
- }
-
- /* Initialize newly allocated block and remember it */
- memset(block.data, 0, block_size);
- path_ptr->block = block;
-
- /* Update pointers in extent path structure */
- path_ptr->header = (void *)block.data;
- if (path_ptr->depth) {
- path_ptr->index = EXT4_EXTENT_FIRST_INDEX(path_ptr->header);
- ext4_extent_index_set_first_block(path_ptr->index, iblock);
- ext4_extent_index_set_leaf(path_ptr->index,
- (path_ptr + 1)->block.lb_id);
- limit = (block_size - sizeof(struct ext4_extent_header)) /
- sizeof(struct ext4_extent_index);
- } else {
- path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header);
- ext4_extent_set_first_block(path_ptr->extent, iblock);
- limit = (block_size - sizeof(struct ext4_extent_header)) /
- sizeof(struct ext4_extent);
- }
-
- /* Initialize on-disk structure (header) */
- ext4_extent_header_set_entries_count(path_ptr->header, 1);
- ext4_extent_header_set_max_entries_count(path_ptr->header, limit);
- ext4_extent_header_set_magic(path_ptr->header, EXT4_EXTENT_MAGIC);
- ext4_extent_header_set_depth(path_ptr->header, path_ptr->depth);
- ext4_extent_header_set_generation(path_ptr->header, 0);
-
- path_ptr->block.dirty = true;
-
- /* Jump to the preceding item */
- path_ptr--;
- } else {
- /* Node with free space */
- if (path_ptr->depth) {
- path_ptr->index =
- EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
- ext4_extent_index_set_first_block(path_ptr->index, iblock);
- ext4_extent_index_set_leaf(path_ptr->index,
- (path_ptr + 1)->block.lb_id);
- } else {
- path_ptr->extent =
- EXT4_EXTENT_FIRST(path_ptr->header) + entries;
- ext4_extent_set_first_block(path_ptr->extent, iblock);
- }
-
- ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);
- path_ptr->block.dirty = true;
-
- /* No more splitting needed */
- return EOK;
- }
- }
-
- ext4_assert(path_ptr == path);
-
- /* Should be the root split too? */
-
- uint16_t entries = ext4_extent_header_get_entries_count(path->header);
- uint16_t limit = ext4_extent_header_get_max_entries_count(path->header);
-
- if (entries == limit) {
- uint32_t new_fblock;
- int rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);
- if (rc != EOK)
- return rc;
-
- struct ext4_block block;
- rc = ext4_block_get(inode_ref->fs->bdev, &block, new_fblock);
- if (rc != EOK)
- return rc;
-
- /* Initialize newly allocated block */
- memset(block.data, 0, block_size);
-
- /* Move data from root to the new block */
- memcpy(block.data, inode_ref->inode->blocks,
- EXT4_INODE_BLOCKS * sizeof(uint32_t));
-
- /* Data block is initialized */
-
- struct ext4_block *root_block = &path->block;
- uint16_t root_depth = path->depth;
- struct ext4_extent_header *root_header = path->header;
-
- /* Make space for tree growing */
- struct ext4_extent_path *new_root = path;
- struct ext4_extent_path *old_root = path + 1;
-
- size_t nbytes = sizeof(struct ext4_extent_path) * (path->depth + 1);
- memmove(old_root, new_root, nbytes);
- memset(new_root, 0, sizeof(struct ext4_extent_path));
-
- /* Update old root structure */
- old_root->block = block;
- old_root->header = (struct ext4_extent_header *)block.data;
-
- /* Add new entry and update limit for entries */
- if (old_root->depth) {
- limit = (block_size - sizeof(struct ext4_extent_header)) /
- sizeof(struct ext4_extent_index);
- old_root->index =
- EXT4_EXTENT_FIRST_INDEX(old_root->header) + entries;
- ext4_extent_index_set_first_block(old_root->index, iblock);
- ext4_extent_index_set_leaf(old_root->index,
- (old_root + 1)->block.lb_id);
- old_root->extent = NULL;
- } else {
- limit = (block_size - sizeof(struct ext4_extent_header)) /
- sizeof(struct ext4_extent);
- old_root->extent = EXT4_EXTENT_FIRST(old_root->header) + entries;
- ext4_extent_set_first_block(old_root->extent, iblock);
- old_root->index = NULL;
- }
-
- ext4_extent_header_set_entries_count(old_root->header, entries + 1);
- ext4_extent_header_set_max_entries_count(old_root->header, limit);
-
- old_root->block.dirty = true;
-
- /* Re-initialize new root metadata */
- new_root->depth = root_depth + 1;
- new_root->block = *root_block;
- new_root->header = root_header;
- new_root->extent = NULL;
- new_root->index = EXT4_EXTENT_FIRST_INDEX(new_root->header);
-
- ext4_extent_header_set_depth(new_root->header, new_root->depth);
-
- /* Create new entry in root */
- ext4_extent_header_set_entries_count(new_root->header, 1);
- ext4_extent_index_set_first_block(new_root->index, 0);
- ext4_extent_index_set_leaf(new_root->index, new_fblock);
-
- new_root->block.dirty = true;
- } else {
- if (path->depth) {
- path->index = EXT4_EXTENT_FIRST_INDEX(path->header) + entries;
- ext4_extent_index_set_first_block(path->index, iblock);
- ext4_extent_index_set_leaf(path->index, (path + 1)->block.lb_id);
- } else {
- path->extent = EXT4_EXTENT_FIRST(path->header) + entries;
- ext4_extent_set_first_block(path->extent, iblock);
- }
-
- ext4_extent_header_set_entries_count(path->header, entries + 1);
- path->block.dirty = true;
- }
-
- return EOK;
+ struct ext4_extent_path *path_ptr = path + path->depth;
+
+ uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
+
+ /* Start splitting */
+ while (path_ptr > path) {
+ uint16_t entries =
+ ext4_extent_header_get_entries_count(path_ptr->header);
+ uint16_t limit =
+ ext4_extent_header_get_max_entries_count(path_ptr->header);
+
+ if (entries == limit) {
+ /* Full node - allocate block for new one */
+ uint32_t fblock;
+ int rc = ext4_balloc_alloc_block(inode_ref, &fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_block block;
+ rc =
+ ext4_block_get(inode_ref->fs->bdev, &block, fblock);
+ if (rc != EOK) {
+ ext4_balloc_free_block(inode_ref, fblock);
+ return rc;
+ }
+
+ /* Put back not modified old block */
+ rc = ext4_block_set(inode_ref->fs->bdev,
+ &path_ptr->block);
+ if (rc != EOK) {
+ ext4_balloc_free_block(inode_ref, fblock);
+ return rc;
+ }
+
+ /* Initialize newly allocated block and remember it */
+ memset(block.data, 0, block_size);
+ path_ptr->block = block;
+
+ /* Update pointers in extent path structure */
+ path_ptr->header = (void *)block.data;
+ if (path_ptr->depth) {
+ path_ptr->index =
+ EXT4_EXTENT_FIRST_INDEX(path_ptr->header);
+ ext4_extent_index_set_first_block(
+ path_ptr->index, iblock);
+ ext4_extent_index_set_leaf(
+ path_ptr->index,
+ (path_ptr + 1)->block.lb_id);
+ limit = (block_size -
+ sizeof(struct ext4_extent_header)) /
+ sizeof(struct ext4_extent_index);
+ } else {
+ path_ptr->extent =
+ EXT4_EXTENT_FIRST(path_ptr->header);
+ ext4_extent_set_first_block(path_ptr->extent,
+ iblock);
+ limit = (block_size -
+ sizeof(struct ext4_extent_header)) /
+ sizeof(struct ext4_extent);
+ }
+
+ /* Initialize on-disk structure (header) */
+ ext4_extent_header_set_entries_count(path_ptr->header,
+ 1);
+ ext4_extent_header_set_max_entries_count(
+ path_ptr->header, limit);
+ ext4_extent_header_set_magic(path_ptr->header,
+ EXT4_EXTENT_MAGIC);
+ ext4_extent_header_set_depth(path_ptr->header,
+ path_ptr->depth);
+ ext4_extent_header_set_generation(path_ptr->header, 0);
+
+ path_ptr->block.dirty = true;
+
+ /* Jump to the preceding item */
+ path_ptr--;
+ } else {
+ /* Node with free space */
+ if (path_ptr->depth) {
+ path_ptr->index =
+ EXT4_EXTENT_FIRST_INDEX(path_ptr->header) +
+ entries;
+ ext4_extent_index_set_first_block(
+ path_ptr->index, iblock);
+ ext4_extent_index_set_leaf(
+ path_ptr->index,
+ (path_ptr + 1)->block.lb_id);
+ } else {
+ path_ptr->extent =
+ EXT4_EXTENT_FIRST(path_ptr->header) +
+ entries;
+ ext4_extent_set_first_block(path_ptr->extent,
+ iblock);
+ }
+
+ ext4_extent_header_set_entries_count(path_ptr->header,
+ entries + 1);
+ path_ptr->block.dirty = true;
+
+ /* No more splitting needed */
+ return EOK;
+ }
+ }
+
+ ext4_assert(path_ptr == path);
+
+ /* Should be the root split too? */
+
+ uint16_t entries = ext4_extent_header_get_entries_count(path->header);
+ uint16_t limit = ext4_extent_header_get_max_entries_count(path->header);
+
+ if (entries == limit) {
+ uint32_t new_fblock;
+ int rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_block block;
+ rc = ext4_block_get(inode_ref->fs->bdev, &block, new_fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Initialize newly allocated block */
+ memset(block.data, 0, block_size);
+
+ /* Move data from root to the new block */
+ memcpy(block.data, inode_ref->inode->blocks,
+ EXT4_INODE_BLOCKS * sizeof(uint32_t));
+
+ /* Data block is initialized */
+
+ struct ext4_block *root_block = &path->block;
+ uint16_t root_depth = path->depth;
+ struct ext4_extent_header *root_header = path->header;
+
+ /* Make space for tree growing */
+ struct ext4_extent_path *new_root = path;
+ struct ext4_extent_path *old_root = path + 1;
+
+ size_t nbytes =
+ sizeof(struct ext4_extent_path) * (path->depth + 1);
+ memmove(old_root, new_root, nbytes);
+ memset(new_root, 0, sizeof(struct ext4_extent_path));
+
+ /* Update old root structure */
+ old_root->block = block;
+ old_root->header = (struct ext4_extent_header *)block.data;
+
+ /* Add new entry and update limit for entries */
+ if (old_root->depth) {
+ limit =
+ (block_size - sizeof(struct ext4_extent_header)) /
+ sizeof(struct ext4_extent_index);
+ old_root->index =
+ EXT4_EXTENT_FIRST_INDEX(old_root->header) + entries;
+ ext4_extent_index_set_first_block(old_root->index,
+ iblock);
+ ext4_extent_index_set_leaf(old_root->index,
+ (old_root + 1)->block.lb_id);
+ old_root->extent = NULL;
+ } else {
+ limit =
+ (block_size - sizeof(struct ext4_extent_header)) /
+ sizeof(struct ext4_extent);
+ old_root->extent =
+ EXT4_EXTENT_FIRST(old_root->header) + entries;
+ ext4_extent_set_first_block(old_root->extent, iblock);
+ old_root->index = NULL;
+ }
+
+ ext4_extent_header_set_entries_count(old_root->header,
+ entries + 1);
+ ext4_extent_header_set_max_entries_count(old_root->header,
+ limit);
+
+ old_root->block.dirty = true;
+
+ /* Re-initialize new root metadata */
+ new_root->depth = root_depth + 1;
+ new_root->block = *root_block;
+ new_root->header = root_header;
+ new_root->extent = NULL;
+ new_root->index = EXT4_EXTENT_FIRST_INDEX(new_root->header);
+
+ ext4_extent_header_set_depth(new_root->header, new_root->depth);
+
+ /* Create new entry in root */
+ ext4_extent_header_set_entries_count(new_root->header, 1);
+ ext4_extent_index_set_first_block(new_root->index, 0);
+ ext4_extent_index_set_leaf(new_root->index, new_fblock);
+
+ new_root->block.dirty = true;
+ } else {
+ if (path->depth) {
+ path->index =
+ EXT4_EXTENT_FIRST_INDEX(path->header) + entries;
+ ext4_extent_index_set_first_block(path->index, iblock);
+ ext4_extent_index_set_leaf(path->index,
+ (path + 1)->block.lb_id);
+ } else {
+ path->extent =
+ EXT4_EXTENT_FIRST(path->header) + entries;
+ ext4_extent_set_first_block(path->extent, iblock);
+ }
+
+ ext4_extent_header_set_entries_count(path->header, entries + 1);
+ path->block.dirty = true;
+ }
+
+ return EOK;
}
int ext4_extent_append_block(struct ext4_inode_ref *inode_ref, uint32_t *iblock,
- uint32_t *fblock, bool update_size)
+ uint32_t *fblock, bool update_size)
{
- uint16_t i;
- struct ext4_sblock *sb = &inode_ref->fs->sb;
- uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
- uint32_t block_size = ext4_sb_get_block_size(sb);
-
- /* Calculate number of new logical block */
- uint32_t new_block_idx = 0;
- if (inode_size > 0) {
- if ((inode_size % block_size) != 0)
- inode_size += block_size - (inode_size % block_size);
-
- new_block_idx = inode_size / block_size;
- }
-
- /* Load the nearest leaf (with extent) */
- struct ext4_extent_path *path;
- int rc = ext4_extent_find_extent(inode_ref, new_block_idx, &path);
- if (rc != EOK)
- return rc;
-
- /* Jump to last item of the path (extent) */
- struct ext4_extent_path *path_ptr = path;
- while (path_ptr->depth != 0)
- path_ptr++;
-
- /* Add new extent to the node if not present */
- if (path_ptr->extent == NULL)
- goto append_extent;
-
- uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
- uint16_t block_limit = (1 << 15);
-
- uint32_t phys_block = 0;
- if (block_count < block_limit) {
- /* There is space for new block in the extent */
- if (block_count == 0) {
- /* Existing extent is empty */
- rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
- if (rc != EOK)
- goto finish;
-
- /* Initialize extent */
- ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
- ext4_extent_set_start(path_ptr->extent, phys_block);
- ext4_extent_set_block_count(path_ptr->extent, 1);
-
- /* Update i-node */
- if (update_size) {
- ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
- inode_ref->dirty = true;
- }
-
- path_ptr->block.dirty = true;
-
- goto finish;
- } else {
- /* Existing extent contains some blocks */
- phys_block = ext4_extent_get_start(path_ptr->extent);
- phys_block += ext4_extent_get_block_count(path_ptr->extent);
-
- /* Check if the following block is free for allocation */
- bool free;
- rc = ext4_balloc_try_alloc_block(inode_ref, phys_block, &free);
- if (rc != EOK)
- goto finish;
-
- if (!free) {
- /* Target is not free, new block must be appended to new extent
- */
- goto append_extent;
- }
-
- /* Update extent */
- ext4_extent_set_block_count(path_ptr->extent, block_count + 1);
-
- /* Update i-node */
- if (update_size) {
- ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
- inode_ref->dirty = true;
- }
-
- path_ptr->block.dirty = true;
-
- goto finish;
- }
- }
+ uint16_t i;
+ struct ext4_sblock *sb = &inode_ref->fs->sb;
+ uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
+ uint32_t block_size = ext4_sb_get_block_size(sb);
+
+ /* Calculate number of new logical block */
+ uint32_t new_block_idx = 0;
+ if (inode_size > 0) {
+ if ((inode_size % block_size) != 0)
+ inode_size += block_size - (inode_size % block_size);
+
+ new_block_idx = inode_size / block_size;
+ }
+
+ /* Load the nearest leaf (with extent) */
+ struct ext4_extent_path *path;
+ int rc = ext4_extent_find_extent(inode_ref, new_block_idx, &path);
+ if (rc != EOK)
+ return rc;
+
+ /* Jump to last item of the path (extent) */
+ struct ext4_extent_path *path_ptr = path;
+ while (path_ptr->depth != 0)
+ path_ptr++;
+
+ /* Add new extent to the node if not present */
+ if (path_ptr->extent == NULL)
+ goto append_extent;
+
+ uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
+ uint16_t block_limit = (1 << 15);
+
+ uint32_t phys_block = 0;
+ if (block_count < block_limit) {
+ /* There is space for new block in the extent */
+ if (block_count == 0) {
+ /* Existing extent is empty */
+ rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
+ if (rc != EOK)
+ goto finish;
+
+ /* Initialize extent */
+ ext4_extent_set_first_block(path_ptr->extent,
+ new_block_idx);
+ ext4_extent_set_start(path_ptr->extent, phys_block);
+ ext4_extent_set_block_count(path_ptr->extent, 1);
+
+ /* Update i-node */
+ if (update_size) {
+ ext4_inode_set_size(inode_ref->inode,
+ inode_size + block_size);
+ inode_ref->dirty = true;
+ }
+
+ path_ptr->block.dirty = true;
+
+ goto finish;
+ } else {
+ /* Existing extent contains some blocks */
+ phys_block = ext4_extent_get_start(path_ptr->extent);
+ phys_block +=
+ ext4_extent_get_block_count(path_ptr->extent);
+
+ /* Check if the following block is free for allocation
+ */
+ bool free;
+ rc = ext4_balloc_try_alloc_block(inode_ref, phys_block,
+ &free);
+ if (rc != EOK)
+ goto finish;
+
+ if (!free) {
+ /* Target is not free, new block must be
+ * appended to new extent
+ */
+ goto append_extent;
+ }
+
+ /* Update extent */
+ ext4_extent_set_block_count(path_ptr->extent,
+ block_count + 1);
+
+ /* Update i-node */
+ if (update_size) {
+ ext4_inode_set_size(inode_ref->inode,
+ inode_size + block_size);
+ inode_ref->dirty = true;
+ }
+
+ path_ptr->block.dirty = true;
+
+ goto finish;
+ }
+ }
append_extent:
- /* Append new extent to the tree */
- phys_block = 0;
+ /* Append new extent to the tree */
+ phys_block = 0;
- /* Allocate new data block */
- rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
- if (rc != EOK)
- goto finish;
+ /* Allocate new data block */
+ rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
+ if (rc != EOK)
+ goto finish;
- /* Append extent for new block (includes tree splitting if needed) */
- rc = ext4_extent_append_extent(inode_ref, path, new_block_idx);
- if (rc != EOK) {
- ext4_balloc_free_block(inode_ref, phys_block);
- goto finish;
- }
+ /* Append extent for new block (includes tree splitting if needed) */
+ rc = ext4_extent_append_extent(inode_ref, path, new_block_idx);
+ if (rc != EOK) {
+ ext4_balloc_free_block(inode_ref, phys_block);
+ goto finish;
+ }
- uint32_t tree_depth = ext4_extent_header_get_depth(path->header);
- path_ptr = path + tree_depth;
+ uint32_t tree_depth = ext4_extent_header_get_depth(path->header);
+ path_ptr = path + tree_depth;
- /* Initialize newly created extent */
- ext4_extent_set_block_count(path_ptr->extent, 1);
- ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
- ext4_extent_set_start(path_ptr->extent, phys_block);
+ /* Initialize newly created extent */
+ ext4_extent_set_block_count(path_ptr->extent, 1);
+ ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
+ ext4_extent_set_start(path_ptr->extent, phys_block);
- /* Update i-node */
- if (update_size) {
- ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
- inode_ref->dirty = true;
- }
+ /* Update i-node */
+ if (update_size) {
+ ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
+ inode_ref->dirty = true;
+ }
- path_ptr->block.dirty = true;
+ path_ptr->block.dirty = true;
finish:
- /* Set return values */
- *iblock = new_block_idx;
- *fblock = phys_block;
-
- /*
- * Put loaded blocks
- * starting from 1: 0 is a block with inode data
- */
- for (i = 1; i <= path->depth; ++i) {
- if (path[i].block.lb_id) {
- int r = ext4_block_set(inode_ref->fs->bdev, &path[i].block);
- if (r != EOK)
- rc = r;
- }
- }
-
- /* Destroy temporary data structure */
- free(path);
-
- return rc;
+ /* Set return values */
+ *iblock = new_block_idx;
+ *fblock = phys_block;
+
+ /*
+ * Put loaded blocks
+ * starting from 1: 0 is a block with inode data
+ */
+ for (i = 1; i <= path->depth; ++i) {
+ if (path[i].block.lb_id) {
+ int r =
+ ext4_block_set(inode_ref->fs->bdev, &path[i].block);
+ if (r != EOK)
+ rc = r;
+ }
+ }
+
+ /* Destroy temporary data structure */
+ free(path);
+
+ return rc;
}
/**
diff --git a/lwext4/ext4_extent.h b/lwext4/ext4_extent.h index 127e14b..fe470da 100644 --- a/lwext4/ext4_extent.h +++ b/lwext4/ext4_extent.h @@ -83,7 +83,7 @@ uint32_t ext4_extent_index_get_first_block(struct ext4_extent_index *index); * @param index Extent index to set number to
* @param iblock Logical number of the first block covered by extent index */
void ext4_extent_index_set_first_block(struct ext4_extent_index *index,
- uint32_t iblock);
+ uint32_t iblock);
/**@brief Get physical number of block where the child node is located.
* @param index Extent index to load number from
@@ -94,7 +94,7 @@ uint64_t ext4_extent_index_get_leaf(struct ext4_extent_index *index); * @param index Extent index to set number to
* @param fblock Ohysical number of the block with child node */
void ext4_extent_index_set_leaf(struct ext4_extent_index *index,
- uint64_t fblock);
+ uint64_t fblock);
/**@brief Get magic value from extent header.
* @param header Extent header to load value from
@@ -105,7 +105,7 @@ uint16_t ext4_extent_header_get_magic(struct ext4_extent_header *header); * @param header Extent header to set value to
* @param magic Magic value of extent header */
void ext4_extent_header_set_magic(struct ext4_extent_header *header,
- uint16_t magic);
+ uint16_t magic);
/**@brief Get number of entries from extent header
* @param header Extent header to get value from
@@ -117,7 +117,7 @@ ext4_extent_header_get_entries_count(struct ext4_extent_header *header); * @param header Extent header to set value to
* @param count Number of entries covered by extent header */
void ext4_extent_header_set_entries_count(struct ext4_extent_header *header,
- uint16_t count);
+ uint16_t count);
/**@brief Get maximum number of entries from extent header
* @param header Extent header to get value from
@@ -129,7 +129,7 @@ ext4_extent_header_get_max_entries_count(struct ext4_extent_header *header); * @param header Extent header to set value to
* @param max_count Maximum number of entries covered by extent header */
void ext4_extent_header_set_max_entries_count(struct ext4_extent_header *header,
- uint16_t max_count);
+ uint16_t max_count);
/**@brief Get depth of extent subtree.
* @param header Extent header to get value from
@@ -140,7 +140,7 @@ uint16_t ext4_extent_header_get_depth(struct ext4_extent_header *header); * @param header Extent header to set value to
* @param depth Depth of extent subtree */
void ext4_extent_header_set_depth(struct ext4_extent_header *header,
- uint16_t depth);
+ uint16_t depth);
/**@brief Get generation from extent header
* @param header Extent header to get value from
@@ -151,7 +151,7 @@ uint32_t ext4_extent_header_get_generation(struct ext4_extent_header *header); * @param header Extent header to set value to
* @param generation Generation */
void ext4_extent_header_set_generation(struct ext4_extent_header *header,
- uint32_t generation);
+ uint32_t generation);
/**@brief Find physical block in the extent tree by logical block number.
* There is no need to save path in the tree during this algorithm.
@@ -160,14 +160,14 @@ void ext4_extent_header_set_generation(struct ext4_extent_header *header, * @param fblock Output value for physical block number
* @return Error code*/
int ext4_extent_find_block(struct ext4_inode_ref *inode_ref, uint32_t iblock,
- uint32_t *fblock);
+ uint32_t *fblock);
/**@brief Release all data blocks starting from specified logical block.
* @param inode_ref I-node to release blocks from
* @param iblock_from First logical block to release
* @return Error code */
int ext4_extent_release_blocks_from(struct ext4_inode_ref *inode_ref,
- uint32_t iblock_from);
+ uint32_t iblock_from);
/**@brief Append data block to the i-node.
* This function allocates data block, tries to append it
@@ -179,9 +179,9 @@ int ext4_extent_release_blocks_from(struct ext4_inode_ref *inode_ref, *
* @return Error code*/
int ext4_extent_append_block(struct ext4_inode_ref *inode_ref, uint32_t *iblock,
- uint32_t *fblock, bool update_size);
+ uint32_t *fblock, bool update_size);
#endif /* EXT4_EXTENT_H_ */
/**
- * @}
- */
+ * @}
+ */
diff --git a/lwext4/ext4_fs.c b/lwext4/ext4_fs.c index c74b115..28102d1 100644 --- a/lwext4/ext4_fs.c +++ b/lwext4/ext4_fs.c @@ -56,217 +56,219 @@ int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev) { - int r, i; - uint16_t tmp; - uint32_t bsize; - bool read_only = false; + int r, i; + uint16_t tmp; + uint32_t bsize; + bool read_only = false; - ext4_assert(fs && bdev); + ext4_assert(fs && bdev); - fs->bdev = bdev; + fs->bdev = bdev; - r = ext4_sb_read(fs->bdev, &fs->sb); - if (r != EOK) - return r; + r = ext4_sb_read(fs->bdev, &fs->sb); + if (r != EOK) + return r; - if (!ext4_sb_check(&fs->sb)) - return ENOTSUP; + if (!ext4_sb_check(&fs->sb)) + return ENOTSUP; - bsize = ext4_sb_get_block_size(&fs->sb); - if (bsize > EXT4_MAX_BLOCK_SIZE) - return ENXIO; + bsize = ext4_sb_get_block_size(&fs->sb); + if (bsize > EXT4_MAX_BLOCK_SIZE) + return ENXIO; - r = ext4_fs_check_features(fs, &read_only); - if (r != EOK) - return r; + r = ext4_fs_check_features(fs, &read_only); + if (r != EOK) + return r; - if (read_only) - return ENOTSUP; + if (read_only) + return ENOTSUP; - /* Compute limits for indirect block levels */ - uint32_t blocks_id = bsize / sizeof(uint32_t); + /* Compute limits for indirect block levels */ + uint32_t blocks_id = bsize / sizeof(uint32_t); - fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT; - fs->inode_blocks_per_level[0] = 1; + fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT; + fs->inode_blocks_per_level[0] = 1; - for (i = 1; i < 4; i++) { - fs->inode_blocks_per_level[i] = - fs->inode_blocks_per_level[i - 1] * blocks_id; - fs->inode_block_limits[i] = - fs->inode_block_limits[i - 1] + fs->inode_blocks_per_level[i]; - } + for (i = 1; i < 4; i++) { + fs->inode_blocks_per_level[i] = + fs->inode_blocks_per_level[i - 1] * blocks_id; + fs->inode_block_limits[i] = fs->inode_block_limits[i - 1] + + fs->inode_blocks_per_level[i]; + } - /*Validate FS*/ - tmp = ext4_get16(&fs->sb, state); - if (tmp & EXT4_SUPERBLOCK_STATE_ERROR_FS) { - ext4_dprintf(EXT4_DEBUG_FS, "last umount error\n"); - } + /*Validate FS*/ + tmp = ext4_get16(&fs->sb, state); + if (tmp & EXT4_SUPERBLOCK_STATE_ERROR_FS) { + ext4_dprintf(EXT4_DEBUG_FS, "last umount error\n"); + } - /* Mark system as mounted */ - ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS); - r = ext4_sb_write(fs->bdev, &fs->sb); - if (r != EOK) - return r; + /* Mark system as mounted */ + ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS); + r = ext4_sb_write(fs->bdev, &fs->sb); + if (r != EOK) + return r; - /*Update mount count*/ - ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1); + /*Update mount count*/ + ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1); - return r; + return r; } int ext4_fs_fini(struct ext4_fs *fs) { - ext4_assert(fs); + ext4_assert(fs); - /*Set superblock state*/ - ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_VALID_FS); + /*Set superblock state*/ + ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_VALID_FS); - return ext4_sb_write(fs->bdev, &fs->sb); + return ext4_sb_write(fs->bdev, &fs->sb); } static void ext4_fs_debug_features_incomp(uint32_t features_incompatible) { - if (features_incompatible & EXT4_FEATURE_INCOMPAT_COMPRESSION) { - ext4_dprintf(EXT4_DEBUG_FS, "compression\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_FILETYPE) { - ext4_dprintf(EXT4_DEBUG_FS, "filetype\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_RECOVER) { - ext4_dprintf(EXT4_DEBUG_FS, "recover\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_JOURNAL_DEV) { - ext4_dprintf(EXT4_DEBUG_FS, "journal_dev\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_META_BG) { - ext4_dprintf(EXT4_DEBUG_FS, "meta_bg\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_EXTENTS) { - ext4_dprintf(EXT4_DEBUG_FS, "extents\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_64BIT) { - ext4_dprintf(EXT4_DEBUG_FS, "64bit\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_MMP) { - ext4_dprintf(EXT4_DEBUG_FS, "mnp\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_FLEX_BG) { - ext4_dprintf(EXT4_DEBUG_FS, "flex_bg\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_EA_INODE) { - ext4_dprintf(EXT4_DEBUG_FS, "ea_inode\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_DIRDATA) { - ext4_dprintf(EXT4_DEBUG_FS, "dirdata\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM) { - ext4_dprintf(EXT4_DEBUG_FS, "meta_csum\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_LARGEDIR) { - ext4_dprintf(EXT4_DEBUG_FS, "largedir\n"); - } - if (features_incompatible & EXT4_FEATURE_INCOMPAT_INLINE_DATA) { - ext4_dprintf(EXT4_DEBUG_FS, "inline_data\n"); - } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_COMPRESSION) { + ext4_dprintf(EXT4_DEBUG_FS, "compression\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_FILETYPE) { + ext4_dprintf(EXT4_DEBUG_FS, "filetype\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_RECOVER) { + ext4_dprintf(EXT4_DEBUG_FS, "recover\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_JOURNAL_DEV) { + ext4_dprintf(EXT4_DEBUG_FS, "journal_dev\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_META_BG) { + ext4_dprintf(EXT4_DEBUG_FS, "meta_bg\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_EXTENTS) { + ext4_dprintf(EXT4_DEBUG_FS, "extents\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_64BIT) { + ext4_dprintf(EXT4_DEBUG_FS, "64bit\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_MMP) { + ext4_dprintf(EXT4_DEBUG_FS, "mnp\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_FLEX_BG) { + ext4_dprintf(EXT4_DEBUG_FS, "flex_bg\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_EA_INODE) { + ext4_dprintf(EXT4_DEBUG_FS, "ea_inode\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_DIRDATA) { + ext4_dprintf(EXT4_DEBUG_FS, "dirdata\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM) { + ext4_dprintf(EXT4_DEBUG_FS, "meta_csum\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_LARGEDIR) { + ext4_dprintf(EXT4_DEBUG_FS, "largedir\n"); + } + if (features_incompatible & EXT4_FEATURE_INCOMPAT_INLINE_DATA) { + ext4_dprintf(EXT4_DEBUG_FS, "inline_data\n"); + } } static void ext4_fs_debug_features_comp(uint32_t features_compatible) { - if (features_compatible & EXT4_FEATURE_COMPAT_DIR_PREALLOC) { - ext4_dprintf(EXT4_DEBUG_FS, " dir_prealloc\n"); - } - if (features_compatible & EXT4_FEATURE_COMPAT_IMAGIC_INODES) { - ext4_dprintf(EXT4_DEBUG_FS, "imagic_inodes\n"); - } - if (features_compatible & EXT4_FEATURE_COMPAT_HAS_JOURNAL) { - ext4_dprintf(EXT4_DEBUG_FS, "has_journal\n"); - } - if (features_compatible & EXT4_FEATURE_COMPAT_EXT_ATTR) { - ext4_dprintf(EXT4_DEBUG_FS, "ext_attr\n"); - } - if (features_compatible & EXT4_FEATURE_COMPAT_RESIZE_INODE) { - ext4_dprintf(EXT4_DEBUG_FS, "resize_inode\n"); - } - if (features_compatible & EXT4_FEATURE_COMPAT_DIR_INDEX) { - ext4_dprintf(EXT4_DEBUG_FS, "dir_index\n"); - } + if (features_compatible & EXT4_FEATURE_COMPAT_DIR_PREALLOC) { + ext4_dprintf(EXT4_DEBUG_FS, " dir_prealloc\n"); + } + if (features_compatible & EXT4_FEATURE_COMPAT_IMAGIC_INODES) { + ext4_dprintf(EXT4_DEBUG_FS, "imagic_inodes\n"); + } + if (features_compatible & EXT4_FEATURE_COMPAT_HAS_JOURNAL) { + ext4_dprintf(EXT4_DEBUG_FS, "has_journal\n"); + } + if (features_compatible & EXT4_FEATURE_COMPAT_EXT_ATTR) { + ext4_dprintf(EXT4_DEBUG_FS, "ext_attr\n"); + } + if (features_compatible & EXT4_FEATURE_COMPAT_RESIZE_INODE) { + ext4_dprintf(EXT4_DEBUG_FS, "resize_inode\n"); + } + if (features_compatible & EXT4_FEATURE_COMPAT_DIR_INDEX) { + ext4_dprintf(EXT4_DEBUG_FS, "dir_index\n"); + } } static void ext4_fs_debug_features_ro(uint32_t features_ro) { - if (features_ro & EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) { - ext4_dprintf(EXT4_DEBUG_FS, "sparse_super\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_LARGE_FILE) { - ext4_dprintf(EXT4_DEBUG_FS, "large_file\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_BTREE_DIR) { - ext4_dprintf(EXT4_DEBUG_FS, "btree_dir\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) { - ext4_dprintf(EXT4_DEBUG_FS, "huge_file\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { - ext4_dprintf(EXT4_DEBUG_FS, "gtd_csum\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) { - ext4_dprintf(EXT4_DEBUG_FS, "dir_nlink\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) { - ext4_dprintf(EXT4_DEBUG_FS, "extra_isize\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_QUOTA) { - ext4_dprintf(EXT4_DEBUG_FS, "quota\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_BIGALLOC) { - ext4_dprintf(EXT4_DEBUG_FS, "bigalloc\n"); - } - if (features_ro & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) { - ext4_dprintf(EXT4_DEBUG_FS, "metadata_csum\n"); - } + if (features_ro & EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) { + ext4_dprintf(EXT4_DEBUG_FS, "sparse_super\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_LARGE_FILE) { + ext4_dprintf(EXT4_DEBUG_FS, "large_file\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_BTREE_DIR) { + ext4_dprintf(EXT4_DEBUG_FS, "btree_dir\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) { + ext4_dprintf(EXT4_DEBUG_FS, "huge_file\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { + ext4_dprintf(EXT4_DEBUG_FS, "gtd_csum\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) { + ext4_dprintf(EXT4_DEBUG_FS, "dir_nlink\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) { + ext4_dprintf(EXT4_DEBUG_FS, "extra_isize\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_QUOTA) { + ext4_dprintf(EXT4_DEBUG_FS, "quota\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_BIGALLOC) { + ext4_dprintf(EXT4_DEBUG_FS, "bigalloc\n"); + } + if (features_ro & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) { + ext4_dprintf(EXT4_DEBUG_FS, "metadata_csum\n"); + } } int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only) { - ext4_assert(fs && read_only); - uint32_t v; - if (ext4_get32(&fs->sb, rev_level) == 0) { - *read_only = false; - return EOK; - } - - ext4_dprintf(EXT4_DEBUG_FS, "\nSB features_incompatible:\n"); - ext4_fs_debug_features_incomp(ext4_get32(&fs->sb, features_incompatible)); - - ext4_dprintf(EXT4_DEBUG_FS, "\nSB features_compatible:\n"); - ext4_fs_debug_features_comp(ext4_get32(&fs->sb, features_compatible)); - - ext4_dprintf(EXT4_DEBUG_FS, "\nSB features_read_only:\n"); - ext4_fs_debug_features_ro(ext4_get32(&fs->sb, features_read_only)); - - /*Check features_incompatible*/ - v = (ext4_get32(&fs->sb, features_incompatible) & - (~CONFIG_FEATURE_INCOMPAT_SUPP)); - if (v) { - ext4_dprintf(EXT4_DEBUG_FS, "SB features_incompatible: fail\n"); - ext4_fs_debug_features_incomp(v); - return ENOTSUP; - } - - /*Check features_read_only*/ - v = (ext4_get32(&fs->sb, features_read_only) & - (~CONFIG_FEATURE_RO_COMPAT_SUPP)); - if (v) { - ext4_dprintf(EXT4_DEBUG_FS, - "\nERROR sblock features_read_only . Unsupported:\n"); - ext4_fs_debug_features_incomp(v); - - *read_only = true; - return EOK; - } - *read_only = false; - - return EOK; + ext4_assert(fs && read_only); + uint32_t v; + if (ext4_get32(&fs->sb, rev_level) == 0) { + *read_only = false; + return EOK; + } + + ext4_dprintf(EXT4_DEBUG_FS, "\nSB features_incompatible:\n"); + ext4_fs_debug_features_incomp( + ext4_get32(&fs->sb, features_incompatible)); + + ext4_dprintf(EXT4_DEBUG_FS, "\nSB features_compatible:\n"); + ext4_fs_debug_features_comp(ext4_get32(&fs->sb, features_compatible)); + + ext4_dprintf(EXT4_DEBUG_FS, "\nSB features_read_only:\n"); + ext4_fs_debug_features_ro(ext4_get32(&fs->sb, features_read_only)); + + /*Check features_incompatible*/ + v = (ext4_get32(&fs->sb, features_incompatible) & + (~CONFIG_FEATURE_INCOMPAT_SUPP)); + if (v) { + ext4_dprintf(EXT4_DEBUG_FS, "SB features_incompatible: fail\n"); + ext4_fs_debug_features_incomp(v); + return ENOTSUP; + } + + /*Check features_read_only*/ + v = (ext4_get32(&fs->sb, features_read_only) & + (~CONFIG_FEATURE_RO_COMPAT_SUPP)); + if (v) { + ext4_dprintf( + EXT4_DEBUG_FS, + "\nERROR sblock features_read_only . Unsupported:\n"); + ext4_fs_debug_features_incomp(v); + + *read_only = true; + return EOK; + } + *read_only = false; + + return EOK; } /**@brief Initialize block bitmap in block group. @@ -275,34 +277,36 @@ int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only) */ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref) { - uint32_t i; - uint32_t bitmap_block_addr = - ext4_bg_get_block_bitmap(bg_ref->block_group, &bg_ref->fs->sb); + uint32_t i; + uint32_t bitmap_block_addr = + ext4_bg_get_block_bitmap(bg_ref->block_group, &bg_ref->fs->sb); - struct ext4_block block_bitmap; - int rc = ext4_block_get(bg_ref->fs->bdev, &block_bitmap, bitmap_block_addr); - if (rc != EOK) - return rc; + struct ext4_block block_bitmap; + int rc = + ext4_block_get(bg_ref->fs->bdev, &block_bitmap, bitmap_block_addr); + if (rc != EOK) + return rc; - memset(block_bitmap.data, 0, ext4_sb_get_block_size(&bg_ref->fs->sb)); + memset(block_bitmap.data, 0, ext4_sb_get_block_size(&bg_ref->fs->sb)); - /* Determine first block and first data block in group */ - uint32_t first_idx = 0; + /* Determine first block and first data block in group */ + uint32_t first_idx = 0; - uint32_t first_data = - ext4_balloc_get_first_data_block_in_group(&bg_ref->fs->sb, bg_ref); - uint32_t first_data_idx = - ext4_fs_baddr2_index_in_group(&bg_ref->fs->sb, first_data); + uint32_t first_data = + ext4_balloc_get_first_data_block_in_group(&bg_ref->fs->sb, bg_ref); + uint32_t first_data_idx = + ext4_fs_baddr2_index_in_group(&bg_ref->fs->sb, first_data); - /*Set bits from to first block to first data block - 1 to one (allocated)*/ - /*TODO: Optimize it*/ - for (i = first_idx; i < first_data_idx; ++i) - ext4_bmap_bit_set(block_bitmap.data, i); + /*Set bits from to first block to first data block - 1 to one + * (allocated)*/ + /*TODO: Optimize it*/ + for (i = first_idx; i < first_data_idx; ++i) + ext4_bmap_bit_set(block_bitmap.data, i); - block_bitmap.dirty = true; + block_bitmap.dirty = true; - /* Save bitmap */ - return ext4_block_set(bg_ref->fs->bdev, &block_bitmap); + /* Save bitmap */ + return ext4_block_set(bg_ref->fs->bdev, &block_bitmap); } /**@brief Initialize i-node bitmap in block group. @@ -311,35 +315,37 @@ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref) */ static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref) { - /* Load bitmap */ - uint32_t bitmap_block_addr = - ext4_bg_get_inode_bitmap(bg_ref->block_group, &bg_ref->fs->sb); + /* Load bitmap */ + uint32_t bitmap_block_addr = + ext4_bg_get_inode_bitmap(bg_ref->block_group, &bg_ref->fs->sb); - struct ext4_block block_bitmap; - int rc = ext4_block_get(bg_ref->fs->bdev, &block_bitmap, bitmap_block_addr); - if (rc != EOK) - return rc; + struct ext4_block block_bitmap; + int rc = + ext4_block_get(bg_ref->fs->bdev, &block_bitmap, bitmap_block_addr); + if (rc != EOK) + return rc; - /* Initialize all bitmap bits to zero */ - uint32_t block_size = ext4_sb_get_block_size(&bg_ref->fs->sb); - uint32_t inodes_per_group = ext4_get32(&bg_ref->fs->sb, inodes_per_group); + /* Initialize all bitmap bits to zero */ + uint32_t block_size = ext4_sb_get_block_size(&bg_ref->fs->sb); + uint32_t inodes_per_group = + ext4_get32(&bg_ref->fs->sb, inodes_per_group); - memset(block_bitmap.data, 0, (inodes_per_group + 7) / 8); + memset(block_bitmap.data, 0, (inodes_per_group + 7) / 8); - uint32_t start_bit = inodes_per_group; - uint32_t end_bit = block_size * 8; + uint32_t start_bit = inodes_per_group; + uint32_t end_bit = block_size * 8; - uint32_t i; - for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) - ext4_bmap_bit_set(block_bitmap.data, i); + uint32_t i; + for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) + ext4_bmap_bit_set(block_bitmap.data, i); - if (i < end_bit) - memset(block_bitmap.data + (i >> 3), 0xff, (end_bit - i) >> 3); + if (i < end_bit) + memset(block_bitmap.data + (i >> 3), 0xff, (end_bit - i) >> 3); - block_bitmap.dirty = true; + block_bitmap.dirty = true; - /* Save bitmap */ - return ext4_block_set(bg_ref->fs->bdev, &block_bitmap); + /* Save bitmap */ + return ext4_block_set(bg_ref->fs->bdev, &block_bitmap); } /**@brief Initialize i-node table in block group. @@ -348,121 +354,127 @@ static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref) */ static int ext4_fs_init_inode_table(struct ext4_block_group_ref *bg_ref) { - struct ext4_sblock *sb = &bg_ref->fs->sb; + struct ext4_sblock *sb = &bg_ref->fs->sb; - uint32_t inode_size = ext4_get32(sb, inode_size); - uint32_t block_size = ext4_sb_get_block_size(sb); - uint32_t inodes_per_block = block_size / inode_size; - uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bg_ref->index); - uint32_t table_blocks = inodes_in_group / inodes_per_block; - uint32_t fblock; + uint32_t inode_size = ext4_get32(sb, inode_size); + uint32_t block_size = ext4_sb_get_block_size(sb); + uint32_t inodes_per_block = block_size / inode_size; + uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bg_ref->index); + uint32_t table_blocks = inodes_in_group / inodes_per_block; + uint32_t fblock; - if (inodes_in_group % inodes_per_block) - table_blocks++; + if (inodes_in_group % inodes_per_block) + table_blocks++; - /* Compute initialization bounds */ - uint32_t first_block = - ext4_bg_get_inode_table_first_block(bg_ref->block_group, sb); + /* Compute initialization bounds */ + uint32_t first_block = + ext4_bg_get_inode_table_first_block(bg_ref->block_group, sb); - uint32_t last_block = first_block + table_blocks - 1; + uint32_t last_block = first_block + table_blocks - 1; - /* Initialization of all itable blocks */ - for (fblock = first_block; fblock <= last_block; ++fblock) { + /* Initialization of all itable blocks */ + for (fblock = first_block; fblock <= last_block; ++fblock) { - struct ext4_block block; - int rc = ext4_block_get(bg_ref->fs->bdev, &block, fblock); - if (rc != EOK) - return rc; + struct ext4_block block; + int rc = ext4_block_get(bg_ref->fs->bdev, &block, fblock); + if (rc != EOK) + return rc; - memset(block.data, 0, block_size); - block.dirty = true; + memset(block.data, 0, block_size); + block.dirty = true; - ext4_block_set(bg_ref->fs->bdev, &block); - if (rc != EOK) - return rc; - } + ext4_block_set(bg_ref->fs->bdev, &block); + if (rc != EOK) + return rc; + } - return EOK; + return EOK; } static uint64_t ext4_fs_get_descriptor_block(struct ext4_sblock *s, - uint32_t bgid, - uint32_t dsc_per_block) + uint32_t bgid, + uint32_t dsc_per_block) { - uint32_t first_meta_bg, dsc_id; + uint32_t first_meta_bg, dsc_id; - int has_super = 0; + int has_super = 0; - dsc_id = bgid / dsc_per_block; - first_meta_bg = ext4_sb_first_meta_bg(s); + dsc_id = bgid / dsc_per_block; + first_meta_bg = ext4_sb_first_meta_bg(s); - if (!ext4_sb_has_feature_incompatible(s, EXT4_FEATURE_INCOMPAT_META_BG) || - dsc_id < first_meta_bg) - return ext4_get32(s, first_data_block) + dsc_id + 1; + if (!ext4_sb_has_feature_incompatible(s, + EXT4_FEATURE_INCOMPAT_META_BG) || + dsc_id < first_meta_bg) + return ext4_get32(s, first_data_block) + dsc_id + 1; - if (ext4_sb_is_super_in_bg(s, bgid)) - has_super = 1; + if (ext4_sb_is_super_in_bg(s, bgid)) + has_super = 1; - return (has_super + ext4_fs_first_bg_block_no(s, bgid)); + return (has_super + ext4_fs_first_bg_block_no(s, bgid)); } int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid, - struct ext4_block_group_ref *ref) + struct ext4_block_group_ref *ref) { - /* Compute number of descriptors, that fits in one data block */ - uint32_t dsc_per_block = - ext4_sb_get_block_size(&fs->sb) / ext4_sb_get_desc_size(&fs->sb); - - /* Block group descriptor table starts at the next block after superblock */ - uint64_t block_id = - ext4_fs_get_descriptor_block(&fs->sb, bgid, dsc_per_block); - - uint32_t offset = (bgid % dsc_per_block) * ext4_sb_get_desc_size(&fs->sb); - - int rc = ext4_block_get(fs->bdev, &ref->block, block_id); - if (rc != EOK) - return rc; - - ref->block_group = (void *)(ref->block.data + offset); - ref->fs = fs; - ref->index = bgid; - ref->dirty = false; - - if (ext4_bg_has_flag(ref->block_group, EXT4_BLOCK_GROUP_BLOCK_UNINIT)) { - rc = ext4_fs_init_block_bitmap(ref); - if (rc != EOK) { - ext4_block_set(fs->bdev, &ref->block); - return rc; - } - ext4_bg_clear_flag(ref->block_group, EXT4_BLOCK_GROUP_BLOCK_UNINIT); - - ref->dirty = true; - } - - if (ext4_bg_has_flag(ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT)) { - rc = ext4_fs_init_inode_bitmap(ref); - if (rc != EOK) { - ext4_block_set(ref->fs->bdev, &ref->block); - return rc; - } - - ext4_bg_clear_flag(ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT); - - if (!ext4_bg_has_flag(ref->block_group, - EXT4_BLOCK_GROUP_ITABLE_ZEROED)) { - rc = ext4_fs_init_inode_table(ref); - if (rc != EOK) { - ext4_block_set(fs->bdev, &ref->block); - return rc; - } - - ext4_bg_set_flag(ref->block_group, EXT4_BLOCK_GROUP_ITABLE_ZEROED); - } - - ref->dirty = true; - } - - return EOK; + /* Compute number of descriptors, that fits in one data block */ + uint32_t dsc_per_block = + ext4_sb_get_block_size(&fs->sb) / ext4_sb_get_desc_size(&fs->sb); + + /* Block group descriptor table starts at the next block after + * superblock */ + uint64_t block_id = + ext4_fs_get_descriptor_block(&fs->sb, bgid, dsc_per_block); + + uint32_t offset = + (bgid % dsc_per_block) * ext4_sb_get_desc_size(&fs->sb); + + int rc = ext4_block_get(fs->bdev, &ref->block, block_id); + if (rc != EOK) + return rc; + + ref->block_group = (void *)(ref->block.data + offset); + ref->fs = fs; + ref->index = bgid; + ref->dirty = false; + + if (ext4_bg_has_flag(ref->block_group, EXT4_BLOCK_GROUP_BLOCK_UNINIT)) { + rc = ext4_fs_init_block_bitmap(ref); + if (rc != EOK) { + ext4_block_set(fs->bdev, &ref->block); + return rc; + } + ext4_bg_clear_flag(ref->block_group, + EXT4_BLOCK_GROUP_BLOCK_UNINIT); + + ref->dirty = true; + } + + if (ext4_bg_has_flag(ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT)) { + rc = ext4_fs_init_inode_bitmap(ref); + if (rc != EOK) { + ext4_block_set(ref->fs->bdev, &ref->block); + return rc; + } + + ext4_bg_clear_flag(ref->block_group, + EXT4_BLOCK_GROUP_INODE_UNINIT); + + if (!ext4_bg_has_flag(ref->block_group, + EXT4_BLOCK_GROUP_ITABLE_ZEROED)) { + rc = ext4_fs_init_inode_table(ref); + if (rc != EOK) { + ext4_block_set(fs->bdev, &ref->block); + return rc; + } + + ext4_bg_set_flag(ref->block_group, + EXT4_BLOCK_GROUP_ITABLE_ZEROED); + } + + ref->dirty = true; + } + + return EOK; } /**@brief Compute checksum of block group descriptor. @@ -472,851 +484,888 @@ int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid, * @return Checksum value */ static uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid, - struct ext4_bgroup *bg) + struct ext4_bgroup *bg) { - /* If checksum not supported, 0 will be returned */ - uint16_t crc = 0; + /* If checksum not supported, 0 will be returned */ + uint16_t crc = 0; - /* Compute the checksum only if the filesystem supports it */ - if (ext4_sb_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { - uint8_t *base = (uint8_t *)bg; - uint8_t *checksum = (uint8_t *)&bg->checksum; + /* Compute the checksum only if the filesystem supports it */ + if (ext4_sb_has_feature_read_only(sb, + EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { + uint8_t *base = (uint8_t *)bg; + uint8_t *checksum = (uint8_t *)&bg->checksum; - uint32_t offset = (uint32_t)(checksum - base); + uint32_t offset = (uint32_t)(checksum - base); - /* Convert block group index to little endian */ - uint32_t le_group = to_le32(bgid); + /* Convert block group index to little endian */ + uint32_t le_group = to_le32(bgid); - /* Initialization */ - crc = ext4_bg_crc16(~0, sb->uuid, sizeof(sb->uuid)); + /* Initialization */ + crc = ext4_bg_crc16(~0, sb->uuid, sizeof(sb->uuid)); - /* Include index of block group */ - crc = ext4_bg_crc16(crc, (uint8_t *)&le_group, sizeof(le_group)); + /* Include index of block group */ + crc = + ext4_bg_crc16(crc, (uint8_t *)&le_group, sizeof(le_group)); - /* Compute crc from the first part (stop before checksum field) */ - crc = ext4_bg_crc16(crc, (uint8_t *)bg, offset); + /* Compute crc from the first part (stop before checksum field) + */ + crc = ext4_bg_crc16(crc, (uint8_t *)bg, offset); - /* Skip checksum */ - offset += sizeof(bg->checksum); + /* Skip checksum */ + offset += sizeof(bg->checksum); - /* Checksum of the rest of block group descriptor */ - if ((ext4_sb_has_feature_incompatible(sb, - EXT4_FEATURE_INCOMPAT_64BIT)) && - (offset < ext4_sb_get_desc_size(sb))) + /* Checksum of the rest of block group descriptor */ + if ((ext4_sb_has_feature_incompatible( + sb, EXT4_FEATURE_INCOMPAT_64BIT)) && + (offset < ext4_sb_get_desc_size(sb))) - crc = ext4_bg_crc16(crc, ((uint8_t *)bg) + offset, - ext4_sb_get_desc_size(sb) - offset); - } - return crc; + crc = ext4_bg_crc16(crc, ((uint8_t *)bg) + offset, + ext4_sb_get_desc_size(sb) - offset); + } + return crc; } int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref) { - /* Check if reference modified */ - if (ref->dirty) { - /* Compute new checksum of block group */ - uint16_t checksum = - ext4_fs_bg_checksum(&ref->fs->sb, ref->index, ref->block_group); + /* Check if reference modified */ + if (ref->dirty) { + /* Compute new checksum of block group */ + uint16_t checksum = ext4_fs_bg_checksum( + &ref->fs->sb, ref->index, ref->block_group); - ref->block_group->checksum = to_le16(checksum); + ref->block_group->checksum = to_le16(checksum); - /* Mark block dirty for writing changes to physical device */ - ref->block.dirty = true; - } + /* Mark block dirty for writing changes to physical device */ + ref->block.dirty = true; + } - /* Put back block, that contains block group descriptor */ - return ext4_block_set(ref->fs->bdev, &ref->block); + /* Put back block, that contains block group descriptor */ + return ext4_block_set(ref->fs->bdev, &ref->block); } int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index, - struct ext4_inode_ref *ref) + struct ext4_inode_ref *ref) { - /* Compute number of i-nodes, that fits in one data block */ - uint32_t inodes_per_group = ext4_get32(&fs->sb, inodes_per_group); - - /* - * Inode numbers are 1-based, but it is simpler to work with 0-based - * when computing indices - */ - index -= 1; - uint32_t block_group = index / inodes_per_group; - uint32_t offset_in_group = index % inodes_per_group; - - /* Load block group, where i-node is located */ - struct ext4_block_group_ref bg_ref; - - int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref); - if (rc != EOK) { - return rc; - } - - /* Load block address, where i-node table is located */ - uint32_t inode_table_start = - ext4_bg_get_inode_table_first_block(bg_ref.block_group, &fs->sb); - - /* Put back block group reference (not needed more) */ - rc = ext4_fs_put_block_group_ref(&bg_ref); - if (rc != EOK) { - return rc; - } - - /* Compute position of i-node in the block group */ - uint16_t inode_size = ext4_get16(&fs->sb, inode_size); - uint32_t block_size = ext4_sb_get_block_size(&fs->sb); - uint32_t byte_offset_in_group = offset_in_group * inode_size; - - /* Compute block address */ - uint64_t block_id = inode_table_start + (byte_offset_in_group / block_size); - - rc = ext4_block_get(fs->bdev, &ref->block, block_id); - if (rc != EOK) { - return rc; - } - - /* Compute position of i-node in the data block */ - uint32_t offset_in_block = byte_offset_in_group % block_size; - ref->inode = (struct ext4_inode *)(ref->block.data + offset_in_block); - - /* We need to store the original value of index in the reference */ - ref->index = index + 1; - ref->fs = fs; - ref->dirty = false; - - return EOK; + /* Compute number of i-nodes, that fits in one data block */ + uint32_t inodes_per_group = ext4_get32(&fs->sb, inodes_per_group); + + /* + * Inode numbers are 1-based, but it is simpler to work with 0-based + * when computing indices + */ + index -= 1; + uint32_t block_group = index / inodes_per_group; + uint32_t offset_in_group = index % inodes_per_group; + + /* Load block group, where i-node is located */ + struct ext4_block_group_ref bg_ref; + + int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref); + if (rc != EOK) { + return rc; + } + + /* Load block address, where i-node table is located */ + uint32_t inode_table_start = + ext4_bg_get_inode_table_first_block(bg_ref.block_group, &fs->sb); + + /* Put back block group reference (not needed more) */ + rc = ext4_fs_put_block_group_ref(&bg_ref); + if (rc != EOK) { + return rc; + } + + /* Compute position of i-node in the block group */ + uint16_t inode_size = ext4_get16(&fs->sb, inode_size); + uint32_t block_size = ext4_sb_get_block_size(&fs->sb); + uint32_t byte_offset_in_group = offset_in_group * inode_size; + + /* Compute block address */ + uint64_t block_id = + inode_table_start + (byte_offset_in_group / block_size); + + rc = ext4_block_get(fs->bdev, &ref->block, block_id); + if (rc != EOK) { + return rc; + } + + /* Compute position of i-node in the data block */ + uint32_t offset_in_block = byte_offset_in_group % block_size; + ref->inode = (struct ext4_inode *)(ref->block.data + offset_in_block); + + /* We need to store the original value of index in the reference */ + ref->index = index + 1; + ref->fs = fs; + ref->dirty = false; + + return EOK; } int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref) { - /* Check if reference modified */ - if (ref->dirty) { - /* Mark block dirty for writing changes to physical device */ - ref->block.dirty = true; - } - - /* Put back block, that contains i-node */ - return ext4_block_set(ref->fs->bdev, &ref->block); + /* Check if reference modified */ + if (ref->dirty) { + /* Mark block dirty for writing changes to physical device */ + ref->block.dirty = true; + } + + /* Put back block, that contains i-node */ + return ext4_block_set(ref->fs->bdev, &ref->block); } int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, - bool is_directory) + bool is_directory) { - /* Check if newly allocated i-node will be a directory */ - uint32_t i; - bool is_dir; - - is_dir = is_directory; - - /* Allocate inode by allocation algorithm */ - uint32_t index; - int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir); - if (rc != EOK) - return rc; - - /* Load i-node from on-disk i-node table */ - rc = ext4_fs_get_inode_ref(fs, index, inode_ref); - if (rc != EOK) { - ext4_ialloc_free_inode(fs, index, is_dir); - return rc; - } - - /* Initialize i-node */ - struct ext4_inode *inode = inode_ref->inode; - - uint16_t mode; - if (is_dir) { - /* - * Default directory permissions to be compatible with other systems - * 0777 (octal) == rwxrwxrwx - */ - - mode = 0777; - mode |= EXT4_INODE_MODE_DIRECTORY; - ext4_inode_set_mode(&fs->sb, inode, mode); - } else { - /* - * Default file permissions to be compatible with other systems - * 0666 (octal) == rw-rw-rw- - */ - - mode = 0666; - mode |= EXT4_INODE_MODE_FILE; - ext4_inode_set_mode(&fs->sb, inode, mode); - } - - ext4_inode_set_links_count(inode, 0); - ext4_inode_set_uid(inode, 0); - ext4_inode_set_gid(inode, 0); - ext4_inode_set_size(inode, 0); - ext4_inode_set_access_time(inode, 0); - ext4_inode_set_change_inode_time(inode, 0); - ext4_inode_set_modification_time(inode, 0); - ext4_inode_set_deletion_time(inode, 0); - ext4_inode_set_blocks_count(&fs->sb, inode, 0); - ext4_inode_set_flags(inode, 0); - ext4_inode_set_generation(inode, 0); - - /* Reset blocks array */ - for (i = 0; i < EXT4_INODE_BLOCKS; i++) - inode->blocks[i] = 0; + /* Check if newly allocated i-node will be a directory */ + uint32_t i; + bool is_dir; + + is_dir = is_directory; + + /* Allocate inode by allocation algorithm */ + uint32_t index; + int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir); + if (rc != EOK) + return rc; + + /* Load i-node from on-disk i-node table */ + rc = ext4_fs_get_inode_ref(fs, index, inode_ref); + if (rc != EOK) { + ext4_ialloc_free_inode(fs, index, is_dir); + return rc; + } + + /* Initialize i-node */ + struct ext4_inode *inode = inode_ref->inode; + + uint16_t mode; + if (is_dir) { + /* + * Default directory permissions to be compatible with other + * systems + * 0777 (octal) == rwxrwxrwx + */ + + mode = 0777; + mode |= EXT4_INODE_MODE_DIRECTORY; + ext4_inode_set_mode(&fs->sb, inode, mode); + } else { + /* + * Default file permissions to be compatible with other systems + * 0666 (octal) == rw-rw-rw- + */ + + mode = 0666; + mode |= EXT4_INODE_MODE_FILE; + ext4_inode_set_mode(&fs->sb, inode, mode); + } + + ext4_inode_set_links_count(inode, 0); + ext4_inode_set_uid(inode, 0); + ext4_inode_set_gid(inode, 0); + ext4_inode_set_size(inode, 0); + ext4_inode_set_access_time(inode, 0); + ext4_inode_set_change_inode_time(inode, 0); + ext4_inode_set_modification_time(inode, 0); + ext4_inode_set_deletion_time(inode, 0); + ext4_inode_set_blocks_count(&fs->sb, inode, 0); + ext4_inode_set_flags(inode, 0); + ext4_inode_set_generation(inode, 0); + + /* Reset blocks array */ + for (i = 0; i < EXT4_INODE_BLOCKS; i++) + inode->blocks[i] = 0; #if CONFIG_EXTENT_ENABLE - /* Initialize extents if needed */ - if (ext4_sb_has_feature_incompatible(&fs->sb, - EXT4_FEATURE_INCOMPAT_EXTENTS)) { - ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS); - - /* Initialize extent root header */ - struct ext4_extent_header *header = ext4_inode_get_extent_header(inode); - ext4_extent_header_set_depth(header, 0); - ext4_extent_header_set_entries_count(header, 0); - ext4_extent_header_set_generation(header, 0); - ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC); - - uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) - - sizeof(struct ext4_extent_header)) / - sizeof(struct ext4_extent); - - ext4_extent_header_set_max_entries_count(header, max_entries); - } + /* Initialize extents if needed */ + if (ext4_sb_has_feature_incompatible(&fs->sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) { + ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS); + + /* Initialize extent root header */ + struct ext4_extent_header *header = + ext4_inode_get_extent_header(inode); + ext4_extent_header_set_depth(header, 0); + ext4_extent_header_set_entries_count(header, 0); + ext4_extent_header_set_generation(header, 0); + ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC); + + uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) - + sizeof(struct ext4_extent_header)) / + sizeof(struct ext4_extent); + + ext4_extent_header_set_max_entries_count(header, max_entries); + } #endif - inode_ref->dirty = true; + inode_ref->dirty = true; - return EOK; + return EOK; } int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref) { - struct ext4_fs *fs = inode_ref->fs; - uint32_t offset; - uint32_t suboffset; + struct ext4_fs *fs = inode_ref->fs; + uint32_t offset; + uint32_t suboffset; #if CONFIG_EXTENT_ENABLE - /* For extents must be data block destroyed by other way */ - if ((ext4_sb_has_feature_incompatible(&fs->sb, - EXT4_FEATURE_INCOMPAT_EXTENTS)) && - (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - /* Data structures are released during truncate operation... */ - goto finish; - } + /* For extents must be data block destroyed by other way */ + if ((ext4_sb_has_feature_incompatible(&fs->sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) && + (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { + /* Data structures are released during truncate operation... */ + goto finish; + } #endif - /* Release all indirect (no data) blocks */ - - /* 1) Single indirect */ - uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0); - if (fblock != 0) { - int rc = ext4_balloc_free_block(inode_ref, fblock); - if (rc != EOK) - return rc; - - ext4_inode_set_indirect_block(inode_ref->inode, 0, 0); - } - - uint32_t block_size = ext4_sb_get_block_size(&fs->sb); - uint32_t count = block_size / sizeof(uint32_t); - - struct ext4_block block; - - /* 2) Double indirect */ - fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1); - if (fblock != 0) { - int rc = ext4_block_get(fs->bdev, &block, fblock); - if (rc != EOK) - return rc; - - uint32_t ind_block; - for (offset = 0; offset < count; ++offset) { - ind_block = to_le32(((uint32_t *)block.data)[offset]); - - if (ind_block != 0) { - rc = ext4_balloc_free_block(inode_ref, ind_block); - if (rc != EOK) { - ext4_block_set(fs->bdev, &block); - return rc; - } - } - } - - ext4_block_set(fs->bdev, &block); - rc = ext4_balloc_free_block(inode_ref, fblock); - if (rc != EOK) - return rc; - - ext4_inode_set_indirect_block(inode_ref->inode, 1, 0); - } - - /* 3) Tripple indirect */ - struct ext4_block subblock; - fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2); - if (fblock != 0) { - int rc = ext4_block_get(fs->bdev, &block, fblock); - if (rc != EOK) - return rc; - - uint32_t ind_block; - for (offset = 0; offset < count; ++offset) { - ind_block = to_le32(((uint32_t *)block.data)[offset]); - - if (ind_block != 0) { - rc = ext4_block_get(fs->bdev, &subblock, ind_block); - if (rc != EOK) { - ext4_block_set(fs->bdev, &block); - return rc; - } - - uint32_t ind_subblock; - for (suboffset = 0; suboffset < count; ++suboffset) { - ind_subblock = - to_le32(((uint32_t *)subblock.data)[suboffset]); - - if (ind_subblock != 0) { - rc = ext4_balloc_free_block(inode_ref, ind_subblock); - if (rc != EOK) { - ext4_block_set(fs->bdev, &subblock); - ext4_block_set(fs->bdev, &block); - return rc; - } - } - } - - ext4_block_set(fs->bdev, &subblock); - - rc = ext4_balloc_free_block(inode_ref, ind_block); - if (rc != EOK) { - ext4_block_set(fs->bdev, &block); - return rc; - } - } - } - - ext4_block_set(fs->bdev, &block); - rc = ext4_balloc_free_block(inode_ref, fblock); - if (rc != EOK) - return rc; - - ext4_inode_set_indirect_block(inode_ref->inode, 2, 0); - } + /* Release all indirect (no data) blocks */ + + /* 1) Single indirect */ + uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0); + if (fblock != 0) { + int rc = ext4_balloc_free_block(inode_ref, fblock); + if (rc != EOK) + return rc; + + ext4_inode_set_indirect_block(inode_ref->inode, 0, 0); + } + + uint32_t block_size = ext4_sb_get_block_size(&fs->sb); + uint32_t count = block_size / sizeof(uint32_t); + + struct ext4_block block; + + /* 2) Double indirect */ + fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1); + if (fblock != 0) { + int rc = ext4_block_get(fs->bdev, &block, fblock); + if (rc != EOK) + return rc; + + uint32_t ind_block; + for (offset = 0; offset < count; ++offset) { + ind_block = to_le32(((uint32_t *)block.data)[offset]); + + if (ind_block != 0) { + rc = ext4_balloc_free_block(inode_ref, + ind_block); + if (rc != EOK) { + ext4_block_set(fs->bdev, &block); + return rc; + } + } + } + + ext4_block_set(fs->bdev, &block); + rc = ext4_balloc_free_block(inode_ref, fblock); + if (rc != EOK) + return rc; + + ext4_inode_set_indirect_block(inode_ref->inode, 1, 0); + } + + /* 3) Tripple indirect */ + struct ext4_block subblock; + fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2); + if (fblock != 0) { + int rc = ext4_block_get(fs->bdev, &block, fblock); + if (rc != EOK) + return rc; + + uint32_t ind_block; + for (offset = 0; offset < count; ++offset) { + ind_block = to_le32(((uint32_t *)block.data)[offset]); + + if (ind_block != 0) { + rc = ext4_block_get(fs->bdev, &subblock, + ind_block); + if (rc != EOK) { + ext4_block_set(fs->bdev, &block); + return rc; + } + + uint32_t ind_subblock; + for (suboffset = 0; suboffset < count; + ++suboffset) { + ind_subblock = to_le32( + ((uint32_t *) + subblock.data)[suboffset]); + + if (ind_subblock != 0) { + rc = ext4_balloc_free_block( + inode_ref, ind_subblock); + if (rc != EOK) { + ext4_block_set( + fs->bdev, + &subblock); + ext4_block_set(fs->bdev, + &block); + return rc; + } + } + } + + ext4_block_set(fs->bdev, &subblock); + + rc = ext4_balloc_free_block(inode_ref, + ind_block); + if (rc != EOK) { + ext4_block_set(fs->bdev, &block); + return rc; + } + } + } + + ext4_block_set(fs->bdev, &block); + rc = ext4_balloc_free_block(inode_ref, fblock); + if (rc != EOK) + return rc; + + ext4_inode_set_indirect_block(inode_ref->inode, 2, 0); + } #if CONFIG_EXTENT_ENABLE finish: #endif - /* Mark inode dirty for writing to the physical device */ - inode_ref->dirty = true; - - /* Free block with extended attributes if present */ - uint32_t xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb); - if (xattr_block) { - int rc = ext4_balloc_free_block(inode_ref, xattr_block); - if (rc != EOK) - return rc; - - ext4_inode_set_file_acl(inode_ref->inode, &fs->sb, 0); - } - - /* Free inode by allocator */ - int rc; - if (ext4_inode_is_type(&fs->sb, inode_ref->inode, - EXT4_INODE_MODE_DIRECTORY)) - rc = ext4_ialloc_free_inode(fs, inode_ref->index, true); - else - rc = ext4_ialloc_free_inode(fs, inode_ref->index, false); - - return rc; + /* Mark inode dirty for writing to the physical device */ + inode_ref->dirty = true; + + /* Free block with extended attributes if present */ + uint32_t xattr_block = + ext4_inode_get_file_acl(inode_ref->inode, &fs->sb); + if (xattr_block) { + int rc = ext4_balloc_free_block(inode_ref, xattr_block); + if (rc != EOK) + return rc; + + ext4_inode_set_file_acl(inode_ref->inode, &fs->sb, 0); + } + + /* Free inode by allocator */ + int rc; + if (ext4_inode_is_type(&fs->sb, inode_ref->inode, + EXT4_INODE_MODE_DIRECTORY)) + rc = ext4_ialloc_free_inode(fs, inode_ref->index, true); + else + rc = ext4_ialloc_free_inode(fs, inode_ref->index, false); + + return rc; } int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size) { - struct ext4_sblock *sb = &inode_ref->fs->sb; - uint32_t i; - - /* Check flags, if i-node can be truncated */ - if (!ext4_inode_can_truncate(sb, inode_ref->inode)) - return EINVAL; - - /* If sizes are equal, nothing has to be done. */ - uint64_t old_size = ext4_inode_get_size(sb, inode_ref->inode); - if (old_size == new_size) - return EOK; - - /* It's not supported to make the larger file by truncate operation */ - if (old_size < new_size) - return EINVAL; - - /* Compute how many blocks will be released */ - uint64_t size_diff = old_size - new_size; - uint32_t block_size = ext4_sb_get_block_size(sb); - uint32_t diff_blocks_count = size_diff / block_size; - if (size_diff % block_size != 0) - diff_blocks_count++; - - uint32_t old_blocks_count = old_size / block_size; - if (old_size % block_size != 0) - old_blocks_count++; + struct ext4_sblock *sb = &inode_ref->fs->sb; + uint32_t i; + + /* Check flags, if i-node can be truncated */ + if (!ext4_inode_can_truncate(sb, inode_ref->inode)) + return EINVAL; + + /* If sizes are equal, nothing has to be done. */ + uint64_t old_size = ext4_inode_get_size(sb, inode_ref->inode); + if (old_size == new_size) + return EOK; + + /* It's not supported to make the larger file by truncate operation */ + if (old_size < new_size) + return EINVAL; + + /* Compute how many blocks will be released */ + uint64_t size_diff = old_size - new_size; + uint32_t block_size = ext4_sb_get_block_size(sb); + uint32_t diff_blocks_count = size_diff / block_size; + if (size_diff % block_size != 0) + diff_blocks_count++; + + uint32_t old_blocks_count = old_size / block_size; + if (old_size % block_size != 0) + old_blocks_count++; #if CONFIG_EXTENT_ENABLE - if ((ext4_sb_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) && - (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - - /* Extents require special operation */ - int rc = ext4_extent_release_blocks_from( - inode_ref, old_blocks_count - diff_blocks_count); - if (rc != EOK) - return rc; - } else + if ((ext4_sb_has_feature_incompatible(sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) && + (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { + + /* Extents require special operation */ + int rc = ext4_extent_release_blocks_from( + inode_ref, old_blocks_count - diff_blocks_count); + if (rc != EOK) + return rc; + } else #endif - { - /* Release data blocks from the end of file */ - - /* Starting from 1 because of logical blocks are numbered from 0 */ - for (i = 1; i <= diff_blocks_count; ++i) { - int rc = - ext4_fs_release_inode_block(inode_ref, old_blocks_count - i); - if (rc != EOK) - return rc; - } - } - - /* Update i-node */ - ext4_inode_set_size(inode_ref->inode, new_size); - inode_ref->dirty = true; - - return EOK; + { + /* Release data blocks from the end of file */ + + /* Starting from 1 because of logical blocks are numbered from 0 + */ + for (i = 1; i <= diff_blocks_count; ++i) { + int rc = ext4_fs_release_inode_block( + inode_ref, old_blocks_count - i); + if (rc != EOK) + return rc; + } + } + + /* Update i-node */ + ext4_inode_set_size(inode_ref->inode, new_size); + inode_ref->dirty = true; + + return EOK; } int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, - uint64_t iblock, uint32_t *fblock) + uint64_t iblock, uint32_t *fblock) { - struct ext4_fs *fs = inode_ref->fs; + struct ext4_fs *fs = inode_ref->fs; - /* For empty file is situation simple */ - if (ext4_inode_get_size(&fs->sb, inode_ref->inode) == 0) { - *fblock = 0; - return EOK; - } + /* For empty file is situation simple */ + if (ext4_inode_get_size(&fs->sb, inode_ref->inode) == 0) { + *fblock = 0; + return EOK; + } - uint32_t current_block; + uint32_t current_block; #if CONFIG_EXTENT_ENABLE - /* Handle i-node using extents */ - if ((ext4_sb_has_feature_incompatible(&fs->sb, - EXT4_FEATURE_INCOMPAT_EXTENTS)) && - (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - - int rc = ext4_extent_find_block(inode_ref, iblock, ¤t_block); - if (rc != EOK) - return rc; - - *fblock = current_block; - return EOK; - } + /* Handle i-node using extents */ + if ((ext4_sb_has_feature_incompatible(&fs->sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) && + (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { + + int rc = + ext4_extent_find_block(inode_ref, iblock, ¤t_block); + if (rc != EOK) + return rc; + + *fblock = current_block; + return EOK; + } #endif - struct ext4_inode *inode = inode_ref->inode; - - /* Direct block are read directly from array in i-node structure */ - if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { - current_block = ext4_inode_get_direct_block(inode, (uint32_t)iblock); - *fblock = current_block; - return EOK; - } - - /* Determine indirection level of the target block */ - unsigned int level = 0; - unsigned int i; - for (i = 1; i < 4; i++) { - if (iblock < fs->inode_block_limits[i]) { - level = i; - break; - } - } - - if (level == 0) - return EIO; - - /* Compute offsets for the topmost level */ - uint64_t block_offset_in_level = iblock - fs->inode_block_limits[level - 1]; - current_block = ext4_inode_get_indirect_block(inode, level - 1); - uint32_t offset_in_block = - block_offset_in_level / fs->inode_blocks_per_level[level - 1]; - - /* Sparse file */ - if (current_block == 0) { - *fblock = 0; - return EOK; - } - - struct ext4_block block; - - /* - * Navigate through other levels, until we find the block number - * or find null reference meaning we are dealing with sparse file - */ - while (level > 0) { - /* Load indirect block */ - int rc = ext4_block_get(fs->bdev, &block, current_block); - if (rc != EOK) - return rc; - - /* Read block address from indirect block */ - current_block = to_le32(((uint32_t *)block.data)[offset_in_block]); - - /* Put back indirect block untouched */ - rc = ext4_block_set(fs->bdev, &block); - if (rc != EOK) - return rc; - - /* Check for sparse file */ - if (current_block == 0) { - *fblock = 0; - return EOK; - } - - /* Jump to the next level */ - level--; - - /* Termination condition - we have address of data block loaded */ - if (level == 0) - break; - - /* Visit the next level */ - block_offset_in_level %= fs->inode_blocks_per_level[level]; - offset_in_block = - block_offset_in_level / fs->inode_blocks_per_level[level - 1]; - } - - *fblock = current_block; - - return EOK; + struct ext4_inode *inode = inode_ref->inode; + + /* Direct block are read directly from array in i-node structure */ + if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { + current_block = + ext4_inode_get_direct_block(inode, (uint32_t)iblock); + *fblock = current_block; + return EOK; + } + + /* Determine indirection level of the target block */ + unsigned int level = 0; + unsigned int i; + for (i = 1; i < 4; i++) { + if (iblock < fs->inode_block_limits[i]) { + level = i; + break; + } + } + + if (level == 0) + return EIO; + + /* Compute offsets for the topmost level */ + uint64_t block_offset_in_level = + iblock - fs->inode_block_limits[level - 1]; + current_block = ext4_inode_get_indirect_block(inode, level - 1); + uint32_t offset_in_block = + block_offset_in_level / fs->inode_blocks_per_level[level - 1]; + + /* Sparse file */ + if (current_block == 0) { + *fblock = 0; + return EOK; + } + + struct ext4_block block; + + /* + * Navigate through other levels, until we find the block number + * or find null reference meaning we are dealing with sparse file + */ + while (level > 0) { + /* Load indirect block */ + int rc = ext4_block_get(fs->bdev, &block, current_block); + if (rc != EOK) + return rc; + + /* Read block address from indirect block */ + current_block = + to_le32(((uint32_t *)block.data)[offset_in_block]); + + /* Put back indirect block untouched */ + rc = ext4_block_set(fs->bdev, &block); + if (rc != EOK) + return rc; + + /* Check for sparse file */ + if (current_block == 0) { + *fblock = 0; + return EOK; + } + + /* Jump to the next level */ + level--; + + /* Termination condition - we have address of data block loaded + */ + if (level == 0) + break; + + /* Visit the next level */ + block_offset_in_level %= fs->inode_blocks_per_level[level]; + offset_in_block = block_offset_in_level / + fs->inode_blocks_per_level[level - 1]; + } + + *fblock = current_block; + + return EOK; } int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, - uint64_t iblock, uint32_t fblock) + uint64_t iblock, uint32_t fblock) { - struct ext4_fs *fs = inode_ref->fs; + struct ext4_fs *fs = inode_ref->fs; #if CONFIG_EXTENT_ENABLE - /* Handle inode using extents */ - if ((ext4_sb_has_feature_incompatible(&fs->sb, - EXT4_FEATURE_INCOMPAT_EXTENTS)) && - (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - /* Not reachable */ - return ENOTSUP; - } + /* Handle inode using extents */ + if ((ext4_sb_has_feature_incompatible(&fs->sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) && + (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { + /* Not reachable */ + return ENOTSUP; + } #endif - /* Handle simple case when we are dealing with direct reference */ - if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { - ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock); - inode_ref->dirty = true; - - return EOK; - } - - /* Determine the indirection level needed to get the desired block */ - unsigned int level = 0; - unsigned int i; - for (i = 1; i < 4; i++) { - if (iblock < fs->inode_block_limits[i]) { - level = i; - break; - } - } - - if (level == 0) - return EIO; - - uint32_t block_size = ext4_sb_get_block_size(&fs->sb); - - /* Compute offsets for the topmost level */ - uint64_t block_offset_in_level = iblock - fs->inode_block_limits[level - 1]; - uint32_t current_block = - ext4_inode_get_indirect_block(inode_ref->inode, level - 1); - uint32_t offset_in_block = - block_offset_in_level / fs->inode_blocks_per_level[level - 1]; - - uint32_t new_block_addr; - - struct ext4_block block; - struct ext4_block new_block; - - /* Is needed to allocate indirect block on the i-node level */ - if (current_block == 0) { - /* Allocate new indirect block */ - int rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr); - if (rc != EOK) - return rc; - - /* Update i-node */ - ext4_inode_set_indirect_block(inode_ref->inode, level - 1, - new_block_addr); - inode_ref->dirty = true; - - /* Load newly allocated block */ - rc = ext4_block_get(fs->bdev, &new_block, new_block_addr); - if (rc != EOK) { - ext4_balloc_free_block(inode_ref, new_block_addr); - return rc; - } - - /* Initialize new block */ - memset(new_block.data, 0, block_size); - new_block.dirty = true; - - /* Put back the allocated block */ - rc = ext4_block_set(fs->bdev, &new_block); - if (rc != EOK) - return rc; - - current_block = new_block_addr; - } - - /* - * Navigate through other levels, until we find the block number - * or find null reference meaning we are dealing with sparse file - */ - while (level > 0) { - int rc = ext4_block_get(fs->bdev, &block, current_block); - if (rc != EOK) - return rc; - - current_block = to_le32(((uint32_t *)block.data)[offset_in_block]); - - if ((level > 1) && (current_block == 0)) { - /* Allocate new block */ - rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr); - if (rc != EOK) { - ext4_block_set(fs->bdev, &block); - return rc; - } - - /* Load newly allocated block */ - rc = ext4_block_get(fs->bdev, &new_block, new_block_addr); - - if (rc != EOK) { - ext4_block_set(fs->bdev, &block); - return rc; - } - - /* Initialize allocated block */ - memset(new_block.data, 0, block_size); - new_block.dirty = true; - - rc = ext4_block_set(fs->bdev, &new_block); - if (rc != EOK) { - ext4_block_set(fs->bdev, &block); - return rc; - } - - /* Write block address to the parent */ - ((uint32_t *)block.data)[offset_in_block] = to_le32(new_block_addr); - block.dirty = true; - current_block = new_block_addr; - } - - /* Will be finished, write the fblock address */ - if (level == 1) { - ((uint32_t *)block.data)[offset_in_block] = to_le32(fblock); - block.dirty = true; - } - - rc = ext4_block_set(fs->bdev, &block); - if (rc != EOK) - return rc; - - level--; - - /* - * If we are on the last level, break here as - * there is no next level to visit - */ - if (level == 0) - break; - - /* Visit the next level */ - block_offset_in_level %= fs->inode_blocks_per_level[level]; - offset_in_block = - block_offset_in_level / fs->inode_blocks_per_level[level - 1]; - } - - return EOK; + /* Handle simple case when we are dealing with direct reference */ + if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { + ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, + fblock); + inode_ref->dirty = true; + + return EOK; + } + + /* Determine the indirection level needed to get the desired block */ + unsigned int level = 0; + unsigned int i; + for (i = 1; i < 4; i++) { + if (iblock < fs->inode_block_limits[i]) { + level = i; + break; + } + } + + if (level == 0) + return EIO; + + uint32_t block_size = ext4_sb_get_block_size(&fs->sb); + + /* Compute offsets for the topmost level */ + uint64_t block_offset_in_level = + iblock - fs->inode_block_limits[level - 1]; + uint32_t current_block = + ext4_inode_get_indirect_block(inode_ref->inode, level - 1); + uint32_t offset_in_block = + block_offset_in_level / fs->inode_blocks_per_level[level - 1]; + + uint32_t new_block_addr; + + struct ext4_block block; + struct ext4_block new_block; + + /* Is needed to allocate indirect block on the i-node level */ + if (current_block == 0) { + /* Allocate new indirect block */ + int rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr); + if (rc != EOK) + return rc; + + /* Update i-node */ + ext4_inode_set_indirect_block(inode_ref->inode, level - 1, + new_block_addr); + inode_ref->dirty = true; + + /* Load newly allocated block */ + rc = ext4_block_get(fs->bdev, &new_block, new_block_addr); + if (rc != EOK) { + ext4_balloc_free_block(inode_ref, new_block_addr); + return rc; + } + + /* Initialize new block */ + memset(new_block.data, 0, block_size); + new_block.dirty = true; + + /* Put back the allocated block */ + rc = ext4_block_set(fs->bdev, &new_block); + if (rc != EOK) + return rc; + + current_block = new_block_addr; + } + + /* + * Navigate through other levels, until we find the block number + * or find null reference meaning we are dealing with sparse file + */ + while (level > 0) { + int rc = ext4_block_get(fs->bdev, &block, current_block); + if (rc != EOK) + return rc; + + current_block = + to_le32(((uint32_t *)block.data)[offset_in_block]); + + if ((level > 1) && (current_block == 0)) { + /* Allocate new block */ + rc = + ext4_balloc_alloc_block(inode_ref, &new_block_addr); + if (rc != EOK) { + ext4_block_set(fs->bdev, &block); + return rc; + } + + /* Load newly allocated block */ + rc = ext4_block_get(fs->bdev, &new_block, + new_block_addr); + + if (rc != EOK) { + ext4_block_set(fs->bdev, &block); + return rc; + } + + /* Initialize allocated block */ + memset(new_block.data, 0, block_size); + new_block.dirty = true; + + rc = ext4_block_set(fs->bdev, &new_block); + if (rc != EOK) { + ext4_block_set(fs->bdev, &block); + return rc; + } + + /* Write block address to the parent */ + ((uint32_t *)block.data)[offset_in_block] = + to_le32(new_block_addr); + block.dirty = true; + current_block = new_block_addr; + } + + /* Will be finished, write the fblock address */ + if (level == 1) { + ((uint32_t *)block.data)[offset_in_block] = + to_le32(fblock); + block.dirty = true; + } + + rc = ext4_block_set(fs->bdev, &block); + if (rc != EOK) + return rc; + + level--; + + /* + * If we are on the last level, break here as + * there is no next level to visit + */ + if (level == 0) + break; + + /* Visit the next level */ + block_offset_in_level %= fs->inode_blocks_per_level[level]; + offset_in_block = block_offset_in_level / + fs->inode_blocks_per_level[level - 1]; + } + + return EOK; } int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref, - uint32_t iblock) + uint32_t iblock) { - uint32_t fblock; - - struct ext4_fs *fs = inode_ref->fs; - - /* Extents are handled otherwise = there is not support in this function */ - ext4_assert( - !(ext4_sb_has_feature_incompatible(&fs->sb, - EXT4_FEATURE_INCOMPAT_EXTENTS) && - (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)))); - - struct ext4_inode *inode = inode_ref->inode; - - /* Handle simple case when we are dealing with direct reference */ - if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { - fblock = ext4_inode_get_direct_block(inode, iblock); - - /* Sparse file */ - if (fblock == 0) - return EOK; - - ext4_inode_set_direct_block(inode, iblock, 0); - return ext4_balloc_free_block(inode_ref, fblock); - } - - /* Determine the indirection level needed to get the desired block */ - unsigned int level = 0; - unsigned int i; - for (i = 1; i < 4; i++) { - if (iblock < fs->inode_block_limits[i]) { - level = i; - break; - } - } - - if (level == 0) - return EIO; - - /* Compute offsets for the topmost level */ - uint64_t block_offset_in_level = iblock - fs->inode_block_limits[level - 1]; - uint32_t current_block = ext4_inode_get_indirect_block(inode, level - 1); - uint32_t offset_in_block = - block_offset_in_level / fs->inode_blocks_per_level[level - 1]; - - /* - * Navigate through other levels, until we find the block number - * or find null reference meaning we are dealing with sparse file - */ - struct ext4_block block; - - while (level > 0) { - - /* Sparse check */ - if (current_block == 0) - return EOK; - - int rc = ext4_block_get(fs->bdev, &block, current_block); - if (rc != EOK) - return rc; - - current_block = to_le32(((uint32_t *)block.data)[offset_in_block]); - - /* Set zero if physical data block address found */ - if (level == 1) { - ((uint32_t *)block.data)[offset_in_block] = to_le32(0); - block.dirty = true; - } - - rc = ext4_block_set(fs->bdev, &block); - if (rc != EOK) - return rc; - - level--; - - /* - * If we are on the last level, break here as - * there is no next level to visit - */ - if (level == 0) - break; - - /* Visit the next level */ - block_offset_in_level %= fs->inode_blocks_per_level[level]; - offset_in_block = - block_offset_in_level / fs->inode_blocks_per_level[level - 1]; - } - - fblock = current_block; - if (fblock == 0) - return EOK; - - /* Physical block is not referenced, it can be released */ - return ext4_balloc_free_block(inode_ref, fblock); + uint32_t fblock; + + struct ext4_fs *fs = inode_ref->fs; + + /* Extents are handled otherwise = there is not support in this function + */ + ext4_assert(!( + ext4_sb_has_feature_incompatible(&fs->sb, + EXT4_FEATURE_INCOMPAT_EXTENTS) && + (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)))); + + struct ext4_inode *inode = inode_ref->inode; + + /* Handle simple case when we are dealing with direct reference */ + if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { + fblock = ext4_inode_get_direct_block(inode, iblock); + + /* Sparse file */ + if (fblock == 0) + return EOK; + + ext4_inode_set_direct_block(inode, iblock, 0); + return ext4_balloc_free_block(inode_ref, fblock); + } + + /* Determine the indirection level needed to get the desired block */ + unsigned int level = 0; + unsigned int i; + for (i = 1; i < 4; i++) { + if (iblock < fs->inode_block_limits[i]) { + level = i; + break; + } + } + + if (level == 0) + return EIO; + + /* Compute offsets for the topmost level */ + uint64_t block_offset_in_level = + iblock - fs->inode_block_limits[level - 1]; + uint32_t current_block = + ext4_inode_get_indirect_block(inode, level - 1); + uint32_t offset_in_block = + block_offset_in_level / fs->inode_blocks_per_level[level - 1]; + + /* + * Navigate through other levels, until we find the block number + * or find null reference meaning we are dealing with sparse file + */ + struct ext4_block block; + + while (level > 0) { + + /* Sparse check */ + if (current_block == 0) + return EOK; + + int rc = ext4_block_get(fs->bdev, &block, current_block); + if (rc != EOK) + return rc; + + current_block = + to_le32(((uint32_t *)block.data)[offset_in_block]); + + /* Set zero if physical data block address found */ + if (level == 1) { + ((uint32_t *)block.data)[offset_in_block] = to_le32(0); + block.dirty = true; + } + + rc = ext4_block_set(fs->bdev, &block); + if (rc != EOK) + return rc; + + level--; + + /* + * If we are on the last level, break here as + * there is no next level to visit + */ + if (level == 0) + break; + + /* Visit the next level */ + block_offset_in_level %= fs->inode_blocks_per_level[level]; + offset_in_block = block_offset_in_level / + fs->inode_blocks_per_level[level - 1]; + } + + fblock = current_block; + if (fblock == 0) + return EOK; + + /* Physical block is not referenced, it can be released */ + return ext4_balloc_free_block(inode_ref, fblock); } int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref, - uint32_t *fblock, uint32_t *iblock) + uint32_t *fblock, uint32_t *iblock) { #if CONFIG_EXTENT_ENABLE - /* Handle extents separately */ - if ((ext4_sb_has_feature_incompatible(&inode_ref->fs->sb, - EXT4_FEATURE_INCOMPAT_EXTENTS)) && - (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - return ext4_extent_append_block(inode_ref, iblock, fblock, true); - } + /* Handle extents separately */ + if ((ext4_sb_has_feature_incompatible(&inode_ref->fs->sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) && + (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { + return ext4_extent_append_block(inode_ref, iblock, fblock, + true); + } #endif - struct ext4_sblock *sb = &inode_ref->fs->sb; + struct ext4_sblock *sb = &inode_ref->fs->sb; - /* Compute next block index and allocate data block */ - uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode); - uint32_t block_size = ext4_sb_get_block_size(sb); + /* Compute next block index and allocate data block */ + uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode); + uint32_t block_size = ext4_sb_get_block_size(sb); - /* Align size i-node size */ - if ((inode_size % block_size) != 0) - inode_size += block_size - (inode_size % block_size); + /* Align size i-node size */ + if ((inode_size % block_size) != 0) + inode_size += block_size - (inode_size % block_size); - /* Logical blocks are numbered from 0 */ - uint32_t new_block_idx = inode_size / block_size; + /* Logical blocks are numbered from 0 */ + uint32_t new_block_idx = inode_size / block_size; - /* Allocate new physical block */ - uint32_t phys_block; - int rc = ext4_balloc_alloc_block(inode_ref, &phys_block); - if (rc != EOK) - return rc; + /* Allocate new physical block */ + uint32_t phys_block; + int rc = ext4_balloc_alloc_block(inode_ref, &phys_block); + if (rc != EOK) + return rc; - /* Add physical block address to the i-node */ - rc = ext4_fs_set_inode_data_block_index(inode_ref, new_block_idx, - phys_block); - if (rc != EOK) { - ext4_balloc_free_block(inode_ref, phys_block); - return rc; - } + /* Add physical block address to the i-node */ + rc = ext4_fs_set_inode_data_block_index(inode_ref, new_block_idx, + phys_block); + if (rc != EOK) { + ext4_balloc_free_block(inode_ref, phys_block); + return rc; + } - /* Update i-node */ - ext4_inode_set_size(inode_ref->inode, inode_size + block_size); - inode_ref->dirty = true; + /* Update i-node */ + ext4_inode_set_size(inode_ref->inode, inode_size + block_size); + inode_ref->dirty = true; - *fblock = phys_block; - *iblock = new_block_idx; + *fblock = phys_block; + *iblock = new_block_idx; - return EOK; + return EOK; } void ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref) { - uint16_t link; - - link = ext4_inode_get_links_count(inode_ref->inode); - link++; - ext4_inode_set_links_count(inode_ref->inode, link); - - bool is_dx = ext4_sb_has_feature_compatible( - &inode_ref->fs->sb, EXT4_FEATURE_COMPAT_DIR_INDEX) && - ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_INDEX); - - if (is_dx && link > 1) { - if (link >= EXT4_LINK_MAX || link == 2) { - ext4_inode_set_links_count(inode_ref->inode, 1); - - uint32_t v = ext4_get32(&inode_ref->fs->sb, features_read_only); - v |= EXT4_FEATURE_RO_COMPAT_DIR_NLINK; - ext4_set32(&inode_ref->fs->sb, features_read_only, v); - } - } + uint16_t link; + + link = ext4_inode_get_links_count(inode_ref->inode); + link++; + ext4_inode_set_links_count(inode_ref->inode, link); + + bool is_dx = + ext4_sb_has_feature_compatible(&inode_ref->fs->sb, + EXT4_FEATURE_COMPAT_DIR_INDEX) && + ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_INDEX); + + if (is_dx && link > 1) { + if (link >= EXT4_LINK_MAX || link == 2) { + ext4_inode_set_links_count(inode_ref->inode, 1); + + uint32_t v = + ext4_get32(&inode_ref->fs->sb, features_read_only); + v |= EXT4_FEATURE_RO_COMPAT_DIR_NLINK; + ext4_set32(&inode_ref->fs->sb, features_read_only, v); + } + } } void ext4_fs_inode_links_count_dec(struct ext4_inode_ref *inode_ref) { - uint16_t links = ext4_inode_get_links_count(inode_ref->inode); - if (!ext4_inode_is_type(&inode_ref->fs->sb, inode_ref->inode, - EXT4_INODE_MODE_DIRECTORY)) { - if (links > 0) - ext4_inode_set_links_count(inode_ref->inode, links - 1); - return; - } - - if (links > 2) - ext4_inode_set_links_count(inode_ref->inode, links - 1); + uint16_t links = ext4_inode_get_links_count(inode_ref->inode); + if (!ext4_inode_is_type(&inode_ref->fs->sb, inode_ref->inode, + EXT4_INODE_MODE_DIRECTORY)) { + if (links > 0) + ext4_inode_set_links_count(inode_ref->inode, links - 1); + return; + } + + if (links > 2) + ext4_inode_set_links_count(inode_ref->inode, links - 1); } /** diff --git a/lwext4/ext4_fs.h b/lwext4/ext4_fs.h index 34ee183..ee63ef4 100644 --- a/lwext4/ext4_fs.h +++ b/lwext4/ext4_fs.h @@ -54,13 +54,13 @@ * @return Relative number of block */ static inline uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, - uint32_t baddr) + uint32_t baddr) { - ext4_assert(baddr); - if (ext4_get32(s, first_data_block)) - baddr--; + ext4_assert(baddr); + if (ext4_get32(s, first_data_block)) + baddr--; - return baddr % ext4_get32(s, blocks_per_group); + return baddr % ext4_get32(s, blocks_per_group); } /**@brief Convert relative block address in group to absolute address. @@ -70,21 +70,21 @@ static inline uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, * @return Absolute block address */ static inline uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, - uint32_t index, - uint32_t bgid) + uint32_t index, + uint32_t bgid) { - if (ext4_get32(s, first_data_block)) - index++; + if (ext4_get32(s, first_data_block)) + index++; - return ext4_get32(s, blocks_per_group) * bgid + index; + return ext4_get32(s, blocks_per_group) * bgid + index; } /**@brief TODO: */ static inline uint64_t ext4_fs_first_bg_block_no(struct ext4_sblock *s, - uint32_t bgid) + uint32_t bgid) { - return (uint64_t)bgid * ext4_get32(s, blocks_per_group) + - ext4_get32(s, first_data_block); + return (uint64_t)bgid * ext4_get32(s, blocks_per_group) + + ext4_get32(s, first_data_block); } /**@brief Initialize filesystem and read all needed data. @@ -117,7 +117,7 @@ int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only); * @return Error code */ int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid, - struct ext4_block_group_ref *ref); + struct ext4_block_group_ref *ref); /**@brief Put reference to block group. * @param ref Pointer for reference to be put back @@ -132,7 +132,7 @@ int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref); * @return Error code */ int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index, - struct ext4_inode_ref *ref); + struct ext4_inode_ref *ref); /**@brief Put reference to i-node. * @param ref Pointer for reference to be put back @@ -147,7 +147,7 @@ int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref); * @return Error code */ int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, - bool is_directory); + bool is_directory); /**@brief Release i-node and mark it as free. * @param inode_ref I-node to be released @@ -169,7 +169,7 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size); * @return Error code */ int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, - uint64_t iblock, uint32_t *fblock); + uint64_t iblock, uint32_t *fblock); /**@brief Set physical block address for the block logical address into the * i-node. @@ -179,7 +179,7 @@ int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, * @return Error code */ int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, - uint64_t iblock, uint32_t fblock); + uint64_t iblock, uint32_t fblock); /**@brief Release data block from i-node * @param inode_ref I-node to release block from @@ -187,7 +187,7 @@ int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, * @return Error code */ int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref, - uint32_t iblock); + uint32_t iblock); /**@brief Append following logical block to the i-node. * @param inode_ref I-node to append block to @@ -196,7 +196,7 @@ int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref, * @return Error code */ int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref, - uint32_t *fblock, uint32_t *iblock); + uint32_t *fblock, uint32_t *iblock); /**@brief Increment inode link count. * @param inode none handle diff --git a/lwext4/ext4_hash.c b/lwext4/ext4_hash.c index 39e9afb..95e7502 100644 --- a/lwext4/ext4_hash.c +++ b/lwext4/ext4_hash.c @@ -80,24 +80,24 @@ * Rotation is separated from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s) \
- { \
- (a) += F((b), (c), (d)) + (x); \
- (a) = ROTATE_LEFT((a), (s)); \
- \
+ { \
+ (a) += F((b), (c), (d)) + (x); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ \
}
#define GG(a, b, c, d, x, s) \
- { \
- (a) += G((b), (c), (d)) + (x) + (uint32_t)0x5A827999; \
- (a) = ROTATE_LEFT((a), (s)); \
- \
+ { \
+ (a) += G((b), (c), (d)) + (x) + (uint32_t)0x5A827999; \
+ (a) = ROTATE_LEFT((a), (s)); \
+ \
}
#define HH(a, b, c, d, x, s) \
- { \
- (a) += H((b), (c), (d)) + (x) + (uint32_t)0x6ED9EBA1; \
- (a) = ROTATE_LEFT((a), (s)); \
- \
+ { \
+ (a) += H((b), (c), (d)) + (x) + (uint32_t)0x6ED9EBA1; \
+ (a) = ROTATE_LEFT((a), (s)); \
+ \
}
/*
@@ -113,42 +113,42 @@ */
static void ext2_half_md4(uint32_t hash[4], uint32_t data[8])
{
- uint32_t a = hash[0], b = hash[1], c = hash[2], d = hash[3];
-
- /* Round 1 */
- FF(a, b, c, d, data[0], 3);
- FF(d, a, b, c, data[1], 7);
- FF(c, d, a, b, data[2], 11);
- FF(b, c, d, a, data[3], 19);
- FF(a, b, c, d, data[4], 3);
- FF(d, a, b, c, data[5], 7);
- FF(c, d, a, b, data[6], 11);
- FF(b, c, d, a, data[7], 19);
-
- /* Round 2 */
- GG(a, b, c, d, data[1], 3);
- GG(d, a, b, c, data[3], 5);
- GG(c, d, a, b, data[5], 9);
- GG(b, c, d, a, data[7], 13);
- GG(a, b, c, d, data[0], 3);
- GG(d, a, b, c, data[2], 5);
- GG(c, d, a, b, data[4], 9);
- GG(b, c, d, a, data[6], 13);
-
- /* Round 3 */
- HH(a, b, c, d, data[3], 3);
- HH(d, a, b, c, data[7], 9);
- HH(c, d, a, b, data[2], 11);
- HH(b, c, d, a, data[6], 15);
- HH(a, b, c, d, data[1], 3);
- HH(d, a, b, c, data[5], 9);
- HH(c, d, a, b, data[0], 11);
- HH(b, c, d, a, data[4], 15);
-
- hash[0] += a;
- hash[1] += b;
- hash[2] += c;
- hash[3] += d;
+ uint32_t a = hash[0], b = hash[1], c = hash[2], d = hash[3];
+
+ /* Round 1 */
+ FF(a, b, c, d, data[0], 3);
+ FF(d, a, b, c, data[1], 7);
+ FF(c, d, a, b, data[2], 11);
+ FF(b, c, d, a, data[3], 19);
+ FF(a, b, c, d, data[4], 3);
+ FF(d, a, b, c, data[5], 7);
+ FF(c, d, a, b, data[6], 11);
+ FF(b, c, d, a, data[7], 19);
+
+ /* Round 2 */
+ GG(a, b, c, d, data[1], 3);
+ GG(d, a, b, c, data[3], 5);
+ GG(c, d, a, b, data[5], 9);
+ GG(b, c, d, a, data[7], 13);
+ GG(a, b, c, d, data[0], 3);
+ GG(d, a, b, c, data[2], 5);
+ GG(c, d, a, b, data[4], 9);
+ GG(b, c, d, a, data[6], 13);
+
+ /* Round 3 */
+ HH(a, b, c, d, data[3], 3);
+ HH(d, a, b, c, data[7], 9);
+ HH(c, d, a, b, data[2], 11);
+ HH(b, c, d, a, data[6], 15);
+ HH(a, b, c, d, data[1], 3);
+ HH(d, a, b, c, data[5], 9);
+ HH(c, d, a, b, data[0], 11);
+ HH(b, c, d, a, data[4], 15);
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
}
/*
@@ -156,165 +156,165 @@ static void ext2_half_md4(uint32_t hash[4], uint32_t data[8]) */
static void ext2_tea(uint32_t hash[4], uint32_t data[8])
{
- uint32_t tea_delta = 0x9E3779B9;
- uint32_t sum;
- uint32_t x = hash[0], y = hash[1];
- int n = 16;
- int i = 1;
-
- while (n-- > 0) {
- sum = i * tea_delta;
- x += ((y << 4) + data[0]) ^ (y + sum) ^ ((y >> 5) + data[1]);
- y += ((x << 4) + data[2]) ^ (x + sum) ^ ((x >> 5) + data[3]);
- i++;
- }
-
- hash[0] += x;
- hash[1] += y;
+ uint32_t tea_delta = 0x9E3779B9;
+ uint32_t sum;
+ uint32_t x = hash[0], y = hash[1];
+ int n = 16;
+ int i = 1;
+
+ while (n-- > 0) {
+ sum = i * tea_delta;
+ x += ((y << 4) + data[0]) ^ (y + sum) ^ ((y >> 5) + data[1]);
+ y += ((x << 4) + data[2]) ^ (x + sum) ^ ((x >> 5) + data[3]);
+ i++;
+ }
+
+ hash[0] += x;
+ hash[1] += y;
}
static uint32_t ext2_legacy_hash(const char *name, int len, int unsigned_char)
{
- uint32_t h0, h1 = 0x12A3FE2D, h2 = 0x37ABE8F9;
- uint32_t multi = 0x6D22F5;
- const unsigned char *uname = (const unsigned char *)name;
- const signed char *sname = (const signed char *)name;
- int val, i;
-
- for (i = 0; i < len; i++) {
- if (unsigned_char)
- val = (unsigned int)*uname++;
- else
- val = (int)*sname++;
-
- h0 = h2 + (h1 ^ (val * multi));
- if (h0 & 0x80000000)
- h0 -= 0x7FFFFFFF;
- h2 = h1;
- h1 = h0;
- }
-
- return (h1 << 1);
+ uint32_t h0, h1 = 0x12A3FE2D, h2 = 0x37ABE8F9;
+ uint32_t multi = 0x6D22F5;
+ const unsigned char *uname = (const unsigned char *)name;
+ const signed char *sname = (const signed char *)name;
+ int val, i;
+
+ for (i = 0; i < len; i++) {
+ if (unsigned_char)
+ val = (unsigned int)*uname++;
+ else
+ val = (int)*sname++;
+
+ h0 = h2 + (h1 ^ (val * multi));
+ if (h0 & 0x80000000)
+ h0 -= 0x7FFFFFFF;
+ h2 = h1;
+ h1 = h0;
+ }
+
+ return (h1 << 1);
}
static void ext2_prep_hashbuf(const char *src, uint32_t slen, uint32_t *dst,
- int dlen, int unsigned_char)
+ int dlen, int unsigned_char)
{
- uint32_t padding = slen | (slen << 8) | (slen << 16) | (slen << 24);
- uint32_t buf_val;
- int len, i;
- int buf_byte;
- const unsigned char *ubuf = (const unsigned char *)src;
- const signed char *sbuf = (const signed char *)src;
-
- if (slen > (uint32_t)dlen)
- len = dlen;
- else
- len = slen;
-
- buf_val = padding;
-
- for (i = 0; i < len; i++) {
- if (unsigned_char)
- buf_byte = (unsigned int)ubuf[i];
- else
- buf_byte = (int)sbuf[i];
-
- if ((i % 4) == 0)
- buf_val = padding;
-
- buf_val <<= 8;
- buf_val += buf_byte;
-
- if ((i % 4) == 3) {
- *dst++ = buf_val;
- dlen -= sizeof(uint32_t);
- buf_val = padding;
- }
- }
-
- dlen -= sizeof(uint32_t);
- if (dlen >= 0)
- *dst++ = buf_val;
-
- dlen -= sizeof(uint32_t);
- while (dlen >= 0) {
- *dst++ = padding;
- dlen -= sizeof(uint32_t);
- }
+ uint32_t padding = slen | (slen << 8) | (slen << 16) | (slen << 24);
+ uint32_t buf_val;
+ int len, i;
+ int buf_byte;
+ const unsigned char *ubuf = (const unsigned char *)src;
+ const signed char *sbuf = (const signed char *)src;
+
+ if (slen > (uint32_t)dlen)
+ len = dlen;
+ else
+ len = slen;
+
+ buf_val = padding;
+
+ for (i = 0; i < len; i++) {
+ if (unsigned_char)
+ buf_byte = (unsigned int)ubuf[i];
+ else
+ buf_byte = (int)sbuf[i];
+
+ if ((i % 4) == 0)
+ buf_val = padding;
+
+ buf_val <<= 8;
+ buf_val += buf_byte;
+
+ if ((i % 4) == 3) {
+ *dst++ = buf_val;
+ dlen -= sizeof(uint32_t);
+ buf_val = padding;
+ }
+ }
+
+ dlen -= sizeof(uint32_t);
+ if (dlen >= 0)
+ *dst++ = buf_val;
+
+ dlen -= sizeof(uint32_t);
+ while (dlen >= 0) {
+ *dst++ = padding;
+ dlen -= sizeof(uint32_t);
+ }
}
int ext2_htree_hash(const char *name, int len, const uint32_t *hash_seed,
- int hash_version, uint32_t *hash_major,
- uint32_t *hash_minor)
+ int hash_version, uint32_t *hash_major,
+ uint32_t *hash_minor)
{
- uint32_t hash[4];
- uint32_t data[8];
- uint32_t major = 0, minor = 0;
- int unsigned_char = 0;
-
- if (!name || !hash_major)
- return (-1);
-
- if (len < 1 || len > 255)
- goto error;
-
- hash[0] = 0x67452301;
- hash[1] = 0xEFCDAB89;
- hash[2] = 0x98BADCFE;
- hash[3] = 0x10325476;
-
- if (hash_seed)
- memcpy(hash, hash_seed, sizeof(hash));
-
- switch (hash_version) {
- case EXT2_HTREE_TEA_UNSIGNED:
- unsigned_char = 1;
- case EXT2_HTREE_TEA:
- while (len > 0) {
- ext2_prep_hashbuf(name, len, data, 16, unsigned_char);
- ext2_tea(hash, data);
- len -= 16;
- name += 16;
- }
- major = hash[0];
- minor = hash[1];
- break;
- case EXT2_HTREE_LEGACY_UNSIGNED:
- unsigned_char = 1;
- case EXT2_HTREE_LEGACY:
- major = ext2_legacy_hash(name, len, unsigned_char);
- break;
- case EXT2_HTREE_HALF_MD4_UNSIGNED:
- unsigned_char = 1;
- case EXT2_HTREE_HALF_MD4:
- while (len > 0) {
- ext2_prep_hashbuf(name, len, data, 32, unsigned_char);
- ext2_half_md4(hash, data);
- len -= 32;
- name += 32;
- }
- major = hash[1];
- minor = hash[2];
- break;
- default:
- goto error;
- }
-
- major &= ~1;
- if (major == (EXT2_HTREE_EOF << 1))
- major = (EXT2_HTREE_EOF - 1) << 1;
- *hash_major = major;
- if (hash_minor)
- *hash_minor = minor;
-
- return EOK;
+ uint32_t hash[4];
+ uint32_t data[8];
+ uint32_t major = 0, minor = 0;
+ int unsigned_char = 0;
+
+ if (!name || !hash_major)
+ return (-1);
+
+ if (len < 1 || len > 255)
+ goto error;
+
+ hash[0] = 0x67452301;
+ hash[1] = 0xEFCDAB89;
+ hash[2] = 0x98BADCFE;
+ hash[3] = 0x10325476;
+
+ if (hash_seed)
+ memcpy(hash, hash_seed, sizeof(hash));
+
+ switch (hash_version) {
+ case EXT2_HTREE_TEA_UNSIGNED:
+ unsigned_char = 1;
+ case EXT2_HTREE_TEA:
+ while (len > 0) {
+ ext2_prep_hashbuf(name, len, data, 16, unsigned_char);
+ ext2_tea(hash, data);
+ len -= 16;
+ name += 16;
+ }
+ major = hash[0];
+ minor = hash[1];
+ break;
+ case EXT2_HTREE_LEGACY_UNSIGNED:
+ unsigned_char = 1;
+ case EXT2_HTREE_LEGACY:
+ major = ext2_legacy_hash(name, len, unsigned_char);
+ break;
+ case EXT2_HTREE_HALF_MD4_UNSIGNED:
+ unsigned_char = 1;
+ case EXT2_HTREE_HALF_MD4:
+ while (len > 0) {
+ ext2_prep_hashbuf(name, len, data, 32, unsigned_char);
+ ext2_half_md4(hash, data);
+ len -= 32;
+ name += 32;
+ }
+ major = hash[1];
+ minor = hash[2];
+ break;
+ default:
+ goto error;
+ }
+
+ major &= ~1;
+ if (major == (EXT2_HTREE_EOF << 1))
+ major = (EXT2_HTREE_EOF - 1) << 1;
+ *hash_major = major;
+ if (hash_minor)
+ *hash_minor = minor;
+
+ return EOK;
error:
- *hash_major = 0;
- if (hash_minor)
- *hash_minor = 0;
- return ENOTSUP;
+ *hash_major = 0;
+ if (hash_minor)
+ *hash_minor = 0;
+ return ENOTSUP;
}
/**
diff --git a/lwext4/ext4_hash.h b/lwext4/ext4_hash.h index 1a02a12..3f1af97 100644 --- a/lwext4/ext4_hash.h +++ b/lwext4/ext4_hash.h @@ -50,8 +50,8 @@ * @param hash_major output value
* @return standard error code*/
int ext2_htree_hash(const char *name, int len, const uint32_t *hash_seed,
- int hash_version, uint32_t *hash_major,
- uint32_t *hash_minor);
+ int hash_version, uint32_t *hash_major,
+ uint32_t *hash_minor);
#endif /* EXT4_HASH_H_ */
diff --git a/lwext4/ext4_ialloc.c b/lwext4/ext4_ialloc.c index c4ecb2a..6a0aa56 100644 --- a/lwext4/ext4_ialloc.c +++ b/lwext4/ext4_ialloc.c @@ -54,10 +54,10 @@ * @return Index of the i-node in the block group
*/
static uint32_t ext4_ialloc_inode2index_in_group(struct ext4_sblock *sb,
- uint32_t inode)
+ uint32_t inode)
{
- uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
- return (inode - 1) % inodes_per_group;
+ uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+ return (inode - 1) % inodes_per_group;
}
/**@brief Convert relative index of i-node to absolute i-node number.
@@ -67,10 +67,10 @@ static uint32_t ext4_ialloc_inode2index_in_group(struct ext4_sblock *sb, *
*/
static uint32_t ext4_ialloc_index_in_group2inode(struct ext4_sblock *sb,
- uint32_t index, uint32_t bgid)
+ uint32_t index, uint32_t bgid)
{
- uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
- return bgid * inodes_per_group + (index + 1);
+ uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+ return bgid * inodes_per_group + (index + 1);
}
/**@brief Compute block group number from the i-node number.
@@ -79,203 +79,216 @@ static uint32_t ext4_ialloc_index_in_group2inode(struct ext4_sblock *sb, * @return Block group number computed from i-node number
*/
static uint32_t ext4_ialloc_get_bgid_of_inode(struct ext4_sblock *sb,
- uint32_t inode)
+ uint32_t inode)
{
- uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
- return (inode - 1) / inodes_per_group;
+ uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+ return (inode - 1) / inodes_per_group;
}
int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir)
{
- struct ext4_sblock *sb = &fs->sb;
-
- /* Compute index of block group and load it */
- uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);
-
- struct ext4_block_group_ref bg_ref;
- int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
- if (rc != EOK)
- return rc;
-
- /* Load i-node bitmap */
- uint32_t bitmap_block_addr =
- ext4_bg_get_inode_bitmap(bg_ref.block_group, sb);
-
- struct ext4_block bitmap_block;
- rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
- if (rc != EOK)
- return rc;
-
- /* Free i-node in the bitmap */
- uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
- ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
- bitmap_block.dirty = true;
-
- /* Put back the block with bitmap */
- rc = ext4_block_set(fs->bdev, &bitmap_block);
- if (rc != EOK) {
- /* Error in saving bitmap */
- ext4_fs_put_block_group_ref(&bg_ref);
- return rc;
- }
-
- /* If released i-node is a directory, decrement used directories count */
- if (is_dir) {
- uint32_t bg_used_dirs =
- ext4_bg_get_used_dirs_count(bg_ref.block_group, sb);
- bg_used_dirs--;
- ext4_bg_set_used_dirs_count(bg_ref.block_group, sb, bg_used_dirs);
- }
-
- /* Update block group free inodes count */
- uint32_t free_inodes =
- ext4_bg_get_free_inodes_count(bg_ref.block_group, sb);
- free_inodes++;
- ext4_bg_set_free_inodes_count(bg_ref.block_group, sb, free_inodes);
-
- bg_ref.dirty = true;
-
- /* Put back the modified block group */
- rc = ext4_fs_put_block_group_ref(&bg_ref);
- if (rc != EOK)
- return rc;
-
- /* Update superblock free inodes count */
- ext4_set32(sb, free_inodes_count, ext4_get32(sb, free_inodes_count) + 1);
-
- return EOK;
+ struct ext4_sblock *sb = &fs->sb;
+
+ /* Compute index of block group and load it */
+ uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);
+
+ struct ext4_block_group_ref bg_ref;
+ int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
+ if (rc != EOK)
+ return rc;
+
+ /* Load i-node bitmap */
+ uint32_t bitmap_block_addr =
+ ext4_bg_get_inode_bitmap(bg_ref.block_group, sb);
+
+ struct ext4_block bitmap_block;
+ rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+ if (rc != EOK)
+ return rc;
+
+ /* Free i-node in the bitmap */
+ uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
+ ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
+ bitmap_block.dirty = true;
+
+ /* Put back the block with bitmap */
+ rc = ext4_block_set(fs->bdev, &bitmap_block);
+ if (rc != EOK) {
+ /* Error in saving bitmap */
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+
+ /* If released i-node is a directory, decrement used directories count
+ */
+ if (is_dir) {
+ uint32_t bg_used_dirs =
+ ext4_bg_get_used_dirs_count(bg_ref.block_group, sb);
+ bg_used_dirs--;
+ ext4_bg_set_used_dirs_count(bg_ref.block_group, sb,
+ bg_used_dirs);
+ }
+
+ /* Update block group free inodes count */
+ uint32_t free_inodes =
+ ext4_bg_get_free_inodes_count(bg_ref.block_group, sb);
+ free_inodes++;
+ ext4_bg_set_free_inodes_count(bg_ref.block_group, sb, free_inodes);
+
+ bg_ref.dirty = true;
+
+ /* Put back the modified block group */
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
+ if (rc != EOK)
+ return rc;
+
+ /* Update superblock free inodes count */
+ ext4_set32(sb, free_inodes_count,
+ ext4_get32(sb, free_inodes_count) + 1);
+
+ return EOK;
}
int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir)
{
- struct ext4_sblock *sb = &fs->sb;
-
- uint32_t bgid = fs->last_inode_bg_id;
- uint32_t bg_count = ext4_block_group_cnt(sb);
- uint32_t sb_free_inodes = ext4_get32(sb, free_inodes_count);
- bool rewind = false;
-
- /* Try to find free i-node in all block groups */
- while (bgid <= bg_count) {
-
- if (bgid == bg_count) {
- if (rewind)
- break;
- bg_count = fs->last_inode_bg_id;
- bgid = 0;
- rewind = true;
- continue;
- }
-
- /* Load block group to check */
- struct ext4_block_group_ref bg_ref;
- int rc = ext4_fs_get_block_group_ref(fs, bgid, &bg_ref);
- if (rc != EOK)
- return rc;
-
- struct ext4_bgroup *bg = bg_ref.block_group;
-
- /* Read necessary values for algorithm */
- uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);
- uint32_t used_dirs = ext4_bg_get_used_dirs_count(bg, sb);
-
- /* Check if this block group is good candidate for allocation */
- if (free_inodes > 0) {
- /* Load block with bitmap */
- uint32_t bitmap_block_addr =
- ext4_bg_get_inode_bitmap(bg_ref.block_group, sb);
-
- struct ext4_block bitmap_block;
- rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
- if (rc != EOK) {
- ext4_fs_put_block_group_ref(&bg_ref);
- return rc;
- }
-
- /* Try to allocate i-node in the bitmap */
- uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bgid);
- uint32_t index_in_group;
-
- rc = ext4_bmap_bit_find_clr(bitmap_block.data, 0, inodes_in_group,
- &index_in_group);
- /* Block group has not any free i-node */
- if (rc == ENOSPC) {
- rc = ext4_block_set(fs->bdev, &bitmap_block);
- if (rc != EOK) {
- ext4_fs_put_block_group_ref(&bg_ref);
- return rc;
- }
-
- rc = ext4_fs_put_block_group_ref(&bg_ref);
- if (rc != EOK)
- return rc;
-
- continue;
- }
-
- ext4_bmap_bit_set(bitmap_block.data, index_in_group);
-
- /* Free i-node found, save the bitmap */
- bitmap_block.dirty = true;
-
- ext4_block_set(fs->bdev, &bitmap_block);
- if (rc != EOK) {
- ext4_fs_put_block_group_ref(&bg_ref);
- return rc;
- }
-
- /* Modify filesystem counters */
- free_inodes--;
- ext4_bg_set_free_inodes_count(bg, sb, free_inodes);
-
- /* Increment used directories counter */
- if (is_dir) {
- used_dirs++;
- ext4_bg_set_used_dirs_count(bg, sb, used_dirs);
- }
-
- /* Decrease unused inodes count */
- if (ext4_bg_has_flag(bg, EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
- uint32_t unused = ext4_bg_get_itable_unused(bg, sb);
-
- uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bgid);
-
- uint32_t free = inodes_in_group - unused;
-
- if (index_in_group >= free) {
- unused = inodes_in_group - (index_in_group + 1);
- ext4_bg_set_itable_unused(bg, sb, unused);
- }
- }
-
- /* Save modified block group */
- bg_ref.dirty = true;
-
- rc = ext4_fs_put_block_group_ref(&bg_ref);
- if (rc != EOK)
- return rc;
-
- /* Update superblock */
- sb_free_inodes--;
- ext4_set32(sb, free_inodes_count, sb_free_inodes);
-
- /* Compute the absolute i-nodex number */
- *index = ext4_ialloc_index_in_group2inode(sb, index_in_group, bgid);
-
- fs->last_inode_bg_id = bgid;
-
- return EOK;
- }
-
- /* Block group not modified, put it and jump to the next block group */
- ext4_fs_put_block_group_ref(&bg_ref);
- if (rc != EOK)
- return rc;
-
- ++bgid;
- }
-
- return ENOSPC;
+ struct ext4_sblock *sb = &fs->sb;
+
+ uint32_t bgid = fs->last_inode_bg_id;
+ uint32_t bg_count = ext4_block_group_cnt(sb);
+ uint32_t sb_free_inodes = ext4_get32(sb, free_inodes_count);
+ bool rewind = false;
+
+ /* Try to find free i-node in all block groups */
+ while (bgid <= bg_count) {
+
+ if (bgid == bg_count) {
+ if (rewind)
+ break;
+ bg_count = fs->last_inode_bg_id;
+ bgid = 0;
+ rewind = true;
+ continue;
+ }
+
+ /* Load block group to check */
+ struct ext4_block_group_ref bg_ref;
+ int rc = ext4_fs_get_block_group_ref(fs, bgid, &bg_ref);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_bgroup *bg = bg_ref.block_group;
+
+ /* Read necessary values for algorithm */
+ uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);
+ uint32_t used_dirs = ext4_bg_get_used_dirs_count(bg, sb);
+
+ /* Check if this block group is good candidate for allocation */
+ if (free_inodes > 0) {
+ /* Load block with bitmap */
+ uint32_t bitmap_block_addr =
+ ext4_bg_get_inode_bitmap(bg_ref.block_group, sb);
+
+ struct ext4_block bitmap_block;
+ rc = ext4_block_get(fs->bdev, &bitmap_block,
+ bitmap_block_addr);
+ if (rc != EOK) {
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+
+ /* Try to allocate i-node in the bitmap */
+ uint32_t inodes_in_group =
+ ext4_inodes_in_group_cnt(sb, bgid);
+ uint32_t index_in_group;
+
+ rc = ext4_bmap_bit_find_clr(bitmap_block.data, 0,
+ inodes_in_group,
+ &index_in_group);
+ /* Block group has not any free i-node */
+ if (rc == ENOSPC) {
+ rc = ext4_block_set(fs->bdev, &bitmap_block);
+ if (rc != EOK) {
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
+ if (rc != EOK)
+ return rc;
+
+ continue;
+ }
+
+ ext4_bmap_bit_set(bitmap_block.data, index_in_group);
+
+ /* Free i-node found, save the bitmap */
+ bitmap_block.dirty = true;
+
+ ext4_block_set(fs->bdev, &bitmap_block);
+ if (rc != EOK) {
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+
+ /* Modify filesystem counters */
+ free_inodes--;
+ ext4_bg_set_free_inodes_count(bg, sb, free_inodes);
+
+ /* Increment used directories counter */
+ if (is_dir) {
+ used_dirs++;
+ ext4_bg_set_used_dirs_count(bg, sb, used_dirs);
+ }
+
+ /* Decrease unused inodes count */
+ if (ext4_bg_has_flag(bg,
+ EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
+ uint32_t unused =
+ ext4_bg_get_itable_unused(bg, sb);
+
+ uint32_t inodes_in_group =
+ ext4_inodes_in_group_cnt(sb, bgid);
+
+ uint32_t free = inodes_in_group - unused;
+
+ if (index_in_group >= free) {
+ unused = inodes_in_group -
+ (index_in_group + 1);
+ ext4_bg_set_itable_unused(bg, sb,
+ unused);
+ }
+ }
+
+ /* Save modified block group */
+ bg_ref.dirty = true;
+
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
+ if (rc != EOK)
+ return rc;
+
+ /* Update superblock */
+ sb_free_inodes--;
+ ext4_set32(sb, free_inodes_count, sb_free_inodes);
+
+ /* Compute the absolute i-nodex number */
+ *index = ext4_ialloc_index_in_group2inode(
+ sb, index_in_group, bgid);
+
+ fs->last_inode_bg_id = bgid;
+
+ return EOK;
+ }
+
+ /* Block group not modified, put it and jump to the next block
+ * group */
+ ext4_fs_put_block_group_ref(&bg_ref);
+ if (rc != EOK)
+ return rc;
+
+ ++bgid;
+ }
+
+ return ENOSPC;
}
/**
diff --git a/lwext4/ext4_inode.c b/lwext4/ext4_inode.c index e8c9760..bbef06b 100644 --- a/lwext4/ext4_inode.c +++ b/lwext4/ext4_inode.c @@ -50,284 +50,289 @@ */
static uint32_t ext4_inode_block_bits_count(uint32_t block_size)
{
- uint32_t bits = 8;
- uint32_t size = block_size;
+ uint32_t bits = 8;
+ uint32_t size = block_size;
- do {
- bits++;
- size = size >> 1;
- } while (size > 256);
+ do {
+ bits++;
+ size = size >> 1;
+ } while (size > 256);
- return bits;
+ return bits;
}
uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode)
{
- uint32_t v = to_le16(inode->mode);
+ uint32_t v = to_le16(inode->mode);
- if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD) {
- v |= ((uint32_t)to_le16(inode->osd2.hurd2.mode_high)) << 16;
- }
+ if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD) {
+ v |= ((uint32_t)to_le16(inode->osd2.hurd2.mode_high)) << 16;
+ }
- return v;
+ return v;
}
void ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
- uint32_t mode)
+ uint32_t mode)
{
- inode->mode = to_le16((mode << 16) >> 16);
+ inode->mode = to_le16((mode << 16) >> 16);
- if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)
- inode->osd2.hurd2.mode_high = to_le16(mode >> 16);
+ if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)
+ inode->osd2.hurd2.mode_high = to_le16(mode >> 16);
}
uint32_t ext4_inode_get_uid(struct ext4_inode *inode)
{
- return to_le32(inode->uid);
+ return to_le32(inode->uid);
}
void ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid)
{
- inode->uid = to_le32(uid);
+ inode->uid = to_le32(uid);
}
uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode)
{
- uint64_t v = to_le32(inode->size_lo);
+ uint64_t v = to_le32(inode->size_lo);
- if ((ext4_get32(sb, rev_level) > 0) &&
- (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)))
- v |= ((uint64_t)to_le32(inode->size_hi)) << 32;
+ if ((ext4_get32(sb, rev_level) > 0) &&
+ (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)))
+ v |= ((uint64_t)to_le32(inode->size_hi)) << 32;
- return v;
+ return v;
}
void ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)
{
- inode->size_lo = to_le32((size << 32) >> 32);
- inode->size_hi = to_le32(size >> 32);
+ inode->size_lo = to_le32((size << 32) >> 32);
+ inode->size_hi = to_le32(size >> 32);
}
uint32_t ext4_inode_get_access_time(struct ext4_inode *inode)
{
- return to_le32(inode->access_time);
+ return to_le32(inode->access_time);
}
void ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time)
{
- inode->access_time = to_le32(time);
+ inode->access_time = to_le32(time);
}
uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode)
{
- return to_le32(inode->change_inode_time);
+ return to_le32(inode->change_inode_time);
}
void ext4_inode_set_change_inode_time(struct ext4_inode *inode, uint32_t time)
{
- inode->change_inode_time = to_le32(time);
+ inode->change_inode_time = to_le32(time);
}
uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode)
{
- return to_le32(inode->modification_time);
+ return to_le32(inode->modification_time);
}
void ext4_inode_set_modification_time(struct ext4_inode *inode, uint32_t time)
{
- inode->modification_time = to_le32(time);
+ inode->modification_time = to_le32(time);
}
uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode)
{
- return to_le32(inode->deletion_time);
+ return to_le32(inode->deletion_time);
}
void ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time)
{
- inode->deletion_time = to_le32(time);
+ inode->deletion_time = to_le32(time);
}
uint32_t ext4_inode_get_gid(struct ext4_inode *inode)
{
- return to_le32(inode->gid);
+ return to_le32(inode->gid);
}
void ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid)
{
- inode->gid = to_le32(gid);
+ inode->gid = to_le32(gid);
}
uint16_t ext4_inode_get_links_count(struct ext4_inode *inode)
{
- return to_le16(inode->links_count);
+ return to_le16(inode->links_count);
}
void ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt)
{
- inode->links_count = to_le16(cnt);
+ inode->links_count = to_le16(cnt);
}
uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
- struct ext4_inode *inode)
+ struct ext4_inode *inode)
{
- uint64_t count = to_le32(inode->blocks_count_lo);
+ uint64_t count = to_le32(inode->blocks_count_lo);
- if (ext4_sb_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+ if (ext4_sb_has_feature_read_only(sb,
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
- /* 48-bit field */
- count |= ((uint64_t)to_le16(inode->osd2.linux2.blocks_high)) << 32;
+ /* 48-bit field */
+ count |= ((uint64_t)to_le16(inode->osd2.linux2.blocks_high))
+ << 32;
- if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {
+ if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {
- uint32_t block_bits =
- ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
- return count << (block_bits - 9);
- }
- }
+ uint32_t block_bits = ext4_inode_block_bits_count(
+ ext4_sb_get_block_size(sb));
+ return count << (block_bits - 9);
+ }
+ }
- return count;
+ return count;
}
int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
- struct ext4_inode *inode, uint64_t count)
+ struct ext4_inode *inode, uint64_t count)
{
- /* 32-bit maximum */
- uint64_t max = 0;
- max = ~max >> 32;
+ /* 32-bit maximum */
+ uint64_t max = 0;
+ max = ~max >> 32;
- if (count <= max) {
- inode->blocks_count_lo = to_le32(count);
- inode->osd2.linux2.blocks_high = 0;
- ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+ if (count <= max) {
+ inode->blocks_count_lo = to_le32(count);
+ inode->osd2.linux2.blocks_high = 0;
+ ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
- return EOK;
- }
+ return EOK;
+ }
- /* Check if there can be used huge files (many blocks) */
- if (!ext4_sb_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
- return EINVAL;
+ /* Check if there can be used huge files (many blocks) */
+ if (!ext4_sb_has_feature_read_only(sb,
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
+ return EINVAL;
- /* 48-bit maximum */
- max = 0;
- max = ~max >> 16;
+ /* 48-bit maximum */
+ max = 0;
+ max = ~max >> 16;
- if (count <= max) {
- inode->blocks_count_lo = to_le32(count);
- inode->osd2.linux2.blocks_high = to_le16(count >> 32);
- ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
- } else {
- uint32_t block_bits =
- ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
+ if (count <= max) {
+ inode->blocks_count_lo = to_le32(count);
+ inode->osd2.linux2.blocks_high = to_le16(count >> 32);
+ ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+ } else {
+ uint32_t block_bits =
+ ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
- ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
- count = count >> (block_bits - 9);
- inode->blocks_count_lo = to_le32(count);
- inode->osd2.linux2.blocks_high = to_le16(count >> 32);
- }
+ ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+ count = count >> (block_bits - 9);
+ inode->blocks_count_lo = to_le32(count);
+ inode->osd2.linux2.blocks_high = to_le16(count >> 32);
+ }
- return EOK;
+ return EOK;
}
uint32_t ext4_inode_get_flags(struct ext4_inode *inode)
{
- return to_le32(inode->flags);
+ return to_le32(inode->flags);
}
void ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags)
{
- inode->flags = to_le32(flags);
+ inode->flags = to_le32(flags);
}
uint32_t ext4_inode_get_generation(struct ext4_inode *inode)
{
- return to_le32(inode->generation);
+ return to_le32(inode->generation);
}
void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen)
{
- inode->generation = to_le32(gen);
+ inode->generation = to_le32(gen);
}
uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
- struct ext4_sblock *sb)
+ struct ext4_sblock *sb)
{
- /*TODO: Verify it*/
- uint64_t v = to_le32(inode->file_acl_lo);
+ /*TODO: Verify it*/
+ uint64_t v = to_le32(inode->file_acl_lo);
- if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
- v |= ((uint32_t)to_le16(inode->osd2.linux2.file_acl_high)) << 16;
+ if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
+ v |= ((uint32_t)to_le16(inode->osd2.linux2.file_acl_high))
+ << 16;
- return v;
+ return v;
}
void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,
- uint64_t acl)
+ uint64_t acl)
{
- /*TODO: Verify it*/
- inode->file_acl_lo = to_le32((acl << 32) >> 32);
+ /*TODO: Verify it*/
+ inode->file_acl_lo = to_le32((acl << 32) >> 32);
- if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
- inode->osd2.linux2.file_acl_high = to_le16(acl >> 32);
+ if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
+ inode->osd2.linux2.file_acl_high = to_le16(acl >> 32);
}
uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx)
{
- return to_le32(inode->blocks[idx]);
+ return to_le32(inode->blocks[idx]);
}
void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
- uint32_t block)
+ uint32_t block)
{
- inode->blocks[idx] = to_le32(block);
+ inode->blocks[idx] = to_le32(block);
}
uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx)
{
- return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);
+ return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);
}
void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
- uint32_t block)
+ uint32_t block)
{
- inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);
+ inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);
}
bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
- uint32_t type)
+ uint32_t type)
{
- return (ext4_inode_get_mode(sb, inode) & EXT4_INODE_MODE_TYPE_MASK) == type;
+ return (ext4_inode_get_mode(sb, inode) & EXT4_INODE_MODE_TYPE_MASK) ==
+ type;
}
bool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f)
{
- return ext4_inode_get_flags(inode) & f;
+ return ext4_inode_get_flags(inode) & f;
}
void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f)
{
- uint32_t flags = ext4_inode_get_flags(inode);
- flags = flags & (~f);
- ext4_inode_set_flags(inode, flags);
+ uint32_t flags = ext4_inode_get_flags(inode);
+ flags = flags & (~f);
+ ext4_inode_set_flags(inode, flags);
}
void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f)
{
- uint32_t flags = ext4_inode_get_flags(inode);
- flags = flags | f;
- ext4_inode_set_flags(inode, flags);
+ uint32_t flags = ext4_inode_get_flags(inode);
+ flags = flags | f;
+ ext4_inode_set_flags(inode, flags);
}
bool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode)
{
- if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||
- (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))
- return false;
+ if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||
+ (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))
+ return false;
- if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||
- (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)))
- return true;
+ if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||
+ (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)))
+ return true;
- return false;
+ return false;
}
struct ext4_extent_header *
ext4_inode_get_extent_header(struct ext4_inode *inode)
{
- return (struct ext4_extent_header *)inode->blocks;
+ return (struct ext4_extent_header *)inode->blocks;
}
/**
diff --git a/lwext4/ext4_inode.h b/lwext4/ext4_inode.h index c0a79ca..0acf734 100644 --- a/lwext4/ext4_inode.h +++ b/lwext4/ext4_inode.h @@ -59,7 +59,7 @@ uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode); * @param mode Mode to set to i-node
*/
void ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
- uint32_t mode);
+ uint32_t mode);
/**@brief Get ID of the i-node owner (user id).
* @param inode I-node to load uid from
@@ -164,7 +164,7 @@ void ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt); * @return Number of 512-bytes blocks
*/
uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
- struct ext4_inode *inode);
+ struct ext4_inode *inode);
/**@brief Set number of 512-bytes blocks used for i-node.
* @param sb Superblock
@@ -173,7 +173,7 @@ uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb, * @return Error code
*/
int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
- struct ext4_inode *inode, uint64_t cnt);
+ struct ext4_inode *inode, uint64_t cnt);
/**@brief Get flags (features) of i-node.
* @param inode I-node to get flags from
@@ -205,7 +205,7 @@ void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen); * @return Block address
*/
uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
- struct ext4_sblock *sb);
+ struct ext4_sblock *sb);
/**@brief Set address of block, where are extended attributes located.
* @param inode I-node
@@ -213,7 +213,7 @@ uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode, * @param file_acl Block address
*/
void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,
- uint64_t acl);
+ uint64_t acl);
/**@brief Get block address of specified direct block.
* @param inode I-node to load block from
@@ -228,7 +228,7 @@ uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx); * @param fblock Physical block address
*/
void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
- uint32_t block);
+ uint32_t block);
/**@brief Get block address of specified indirect block.
* @param inode I-node to get block address from
@@ -243,7 +243,7 @@ uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx); * @param fblock Physical block address
*/
void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
- uint32_t block);
+ uint32_t block);
/**@brief Check if i-node has specified type.
* @param sb Superblock
@@ -252,7 +252,7 @@ void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx, * @return Result of check operation
*/
bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
- uint32_t type);
+ uint32_t type);
/**@brief Check if i-node has specified flag.
* @param inode I-node to check flags of
diff --git a/lwext4/ext4_super.c b/lwext4/ext4_super.c index 6f57c71..0258ca7 100644 --- a/lwext4/ext4_super.c +++ b/lwext4/ext4_super.c @@ -44,186 +44,190 @@ uint32_t ext4_block_group_cnt(struct ext4_sblock *s) { - uint64_t blocks_count = ext4_sb_get_blocks_cnt(s); - uint32_t blocks_per_group = ext4_get32(s, blocks_per_group); + uint64_t blocks_count = ext4_sb_get_blocks_cnt(s); + uint32_t blocks_per_group = ext4_get32(s, blocks_per_group); - uint32_t block_groups_count = blocks_count / blocks_per_group; + uint32_t block_groups_count = blocks_count / blocks_per_group; - if (blocks_count % blocks_per_group) - block_groups_count++; + if (blocks_count % blocks_per_group) + block_groups_count++; - return block_groups_count; + return block_groups_count; } uint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid) { - uint32_t block_group_count = ext4_block_group_cnt(s); - uint32_t blocks_per_group = ext4_get32(s, blocks_per_group); - uint64_t total_blocks = ext4_sb_get_blocks_cnt(s); + uint32_t block_group_count = ext4_block_group_cnt(s); + uint32_t blocks_per_group = ext4_get32(s, blocks_per_group); + uint64_t total_blocks = ext4_sb_get_blocks_cnt(s); - if (bgid < block_group_count - 1) - return blocks_per_group; + if (bgid < block_group_count - 1) + return blocks_per_group; - return (total_blocks - ((block_group_count - 1) * blocks_per_group)); + return (total_blocks - ((block_group_count - 1) * blocks_per_group)); } uint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid) { - uint32_t block_group_count = ext4_block_group_cnt(s); - uint32_t inodes_per_group = ext4_get32(s, inodes_per_group); - uint32_t total_inodes = ext4_get32(s, inodes_count); + uint32_t block_group_count = ext4_block_group_cnt(s); + uint32_t inodes_per_group = ext4_get32(s, inodes_per_group); + uint32_t total_inodes = ext4_get32(s, inodes_count); - if (bgid < block_group_count - 1) - return inodes_per_group; + if (bgid < block_group_count - 1) + return inodes_per_group; - return (total_inodes - ((block_group_count - 1) * inodes_per_group)); + return (total_inodes - ((block_group_count - 1) * inodes_per_group)); } int ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s) { - return ext4_block_writebytes(bdev, EXT4_SUPERBLOCK_OFFSET, s, - EXT4_SUPERBLOCK_SIZE); + return ext4_block_writebytes(bdev, EXT4_SUPERBLOCK_OFFSET, s, + EXT4_SUPERBLOCK_SIZE); } int ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s) { - return ext4_block_readbytes(bdev, EXT4_SUPERBLOCK_OFFSET, s, - EXT4_SUPERBLOCK_SIZE); + return ext4_block_readbytes(bdev, EXT4_SUPERBLOCK_OFFSET, s, + EXT4_SUPERBLOCK_SIZE); } bool ext4_sb_check(struct ext4_sblock *s) { - if (ext4_get16(s, magic) != EXT4_SUPERBLOCK_MAGIC) - return false; + if (ext4_get16(s, magic) != EXT4_SUPERBLOCK_MAGIC) + return false; - if (ext4_get32(s, inodes_count) == 0) - return false; + if (ext4_get32(s, inodes_count) == 0) + return false; - if (ext4_sb_get_blocks_cnt(s) == 0) - return false; + if (ext4_sb_get_blocks_cnt(s) == 0) + return false; - if (ext4_get32(s, blocks_per_group) == 0) - return false; + if (ext4_get32(s, blocks_per_group) == 0) + return false; - if (ext4_get32(s, inodes_per_group) == 0) - return false; + if (ext4_get32(s, inodes_per_group) == 0) + return false; - if (ext4_get16(s, inode_size) < 128) - return false; + if (ext4_get16(s, inode_size) < 128) + return false; - if (ext4_get32(s, first_inode) < 11) - return false; + if (ext4_get32(s, first_inode) < 11) + return false; - if (ext4_sb_get_desc_size(s) < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) - return false; + if (ext4_sb_get_desc_size(s) < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) + return false; - if (ext4_sb_get_desc_size(s) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE) - return false; + if (ext4_sb_get_desc_size(s) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE) + return false; - return true; + return true; } static inline int is_multiple(uint32_t a, uint32_t b) { - while (1) { - if (a < b) - return 0; - if (a == b) - return 1; - if ((a % b) != 0) - return 0; - a = a / b; - } + while (1) { + if (a < b) + return 0; + if (a == b) + return 1; + if ((a % b) != 0) + return 0; + a = a / b; + } } static int ext4_sb_sparse(uint32_t group) { - if (group <= 1) - return 1; + if (group <= 1) + return 1; - if (!(group & 1)) - return 0; + if (!(group & 1)) + return 0; - return (is_multiple(group, 7) || is_multiple(group, 5) || - is_multiple(group, 3)); + return (is_multiple(group, 7) || is_multiple(group, 5) || + is_multiple(group, 3)); } bool ext4_sb_is_super_in_bg(struct ext4_sblock *s, uint32_t group) { - if (ext4_sb_has_feature_read_only(s, EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && - !ext4_sb_sparse(group)) - return false; - return true; + if (ext4_sb_has_feature_read_only( + s, EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && + !ext4_sb_sparse(group)) + return false; + return true; } static uint32_t ext4_bg_num_gdb_meta(struct ext4_sblock *s, uint32_t group) { - uint32_t dsc_per_block = - ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); + uint32_t dsc_per_block = + ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); - uint32_t metagroup = group / dsc_per_block; - uint32_t first = metagroup * dsc_per_block; - uint32_t last = first + dsc_per_block - 1; + uint32_t metagroup = group / dsc_per_block; + uint32_t first = metagroup * dsc_per_block; + uint32_t last = first + dsc_per_block - 1; - if (group == first || group == first + 1 || group == last) - return 1; - return 0; + if (group == first || group == first + 1 || group == last) + return 1; + return 0; } static uint32_t ext4_bg_num_gdb_nometa(struct ext4_sblock *s, uint32_t group) { - if (!ext4_sb_is_super_in_bg(s, group)) - return 0; - uint32_t dsc_per_block = - ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); + if (!ext4_sb_is_super_in_bg(s, group)) + return 0; + uint32_t dsc_per_block = + ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); - uint32_t db_count = - (ext4_block_group_cnt(s) + dsc_per_block - 1) / dsc_per_block; + uint32_t db_count = + (ext4_block_group_cnt(s) + dsc_per_block - 1) / dsc_per_block; - if (ext4_sb_has_feature_incompatible(s, EXT4_FEATURE_INCOMPAT_META_BG)) - return ext4_sb_first_meta_bg(s); + if (ext4_sb_has_feature_incompatible(s, EXT4_FEATURE_INCOMPAT_META_BG)) + return ext4_sb_first_meta_bg(s); - return db_count; + return db_count; } uint32_t ext4_bg_num_gdb(struct ext4_sblock *s, uint32_t group) { - uint32_t dsc_per_block = - ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); - uint32_t first_meta_bg = ext4_sb_first_meta_bg(s); - uint32_t metagroup = group / dsc_per_block; + uint32_t dsc_per_block = + ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); + uint32_t first_meta_bg = ext4_sb_first_meta_bg(s); + uint32_t metagroup = group / dsc_per_block; - if (!ext4_sb_has_feature_incompatible(s, EXT4_FEATURE_INCOMPAT_META_BG) || - metagroup < first_meta_bg) - return ext4_bg_num_gdb_nometa(s, group); + if (!ext4_sb_has_feature_incompatible(s, + EXT4_FEATURE_INCOMPAT_META_BG) || + metagroup < first_meta_bg) + return ext4_bg_num_gdb_nometa(s, group); - return ext4_bg_num_gdb_meta(s, group); + return ext4_bg_num_gdb_meta(s, group); } uint32_t ext4_num_base_meta_clusters(struct ext4_sblock *s, - uint32_t block_group) + uint32_t block_group) { - uint32_t num; - uint32_t dsc_per_block = - ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); - - num = ext4_sb_is_super_in_bg(s, block_group); - - if (!ext4_sb_has_feature_incompatible(s, EXT4_FEATURE_INCOMPAT_META_BG) || - block_group < ext4_sb_first_meta_bg(s) * dsc_per_block) { - if (num) { - num += ext4_bg_num_gdb(s, block_group); - num += ext4_get16(s, s_reserved_gdt_blocks); - } - } else { - num += ext4_bg_num_gdb(s, block_group); - } - - uint32_t clustersize = 1024 << ext4_get32(s, log_cluster_size); - uint32_t cluster_ratio = clustersize / ext4_sb_get_block_size(s); - uint32_t v = (num + cluster_ratio - 1) >> ext4_get32(s, log_cluster_size); - - return v; + uint32_t num; + uint32_t dsc_per_block = + ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s); + + num = ext4_sb_is_super_in_bg(s, block_group); + + if (!ext4_sb_has_feature_incompatible(s, + EXT4_FEATURE_INCOMPAT_META_BG) || + block_group < ext4_sb_first_meta_bg(s) * dsc_per_block) { + if (num) { + num += ext4_bg_num_gdb(s, block_group); + num += ext4_get16(s, s_reserved_gdt_blocks); + } + } else { + num += ext4_bg_num_gdb(s, block_group); + } + + uint32_t clustersize = 1024 << ext4_get32(s, log_cluster_size); + uint32_t cluster_ratio = clustersize / ext4_sb_get_block_size(s); + uint32_t v = + (num + cluster_ratio - 1) >> ext4_get32(s, log_cluster_size); + + return v; } /** diff --git a/lwext4/ext4_super.h b/lwext4/ext4_super.h index 1852b48..9451218 100644 --- a/lwext4/ext4_super.h +++ b/lwext4/ext4_super.h @@ -50,8 +50,8 @@ * @return count of blocks*/ static inline uint64_t ext4_sb_get_blocks_cnt(struct ext4_sblock *s) { - return ((uint64_t)to_le32(s->blocks_count_hi) << 32) | - to_le32(s->blocks_count_lo); + return ((uint64_t)to_le32(s->blocks_count_hi) << 32) | + to_le32(s->blocks_count_lo); } /**@brief Free blocks count get stored in superblock. @@ -59,18 +59,18 @@ static inline uint64_t ext4_sb_get_blocks_cnt(struct ext4_sblock *s) * @return free blocks*/ static inline uint64_t ext4_sb_get_free_blocks_cnt(struct ext4_sblock *s) { - return ((uint64_t)to_le32(s->free_blocks_count_hi) << 32) | - to_le32(s->free_blocks_count_lo); + return ((uint64_t)to_le32(s->free_blocks_count_hi) << 32) | + to_le32(s->free_blocks_count_lo); } /**@brief Free blocks count set. * @param s superblock descriptor * @param cnt new value of free blocks*/ static inline void ext4_sb_set_free_blocks_cnt(struct ext4_sblock *s, - uint64_t cnt) + uint64_t cnt) { - s->free_blocks_count_lo = to_le32((cnt << 32) >> 32); - s->free_blocks_count_hi = to_le32(cnt >> 32); + s->free_blocks_count_lo = to_le32((cnt << 32) >> 32); + s->free_blocks_count_hi = to_le32(cnt >> 32); } /**@brief Block size get from superblock. @@ -78,7 +78,7 @@ static inline void ext4_sb_set_free_blocks_cnt(struct ext4_sblock *s, * @return block size in bytes*/ static inline uint32_t ext4_sb_get_block_size(struct ext4_sblock *s) { - return 1024 << to_le32(s->log_block_size); + return 1024 << to_le32(s->log_block_size); } /**@brief Block group descriptor size. @@ -86,11 +86,11 @@ static inline uint32_t ext4_sb_get_block_size(struct ext4_sblock *s) * @return block group descriptor size in bytes*/ static inline uint16_t ext4_sb_get_desc_size(struct ext4_sblock *s) { - uint16_t size = to_le16(s->desc_size); + uint16_t size = to_le16(s->desc_size); - return size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE - ? EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE - : size; + return size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE + ? EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE + : size; } /*************************Flags and features*********************************/ @@ -101,7 +101,7 @@ static inline uint16_t ext4_sb_get_desc_size(struct ext4_sblock *s) * @return true if flag is supported*/ static inline bool ext4_sb_check_flag(struct ext4_sblock *s, uint32_t v) { - return to_le32(s->flags) & v; + return to_le32(s->flags) & v; } /**@brief Support check of feature compatible. @@ -109,9 +109,9 @@ static inline bool ext4_sb_check_flag(struct ext4_sblock *s, uint32_t v) * @param v feature to check * @return true if feature is supported*/ static inline bool ext4_sb_has_feature_compatible(struct ext4_sblock *s, - uint32_t v) + uint32_t v) { - return to_le32(s->features_compatible) & v; + return to_le32(s->features_compatible) & v; } /**@brief Support check of feature incompatible. @@ -119,9 +119,9 @@ static inline bool ext4_sb_has_feature_compatible(struct ext4_sblock *s, * @param v feature to check * @return true if feature is supported*/ static inline bool ext4_sb_has_feature_incompatible(struct ext4_sblock *s, - uint32_t v) + uint32_t v) { - return to_le32(s->features_incompatible) & v; + return to_le32(s->features_incompatible) & v; } /**@brief Support check of read only flag. @@ -129,9 +129,9 @@ static inline bool ext4_sb_has_feature_incompatible(struct ext4_sblock *s, * @param v flag to check * @return true if flag is supported*/ static inline bool ext4_sb_has_feature_read_only(struct ext4_sblock *s, - uint32_t v) + uint32_t v) { - return to_le32(s->features_read_only) & v; + return to_le32(s->features_read_only) & v; } /**@brief Block group to flex group. @@ -139,9 +139,9 @@ static inline bool ext4_sb_has_feature_read_only(struct ext4_sblock *s, * @param block_group block group * @return flex group id*/ static inline uint32_t ext4_sb_bg_to_flex(struct ext4_sblock *s, - uint32_t block_group) + uint32_t block_group) { - return block_group >> to_le32(s->log_groups_per_flex); + return block_group >> to_le32(s->log_groups_per_flex); } /**@brief Flex block group size. @@ -149,7 +149,7 @@ static inline uint32_t ext4_sb_bg_to_flex(struct ext4_sblock *s, * @return flex bg size*/ static inline uint32_t ext4_sb_flex_bg_size(struct ext4_sblock *s) { - return 1 << to_le32(s->log_groups_per_flex); + return 1 << to_le32(s->log_groups_per_flex); } /**@brief Return first meta block group id. @@ -157,7 +157,7 @@ static inline uint32_t ext4_sb_flex_bg_size(struct ext4_sblock *s) * @return first meta_bg id */ static inline uint32_t ext4_sb_first_meta_bg(struct ext4_sblock *s) { - return to_le32(s->first_meta_bg); + return to_le32(s->first_meta_bg); } /**************************More complex functions****************************/ @@ -211,7 +211,7 @@ uint32_t ext4_bg_num_gdb(struct ext4_sblock *s, uint32_t group); /**@brief TODO:*/ uint32_t ext4_num_base_meta_clusters(struct ext4_sblock *s, - uint32_t block_group); + uint32_t block_group); #endif /* EXT4_SUPER_H_ */ diff --git a/lwext4/ext4_types.h b/lwext4/ext4_types.h index 953a70a..86ed318 100644 --- a/lwext4/ext4_types.h +++ b/lwext4/ext4_types.h @@ -51,102 +51,104 @@ * Structure of the super block */ struct ext4_sblock { - uint32_t inodes_count; /* I-nodes count */ - uint32_t blocks_count_lo; /* Blocks count */ - uint32_t reserved_blocks_count_lo; /* Reserved blocks count */ - uint32_t free_blocks_count_lo; /* Free blocks count */ - uint32_t free_inodes_count; /* Free inodes count */ - uint32_t first_data_block; /* First Data Block */ - uint32_t log_block_size; /* Block size */ - uint32_t log_cluster_size; /* Obsoleted fragment size */ - uint32_t blocks_per_group; /* Number of blocks per group */ - uint32_t frags_per_group; /* Obsoleted fragments per group */ - uint32_t inodes_per_group; /* Number of inodes per group */ - uint32_t mount_time; /* Mount time */ - uint32_t write_time; /* Write time */ - uint16_t mount_count; /* Mount count */ - uint16_t max_mount_count; /* Maximal mount count */ - uint16_t magic; /* Magic signature */ - uint16_t state; /* File system state */ - uint16_t errors; /* Behavior when detecting errors */ - uint16_t minor_rev_level; /* Minor revision level */ - uint32_t last_check_time; /* Time of last check */ - uint32_t check_interval; /* Maximum time between checks */ - uint32_t creator_os; /* Creator OS */ - uint32_t rev_level; /* Revision level */ - uint16_t def_resuid; /* Default uid for reserved blocks */ - uint16_t def_resgid; /* Default gid for reserved blocks */ - - /* Fields for EXT4_DYNAMIC_REV superblocks only. */ - uint32_t first_inode; /* First non-reserved inode */ - uint16_t inode_size; /* Size of inode structure */ - uint16_t block_group_index; /* Block group index of this superblock */ - uint32_t features_compatible; /* Compatible feature set */ - uint32_t features_incompatible; /* Incompatible feature set */ - uint32_t features_read_only; /* Readonly-compatible feature set */ - uint8_t uuid[16]; /* 128-bit uuid for volume */ - char volume_name[16]; /* Volume name */ - char last_mounted[64]; /* Directory where last mounted */ - uint32_t algorithm_usage_bitmap; /* For compression */ - - /* - * Performance hints. Directory preallocation should only - * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. - */ - uint8_t s_prealloc_blocks; /* Number of blocks to try to preallocate */ - uint8_t s_prealloc_dir_blocks; /* Number to preallocate for dirs */ - uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */ - - /* - * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set. - */ - uint8_t journal_uuid[16]; /* UUID of journal superblock */ - uint32_t journal_inode_number; /* Inode number of journal file */ - uint32_t journal_dev; /* Device number of journal file */ - uint32_t last_orphan; /* Head of list of inodes to delete */ - uint32_t hash_seed[4]; /* HTREE hash seed */ - uint8_t default_hash_version; /* Default hash version to use */ - uint8_t journal_backup_type; - uint16_t desc_size; /* Size of group descriptor */ - uint32_t default_mount_opts; /* Default mount options */ - uint32_t first_meta_bg; /* First metablock block group */ - uint32_t mkfs_time; /* When the filesystem was created */ - uint32_t journal_blocks[17]; /* Backup of the journal inode */ - - /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ - uint32_t blocks_count_hi; /* Blocks count */ - uint32_t reserved_blocks_count_hi; /* Reserved blocks count */ - uint32_t free_blocks_count_hi; /* Free blocks count */ - uint16_t min_extra_isize; /* All inodes have at least # bytes */ - uint16_t want_extra_isize; /* New inodes should reserve # bytes */ - uint32_t flags; /* Miscellaneous flags */ - uint16_t raid_stride; /* RAID stride */ - uint16_t mmp_interval; /* # seconds to wait in MMP checking */ - uint64_t mmp_block; /* Block for multi-mount protection */ - uint32_t raid_stripe_width; /* Blocks on all data disks (N * stride) */ - uint8_t log_groups_per_flex; /* FLEX_BG group size */ - uint8_t reserved_char_pad; - uint16_t reserved_pad; - uint64_t kbytes_written; /* Number of lifetime kilobytes written */ - uint32_t snapshot_inum; /* I-node number of active snapshot */ - uint32_t snapshot_id; /* Sequential ID of active snapshot */ - uint64_t snapshot_r_blocks_count; /* Reserved blocks for active snapshot's - future use */ - uint32_t snapshot_list; /* I-node number of the head of the on-disk snapshot - list */ - uint32_t error_count; /* Number of file system errors */ - uint32_t first_error_time; /* First time an error happened */ - uint32_t first_error_ino; /* I-node involved in first error */ - uint64_t first_error_block; /* Block involved of first error */ - uint8_t first_error_func[32]; /* Function where the error happened */ - uint32_t first_error_line; /* Line number where error happened */ - uint32_t last_error_time; /* Most recent time of an error */ - uint32_t last_error_ino; /* I-node involved in last error */ - uint32_t last_error_line; /* Line number where error happened */ - uint64_t last_error_block; /* Block involved of last error */ - uint8_t last_error_func[32]; /* Function where the error happened */ - uint8_t mount_opts[64]; - uint32_t padding[112]; /* Padding to the end of the block */ + uint32_t inodes_count; /* I-nodes count */ + uint32_t blocks_count_lo; /* Blocks count */ + uint32_t reserved_blocks_count_lo; /* Reserved blocks count */ + uint32_t free_blocks_count_lo; /* Free blocks count */ + uint32_t free_inodes_count; /* Free inodes count */ + uint32_t first_data_block; /* First Data Block */ + uint32_t log_block_size; /* Block size */ + uint32_t log_cluster_size; /* Obsoleted fragment size */ + uint32_t blocks_per_group; /* Number of blocks per group */ + uint32_t frags_per_group; /* Obsoleted fragments per group */ + uint32_t inodes_per_group; /* Number of inodes per group */ + uint32_t mount_time; /* Mount time */ + uint32_t write_time; /* Write time */ + uint16_t mount_count; /* Mount count */ + uint16_t max_mount_count; /* Maximal mount count */ + uint16_t magic; /* Magic signature */ + uint16_t state; /* File system state */ + uint16_t errors; /* Behavior when detecting errors */ + uint16_t minor_rev_level; /* Minor revision level */ + uint32_t last_check_time; /* Time of last check */ + uint32_t check_interval; /* Maximum time between checks */ + uint32_t creator_os; /* Creator OS */ + uint32_t rev_level; /* Revision level */ + uint16_t def_resuid; /* Default uid for reserved blocks */ + uint16_t def_resgid; /* Default gid for reserved blocks */ + + /* Fields for EXT4_DYNAMIC_REV superblocks only. */ + uint32_t first_inode; /* First non-reserved inode */ + uint16_t inode_size; /* Size of inode structure */ + uint16_t block_group_index; /* Block group index of this superblock */ + uint32_t features_compatible; /* Compatible feature set */ + uint32_t features_incompatible; /* Incompatible feature set */ + uint32_t features_read_only; /* Readonly-compatible feature set */ + uint8_t uuid[16]; /* 128-bit uuid for volume */ + char volume_name[16]; /* Volume name */ + char last_mounted[64]; /* Directory where last mounted */ + uint32_t algorithm_usage_bitmap; /* For compression */ + + /* + * Performance hints. Directory preallocation should only + * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. + */ + uint8_t s_prealloc_blocks; /* Number of blocks to try to preallocate */ + uint8_t s_prealloc_dir_blocks; /* Number to preallocate for dirs */ + uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */ + + /* + * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set. + */ + uint8_t journal_uuid[16]; /* UUID of journal superblock */ + uint32_t journal_inode_number; /* Inode number of journal file */ + uint32_t journal_dev; /* Device number of journal file */ + uint32_t last_orphan; /* Head of list of inodes to delete */ + uint32_t hash_seed[4]; /* HTREE hash seed */ + uint8_t default_hash_version; /* Default hash version to use */ + uint8_t journal_backup_type; + uint16_t desc_size; /* Size of group descriptor */ + uint32_t default_mount_opts; /* Default mount options */ + uint32_t first_meta_bg; /* First metablock block group */ + uint32_t mkfs_time; /* When the filesystem was created */ + uint32_t journal_blocks[17]; /* Backup of the journal inode */ + + /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ + uint32_t blocks_count_hi; /* Blocks count */ + uint32_t reserved_blocks_count_hi; /* Reserved blocks count */ + uint32_t free_blocks_count_hi; /* Free blocks count */ + uint16_t min_extra_isize; /* All inodes have at least # bytes */ + uint16_t want_extra_isize; /* New inodes should reserve # bytes */ + uint32_t flags; /* Miscellaneous flags */ + uint16_t raid_stride; /* RAID stride */ + uint16_t mmp_interval; /* # seconds to wait in MMP checking */ + uint64_t mmp_block; /* Block for multi-mount protection */ + uint32_t raid_stripe_width; /* Blocks on all data disks (N * stride) */ + uint8_t log_groups_per_flex; /* FLEX_BG group size */ + uint8_t reserved_char_pad; + uint16_t reserved_pad; + uint64_t kbytes_written; /* Number of lifetime kilobytes written */ + uint32_t snapshot_inum; /* I-node number of active snapshot */ + uint32_t snapshot_id; /* Sequential ID of active snapshot */ + uint64_t + snapshot_r_blocks_count; /* Reserved blocks for active snapshot's + future use */ + uint32_t + snapshot_list; /* I-node number of the head of the on-disk snapshot + list */ + uint32_t error_count; /* Number of file system errors */ + uint32_t first_error_time; /* First time an error happened */ + uint32_t first_error_ino; /* I-node involved in first error */ + uint64_t first_error_block; /* Block involved of first error */ + uint8_t first_error_func[32]; /* Function where the error happened */ + uint32_t first_error_line; /* Line number where error happened */ + uint32_t last_error_time; /* Most recent time of an error */ + uint32_t last_error_ino; /* I-node involved in last error */ + uint32_t last_error_line; /* Line number where error happened */ + uint64_t last_error_block; /* Block involved of last error */ + uint8_t last_error_func[32]; /* Function where the error happened */ + uint8_t mount_opts[64]; + uint32_t padding[112]; /* Padding to the end of the block */ } __attribute__((packed)); #define EXT4_SUPERBLOCK_MAGIC 0xEF53 @@ -213,10 +215,10 @@ struct ext4_sblock { #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 #define EXT4_FEATURE_INCOMPAT_MMP 0x0100 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 -#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 /* EA in inode */ -#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 /* data in dirent */ +#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 /* EA in inode */ +#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 /* data in dirent */ #define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */ -#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ +#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ /* @@ -225,11 +227,11 @@ struct ext4_sblock { #define EXT2_FEATURE_COMPAT_SUPP 0x0000 #define EXT2_FEATURE_INCOMPAT_SUPP \ - (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG) + (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG) #define EXT2_FEATURE_RO_COMPAT_SUPP \ - (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \ - EXT4_FEATURE_RO_COMPAT_BTREE_DIR) + (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \ + EXT4_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_BTREE_DIR) /* * EXT3 supported feature set @@ -237,11 +239,11 @@ struct ext4_sblock { #define EXT3_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX) #define EXT3_FEATURE_INCOMPAT_SUPP \ - (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG) + (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG) #define EXT3_FEATURE_RO_COMPAT_SUPP \ - (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \ - EXT4_FEATURE_RO_COMPAT_BTREE_DIR) + (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \ + EXT4_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_BTREE_DIR) /* * EXT4 supported feature set @@ -249,15 +251,16 @@ struct ext4_sblock { #define EXT4_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX) #define EXT4_FEATURE_INCOMPAT_SUPP \ - (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG | \ - EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_FLEX_BG | \ - EXT4_FEATURE_INCOMPAT_64BIT) + (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG | \ + EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_FLEX_BG | \ + EXT4_FEATURE_INCOMPAT_64BIT) #define EXT4_FEATURE_RO_COMPAT_SUPP \ - (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \ - EXT4_FEATURE_RO_COMPAT_GDT_CSUM | EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ - EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | EXT4_FEATURE_RO_COMPAT_BTREE_DIR | \ - EXT4_FEATURE_RO_COMPAT_HUGE_FILE) + (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \ + EXT4_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \ + EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ + EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \ + EXT4_FEATURE_RO_COMPAT_BTREE_DIR | EXT4_FEATURE_RO_COMPAT_HUGE_FILE) /*Ignored features: * RECOVER - journaling in lwext4 is not supported @@ -265,7 +268,7 @@ struct ext4_sblock { * MMP - multi-mout protection (impossible scenario) * */ #define FEATURE_INCOMPAT_IGNORED \ - EXT4_FEATURE_INCOMPAT_RECOVER | EXT4_FEATURE_INCOMPAT_MMP + EXT4_FEATURE_INCOMPAT_RECOVER | EXT4_FEATURE_INCOMPAT_MMP #if 0 /*TODO: Features incompatible to implement*/ @@ -280,13 +283,13 @@ struct ext4_sblock { #endif struct ext4_fs { - struct ext4_blockdev *bdev; - struct ext4_sblock sb; + struct ext4_blockdev *bdev; + struct ext4_sblock sb; - uint64_t inode_block_limits[4]; - uint64_t inode_blocks_per_level[4]; + uint64_t inode_block_limits[4]; + uint64_t inode_blocks_per_level[4]; - uint32_t last_inode_bg_id; + uint32_t last_inode_bg_id; }; /* Inode table/bitmap not in use */ @@ -300,38 +303,38 @@ struct ext4_fs { * Structure of a blocks group descriptor */ struct ext4_bgroup { - uint32_t block_bitmap_lo; /* Blocks bitmap block */ - uint32_t inode_bitmap_lo; /* Inodes bitmap block */ - uint32_t inode_table_first_block_lo; /* Inodes table block */ - uint16_t free_blocks_count_lo; /* Free blocks count */ - uint16_t free_inodes_count_lo; /* Free inodes count */ - uint16_t used_dirs_count_lo; /* Directories count */ - uint16_t flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ - uint32_t exclude_bitmap_lo; /* Exclude bitmap for snapshots */ - uint16_t block_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+bbitmap) LE */ - uint16_t inode_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+ibitmap) LE */ - uint16_t itable_unused_lo; /* Unused inodes count */ - uint16_t checksum; /* crc16(sb_uuid+group+desc) */ - - uint32_t block_bitmap_hi; /* Blocks bitmap block MSB */ - uint32_t inode_bitmap_hi; /* I-nodes bitmap block MSB */ - uint32_t inode_table_first_block_hi; /* I-nodes table block MSB */ - uint16_t free_blocks_count_hi; /* Free blocks count MSB */ - uint16_t free_inodes_count_hi; /* Free i-nodes count MSB */ - uint16_t used_dirs_count_hi; /* Directories count MSB */ - uint16_t itable_unused_hi; /* Unused inodes count MSB */ - uint32_t exclude_bitmap_hi; /* Exclude bitmap block MSB */ - uint16_t block_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+bbitmap) BE */ - uint16_t inode_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+ibitmap) BE */ - uint32_t reserved; /* Padding */ + uint32_t block_bitmap_lo; /* Blocks bitmap block */ + uint32_t inode_bitmap_lo; /* Inodes bitmap block */ + uint32_t inode_table_first_block_lo; /* Inodes table block */ + uint16_t free_blocks_count_lo; /* Free blocks count */ + uint16_t free_inodes_count_lo; /* Free inodes count */ + uint16_t used_dirs_count_lo; /* Directories count */ + uint16_t flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ + uint32_t exclude_bitmap_lo; /* Exclude bitmap for snapshots */ + uint16_t block_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+bbitmap) LE */ + uint16_t inode_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+ibitmap) LE */ + uint16_t itable_unused_lo; /* Unused inodes count */ + uint16_t checksum; /* crc16(sb_uuid+group+desc) */ + + uint32_t block_bitmap_hi; /* Blocks bitmap block MSB */ + uint32_t inode_bitmap_hi; /* I-nodes bitmap block MSB */ + uint32_t inode_table_first_block_hi; /* I-nodes table block MSB */ + uint16_t free_blocks_count_hi; /* Free blocks count MSB */ + uint16_t free_inodes_count_hi; /* Free i-nodes count MSB */ + uint16_t used_dirs_count_hi; /* Directories count MSB */ + uint16_t itable_unused_hi; /* Unused inodes count MSB */ + uint32_t exclude_bitmap_hi; /* Exclude bitmap block MSB */ + uint16_t block_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+bbitmap) BE */ + uint16_t inode_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+ibitmap) BE */ + uint32_t reserved; /* Padding */ }; struct ext4_block_group_ref { - struct ext4_block block; - struct ext4_bgroup *block_group; - struct ext4_fs *fs; - uint32_t index; - bool dirty; + struct ext4_block block; + struct ext4_bgroup *block_group; + struct ext4_fs *fs; + uint32_t index; + bool dirty; }; #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32 @@ -349,55 +352,56 @@ struct ext4_block_group_ref { #define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1) #define EXT4_INODE_BLOCKS (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1) #define EXT4_INODE_INDIRECT_BLOCK_COUNT \ - (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT) + (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT) /* * Structure of an inode on the disk */ struct ext4_inode { - uint16_t mode; /* File mode */ - uint16_t uid; /* Low 16 bits of owner uid */ - uint32_t size_lo; /* Size in bytes */ - uint32_t access_time; /* Access time */ - uint32_t change_inode_time; /* I-node change time */ - uint32_t modification_time; /* Modification time */ - uint32_t deletion_time; /* Deletion time */ - uint16_t gid; /* Low 16 bits of group id */ - uint16_t links_count; /* Links count */ - uint32_t blocks_count_lo; /* Blocks count */ - uint32_t flags; /* File flags */ - uint32_t unused_osd1; /* OS dependent - not used in HelenOS */ - uint32_t blocks[EXT4_INODE_BLOCKS]; /* Pointers to blocks */ - uint32_t generation; /* File version (for NFS) */ - uint32_t file_acl_lo; /* File ACL */ - uint32_t size_hi; - uint32_t obso_faddr; /* Obsoleted fragment address */ - - union { - struct { - uint16_t blocks_high; - uint16_t file_acl_high; - uint16_t uid_high; - uint16_t gid_high; - uint32_t reserved2; - } linux2; - struct { - uint16_t reserved1; - uint16_t mode_high; - uint16_t uid_high; - uint16_t gid_high; - uint32_t author; - } hurd2; - } __attribute__((packed)) osd2; - - uint16_t extra_isize; - uint16_t pad1; - uint32_t ctime_extra; /* Extra change time (nsec << 2 | epoch) */ - uint32_t mtime_extra; /* Extra Modification time (nsec << 2 | epoch) */ - uint32_t atime_extra; /* Extra Access time (nsec << 2 | epoch) */ - uint32_t crtime; /* File creation time */ - uint32_t crtime_extra; /* Extra file creation time (nsec << 2 | epoch) */ - uint32_t version_hi; /* High 32 bits for 64-bit version */ + uint16_t mode; /* File mode */ + uint16_t uid; /* Low 16 bits of owner uid */ + uint32_t size_lo; /* Size in bytes */ + uint32_t access_time; /* Access time */ + uint32_t change_inode_time; /* I-node change time */ + uint32_t modification_time; /* Modification time */ + uint32_t deletion_time; /* Deletion time */ + uint16_t gid; /* Low 16 bits of group id */ + uint16_t links_count; /* Links count */ + uint32_t blocks_count_lo; /* Blocks count */ + uint32_t flags; /* File flags */ + uint32_t unused_osd1; /* OS dependent - not used in HelenOS */ + uint32_t blocks[EXT4_INODE_BLOCKS]; /* Pointers to blocks */ + uint32_t generation; /* File version (for NFS) */ + uint32_t file_acl_lo; /* File ACL */ + uint32_t size_hi; + uint32_t obso_faddr; /* Obsoleted fragment address */ + + union { + struct { + uint16_t blocks_high; + uint16_t file_acl_high; + uint16_t uid_high; + uint16_t gid_high; + uint32_t reserved2; + } linux2; + struct { + uint16_t reserved1; + uint16_t mode_high; + uint16_t uid_high; + uint16_t gid_high; + uint32_t author; + } hurd2; + } __attribute__((packed)) osd2; + + uint16_t extra_isize; + uint16_t pad1; + uint32_t ctime_extra; /* Extra change time (nsec << 2 | epoch) */ + uint32_t mtime_extra; /* Extra Modification time (nsec << 2 | epoch) */ + uint32_t atime_extra; /* Extra Access time (nsec << 2 | epoch) */ + uint32_t crtime; /* File creation time */ + uint32_t + crtime_extra; /* Extra file creation time (nsec << 2 | epoch) */ + uint32_t version_hi; /* High 32 bits for 64-bit version */ } __attribute__((packed)); #define EXT4_INODE_MODE_FIFO 0x1000 @@ -424,17 +428,17 @@ struct ext4_inode { /* Compression flags */ #define EXT4_INODE_FLAG_DIRTY 0x00000100 #define EXT4_INODE_FLAG_COMPRBLK \ - 0x00000200 /* One or more compressed clusters */ + 0x00000200 /* One or more compressed clusters */ #define EXT4_INODE_FLAG_NOCOMPR 0x00000400 /* Don't compress */ #define EXT4_INODE_FLAG_ECOMPR 0x00000800 /* Compression error */ #define EXT4_INODE_FLAG_INDEX 0x00001000 /* hash-indexed directory */ #define EXT4_INODE_FLAG_IMAGIC 0x00002000 /* AFS directory */ #define EXT4_INODE_FLAG_JOURNAL_DATA \ - 0x00004000 /* File data should be journaled */ + 0x00004000 /* File data should be journaled */ #define EXT4_INODE_FLAG_NOTAIL 0x00008000 /* File tail should not be merged */ #define EXT4_INODE_FLAG_DIRSYNC \ - 0x00010000 /* Dirsync behaviour (directories only) */ + 0x00010000 /* Dirsync behaviour (directories only) */ #define EXT4_INODE_FLAG_TOPDIR 0x00020000 /* Top of directory hierarchies */ #define EXT4_INODE_FLAG_HUGE_FILE 0x00040000 /* Set to each huge file */ #define EXT4_INODE_FLAG_EXTENTS 0x00080000 /* Inode uses extents */ @@ -445,11 +449,11 @@ struct ext4_inode { #define EXT4_INODE_ROOT_INDEX 2 struct ext4_inode_ref { - struct ext4_block block; - struct ext4_inode *inode; - struct ext4_fs *fs; - uint32_t index; - bool dirty; + struct ext4_block block; + struct ext4_inode *inode; + struct ext4_fs *fs; + uint32_t index; + bool dirty; }; #define EXT4_DIRECTORY_FILENAME_LEN 255 @@ -464,85 +468,85 @@ struct ext4_inode_ref { #define EXT4_DIRECTORY_FILETYPE_SYMLINK 7 union ext4_directory_entry_ll_internal { - uint8_t name_length_high; /* Higher 8 bits of name length */ - uint8_t inode_type; /* Type of referenced inode (in rev >= 0.5) */ + uint8_t name_length_high; /* Higher 8 bits of name length */ + uint8_t inode_type; /* Type of referenced inode (in rev >= 0.5) */ } __attribute__((packed)); /** * Linked list directory entry structure */ struct ext4_directory_entry_ll { - uint32_t inode; /* I-node for the entry */ - uint16_t entry_length; /* Distance to the next directory entry */ - uint8_t name_length; /* Lower 8 bits of name length */ + uint32_t inode; /* I-node for the entry */ + uint16_t entry_length; /* Distance to the next directory entry */ + uint8_t name_length; /* Lower 8 bits of name length */ - union ext4_directory_entry_ll_internal in; + union ext4_directory_entry_ll_internal in; - uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; /* Entry name */ + uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; /* Entry name */ } __attribute__((packed)); struct ext4_directory_iterator { - struct ext4_inode_ref *inode_ref; - struct ext4_block current_block; - uint64_t current_offset; - struct ext4_directory_entry_ll *current; + struct ext4_inode_ref *inode_ref; + struct ext4_block current_block; + uint64_t current_offset; + struct ext4_directory_entry_ll *current; }; struct ext4_directory_search_result { - struct ext4_block block; - struct ext4_directory_entry_ll *dentry; + struct ext4_block block; + struct ext4_directory_entry_ll *dentry; }; /* Structures for indexed directory */ struct ext4_directory_dx_countlimit { - uint16_t limit; - uint16_t count; + uint16_t limit; + uint16_t count; }; struct ext4_directory_dx_dot_entry { - uint32_t inode; - uint16_t entry_length; - uint8_t name_length; - uint8_t inode_type; - uint8_t name[4]; + uint32_t inode; + uint16_t entry_length; + uint8_t name_length; + uint8_t inode_type; + uint8_t name[4]; }; struct ext4_directory_dx_root_info { - uint32_t reserved_zero; - uint8_t hash_version; - uint8_t info_length; - uint8_t indirect_levels; - uint8_t unused_flags; + uint32_t reserved_zero; + uint8_t hash_version; + uint8_t info_length; + uint8_t indirect_levels; + uint8_t unused_flags; }; struct ext4_directory_dx_entry { - uint32_t hash; - uint32_t block; + uint32_t hash; + uint32_t block; }; struct ext4_directory_dx_root { - struct ext4_directory_dx_dot_entry dots[2]; - struct ext4_directory_dx_root_info info; - struct ext4_directory_dx_entry entries[]; + struct ext4_directory_dx_dot_entry dots[2]; + struct ext4_directory_dx_root_info info; + struct ext4_directory_dx_entry entries[]; }; struct ext4_fake_directory_entry { - uint32_t inode; - uint16_t entry_length; - uint8_t name_length; - uint8_t inode_type; + uint32_t inode; + uint16_t entry_length; + uint8_t name_length; + uint8_t inode_type; }; struct ext4_directory_dx_node { - struct ext4_fake_directory_entry fake; - struct ext4_directory_dx_entry entries[]; + struct ext4_fake_directory_entry fake; + struct ext4_directory_dx_entry entries[]; }; struct ext4_directory_dx_block { - struct ext4_block block; - struct ext4_directory_dx_entry *entries; - struct ext4_directory_dx_entry *position; + struct ext4_block block; + struct ext4_directory_dx_entry *entries; + struct ext4_directory_dx_entry *position; }; #define EXT4_ERR_BAD_DX_DIR (-25000) @@ -554,10 +558,10 @@ struct ext4_directory_dx_block { * It's used at the bottom of the tree. */ struct ext4_extent { - uint32_t first_block; /* First logical block extent covers */ - uint16_t block_count; /* Number of blocks covered by extent */ - uint16_t start_hi; /* High 16 bits of physical block */ - uint32_t start_lo; /* Low 32 bits of physical block */ + uint32_t first_block; /* First logical block extent covers */ + uint16_t block_count; /* Number of blocks covered by extent */ + uint16_t start_hi; /* High 16 bits of physical block */ + uint32_t start_lo; /* Low 32 bits of physical block */ }; /* @@ -565,46 +569,46 @@ struct ext4_extent { * It's used at all the levels except the bottom. */ struct ext4_extent_index { - uint32_t first_block; /* Index covers logical blocks from 'block' */ - - /** - * Pointer to the physical block of the next - * level. leaf or next index could be there - * high 16 bits of physical block - */ - uint32_t leaf_lo; - uint16_t leaf_hi; - uint16_t padding; + uint32_t first_block; /* Index covers logical blocks from 'block' */ + + /** + * Pointer to the physical block of the next + * level. leaf or next index could be there + * high 16 bits of physical block + */ + uint32_t leaf_lo; + uint16_t leaf_hi; + uint16_t padding; }; /* * Each block (leaves and indexes), even inode-stored has header. */ struct ext4_extent_header { - uint16_t magic; - uint16_t entries_count; /* Number of valid entries */ - uint16_t max_entries_count; /* Capacity of store in entries */ - uint16_t depth; /* Has tree real underlying blocks? */ - uint32_t generation; /* generation of the tree */ + uint16_t magic; + uint16_t entries_count; /* Number of valid entries */ + uint16_t max_entries_count; /* Capacity of store in entries */ + uint16_t depth; /* Has tree real underlying blocks? */ + uint32_t generation; /* generation of the tree */ }; struct ext4_extent_path { - struct ext4_block block; - uint16_t depth; - struct ext4_extent_header *header; - struct ext4_extent_index *index; - struct ext4_extent *extent; + struct ext4_block block; + uint16_t depth; + struct ext4_extent_header *header; + struct ext4_extent_index *index; + struct ext4_extent *extent; }; #define EXT4_EXTENT_MAGIC 0xF30A #define EXT4_EXTENT_FIRST(header) \ - ((struct ext4_extent *)(((char *)(header)) + \ - sizeof(struct ext4_extent_header))) + ((struct ext4_extent *)(((char *)(header)) + \ + sizeof(struct ext4_extent_header))) #define EXT4_EXTENT_FIRST_INDEX(header) \ - ((struct ext4_extent_index *)(((char *)(header)) + \ - sizeof(struct ext4_extent_header))) + ((struct ext4_extent_index *)(((char *)(header)) + \ + sizeof(struct ext4_extent_header))) /* EXT3 HTree directory indexing */ #define EXT2_HTREE_LEGACY 0 @@ -617,10 +621,10 @@ struct ext4_extent_path { #define EXT2_HTREE_EOF 0x7FFFFFFFUL struct ext4_hash_info { - uint32_t hash; - uint32_t minor_hash; - uint32_t hash_version; - const uint32_t *seed; + uint32_t hash; + uint32_t minor_hash; + uint32_t hash_version; + const uint32_t *seed; }; /*****************************************************************************/ @@ -628,21 +632,22 @@ struct ext4_hash_info { #ifdef CONFIG_BIG_ENDIAN static inline uint64_t to_le64(uint64_t n) { - return ((n & 0xff) << 56) | ((n & 0xff00) << 40) | ((n & 0xff0000) << 24) | - ((n & 0xff000000LL) << 8) | ((n & 0xff00000000LL) >> 8) | - ((n & 0xff0000000000LL) >> 24) | ((n & 0xff000000000000LL) >> 40) | - ((n & 0xff00000000000000LL) >> 56); + return ((n & 0xff) << 56) | ((n & 0xff00) << 40) | + ((n & 0xff0000) << 24) | ((n & 0xff000000LL) << 8) | + ((n & 0xff00000000LL) >> 8) | ((n & 0xff0000000000LL) >> 24) | + ((n & 0xff000000000000LL) >> 40) | + ((n & 0xff00000000000000LL) >> 56); } static inline uint32_t to_le32(uint32_t n) { - return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | - ((n & 0xff000000) >> 24); + return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | + ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); } static inline uint16_t to_le16(uint16_t n) { - return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); } #else @@ -658,16 +663,16 @@ static inline uint16_t to_le16(uint16_t n) #define ext4_get8(s, f) (s)->f #define ext4_set32(s, f, v) \ - do { \ - (s)->f = to_le32(v); \ - } while (0) + do { \ + (s)->f = to_le32(v); \ + } while (0) #define ext4_set16(s, f, v) \ - do { \ - (s)->f = to_le16(v); \ - } while (0) + do { \ + (s)->f = to_le16(v); \ + } while (0) #define ext4_set8 \ - (s, f, v) do { (s)->f = (v); } \ - while (0) + (s, f, v) do { (s)->f = (v); } \ + while (0) #endif /* EXT4_TYPES_H_ */ |
