void MakeLog(void){ uint16_t crc_main = 0xffff; if (gf_buffer_indicator == 1){ //if this flag is 1 we must send the g_buffer_uSD_2 for (uint16_t i=0;i<BUFFER_SIZE-2;i++) { //calculating the CRC crc_main = (uint16_t)(crc_main + g_buffer_uSD_2[i]); } g_buffer_uSD_2[BUFFER_SIZE-1] = lo8(crc_main); g_buffer_uSD_2[BUFFER_SIZE-2] = hi8(crc_main); g_error = f_lseek(&f_origem, f_size(&f_origem)); //looks for the end of the file //TODO:: do something with those errors g_error = f_write(&f_origem, g_buffer_uSD_2, BUFFER_SIZE, &br); //write the buffer on the end of the file g_error = f_sync(&f_origem); //waits for it to finish } else{ //if gf_buffer_indicator is 0 we must send the g_buffer_uSD for (uint16_t i=0;i<BUFFER_SIZE-2;i++) {//calculating the CRC crc_main = (uint16_t)(crc_main + g_buffer_uSD[i]); } g_buffer_uSD[BUFFER_SIZE-1] = lo8(crc_main); g_buffer_uSD[BUFFER_SIZE-2] = hi8(crc_main); g_error = f_lseek(&f_origem, f_size(&f_origem)); //TODO:: do something with this error g_error = f_write(&f_origem, g_buffer_uSD, BUFFER_SIZE, &br); g_error = f_sync(&f_origem); }//close else }
uint32_t file_size_w_buf(FIL *fp) { if (fp->flag & FA_READ) { return f_size(fp); } else { return f_size(fp) + file_buffer_index; } }
void f_dump(void) { file_id_t i; int j; for (i = FILE1; i < FILE_ID_END; i++) { printf("FILE %u: addr = %lu, len = %lu, size = %lu\n", i + 1, \ f_addr(i), f_len(i), f_size(i)); for (j = 0; j < f_size(i); j++) putchar(DISK[f_addr(i) + j]); putchar('\n'); } }
int fatfs_pwrite(struct block_cache *output, off_t block_offset, const char *filename, int offset, const char *buffer, off_t size) { // Check if this is the same file as a previous pwrite call if (current_file_ && strcmp(current_file_, filename) != 0) close_open_files(); MAYBE_MOUNT(output, block_offset); if (!current_file_) { CHECK("fat_write can't open file", filename, f_open(&fil_, filename, FA_OPEN_ALWAYS | FA_WRITE)); // Assuming it opens ok, cache the filename for future writes. current_file_ = strdup(filename); } // Check if this pwrite requires a seek. DWORD desired_offset = offset; if (desired_offset != f_tell(&fil_)) { // Need to seek, but if we're seeking past the end, be sure to fill in with zeros. if (desired_offset > f_size(&fil_)) { // Seek to the end CHECK("fat_write can't seek to end of file", filename, f_lseek(&fil_, f_size(&fil_))); // Write zeros. DWORD zero_count = desired_offset - f_tell(&fil_); char zero_buffer[FWUP_BLOCK_SIZE]; memset(zero_buffer, 0, sizeof(zero_buffer)); while (zero_count) { DWORD btw = (zero_count < sizeof(zero_buffer) ? zero_count : sizeof(zero_buffer)); UINT bw; CHECK("fat_write can't write", filename, f_write(&fil_, zero_buffer, btw, &bw)); if (btw != bw) ERR_RETURN("Error writing file to FAT: %s, expected %ld bytes written, got %d (maybe the disk is full?)", filename, size, bw); zero_count -= bw; } } else { CHECK("fat_write can't seek in file", filename, f_lseek(&fil_, desired_offset)); } } UINT bw; CHECK("fat_write can't write", filename, f_write(&fil_, buffer, size, &bw)); if (size != bw) ERR_RETURN("Error writing file to FAT: %s, expected %ld bytes written, got %d (maybe the disk is full?)", filename, size, bw); return 0; }
void logBootInfo(const char *pExtraInfo) { const char filename[] = "0:boot.csv"; char logMsg[128] = { 0 }; char dateTime[24] = { 0 }; rtc_getDateTimeString(dateTime); if(rebootType_watchdogRecover == getRebootCause()) { sprintf(logMsg, "%s, BAD BOOT (%s): PC: 0x%08X LR: 0x%08X PSR: 0x%08X\n", dateTime, pExtraInfo, (unsigned int)FAULT_PC, (unsigned int)FAULT_LR, (unsigned int)FAULT_PSR); } else { sprintf(logMsg, "%s, NORMAL BOOT (%s)\n", dateTime, pExtraInfo); } FIL file; unsigned int bytesWritten = 0; if (FR_OK == f_open(&file, filename, FA_OPEN_ALWAYS | FA_WRITE)) { if(FR_OK == f_lseek(&file, f_size(&file))) { f_write(&file, logMsg, strlen(logMsg), &bytesWritten); } f_close(&file); } if(strlen(logMsg) != bytesWritten) { puts("Error writing boot info"); } }
static u32 loadPayload(const char *pattern) { char path[30] = "/luma/payloads"; DIR dir; FILINFO info; FRESULT result = f_findfirst(&dir, &info, path, pattern); f_closedir(&dir); if(result != FR_OK || !info.fname[0]) return 0; path[14] = '/'; u32 i; for(i = 0; info.fname[i]; i++) path[15 + i] = info.fname[i]; path[15 + i] = '\0'; FIL payload; unsigned int br; f_open(&payload, path, FA_READ); f_read(&payload, (void *)PAYLOAD_ADDRESS, f_size(&payload), &br); f_close(&payload); return 1; }
/** * Writes (appends) data stream to a file * * \param FIL* fobj - file object to be used (NOTE: remember to use '&' operator) * \param char* srcBuff - buffer to fill with data read * \param unsigned long to_write - amount of data to write on file * \return WORD - amount of data written */ WORD SDStreamWrite(FIL* fobj, char *srcBuff, unsigned long to_write) { #if _FS_READONLY return FALSE; #else unsigned int len; BOOL streamResult; if ((fobj->flag && FA_WRITE) != 0) { // Seek to the end of file streamResult = f_lseek(fobj, f_size(fobj)); if (streamResult != FR_OK) { errManager(); fileClose(fobj); return 0; } // Append of the text at the end of file streamResult = f_write(fobj, srcBuff, to_write, &len); if ( (streamResult != FR_OK) || (len != to_write) ) { SDdebug("ERROR on write\n"); errManager(); fileClose(fobj); return 0; } else return len; } else return 0; #endif }
u32 IdentifyImage(const char* path) { u8 header[0x200]; FIL file; if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) return 0; f_lseek(&file, 0); f_sync(&file); UINT fsize = f_size(&file); UINT bytes_read; if ((f_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) { f_close(&file); return 0; } f_close(&file); if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) && (getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) { return IMG_NAND; } else if (getbe16(header + 0x1FE) == 0x55AA) { // migt be FAT or MBR if ((strncmp((char*) header + 0x36, "FAT12 ", 8) == 0) || (strncmp((char*) header + 0x36, "FAT16 ", 8) == 0) || (strncmp((char*) header + 0x36, "FAT ", 8) == 0) || (strncmp((char*) header + 0x52, "FAT32 ", 8) == 0)) { return IMG_FAT; // this is an actual FAT header } else if (((getle32(header + 0x1BE + 0x8) + getle32(header + 0x1BE + 0xC)) < (fsize / 0x200)) && // check file size (getle32(header + 0x1BE + 0x8) > 0) && (getle32(header + 0x1BE + 0xC) >= 0x800) && // check first partition sanity ((header[0x1BE + 0x4] == 0x1) || (header[0x1BE + 0x4] == 0x4) || (header[0x1BE + 0x4] == 0x6) || // filesystem type (header[0x1BE + 0x4] == 0xB) || (header[0x1BE + 0x4] == 0xC) || (header[0x1BE + 0x4] == 0xE))) { return IMG_FAT; // this might be an MBR -> give it the benefit of doubt } } return 0; }
SDFS_status_type SDFS_open(FIL* fp, const char* name, FMODE_t mode) { SDFS_status_type ret_wert = SDFS_OPEN_ERR; FRESULT check = FR_INVALID_PARAMETER; switch (mode) { case F_RD: check = f_open(fp, name, FA_OPEN_EXISTING | FA_READ); break; case F_WR: check = f_open(fp, name, FA_OPEN_EXISTING | FA_WRITE); break; case F_WR_NEW: check = f_open(fp, name, FA_OPEN_ALWAYS | FA_WRITE); break; case F_WR_CLEAR: check = f_open(fp, name, FA_CREATE_ALWAYS | FA_WRITE); break; } if (check == FR_OK) { ret_wert = SDFS_OK; if ((mode == F_WR) || (mode == F_WR_NEW)) { check = f_lseek(fp, f_size(fp)); if (check != FR_OK) { ret_wert = SDFS_SEEK_ERR; } } } else { ret_wert = SDFS_OPEN_ERR; } return (ret_wert); }
static void rand_arr(struct f_test_arr_t *arr, int len) { file_id_t id; int r; for (id = FILE1; id < FILE_ID_END; id++) { r = rand(); arr[id].offset = r % f_size(id); srand(r); r = rand(); arr[id].len = r % f_size(id) + 1; srand(r); if (arr[id].offset > arr[id].len) arr[id].len = f_size(id) - arr[id].offset; if (arr[id].offset + arr[id].len > f_size(id)) arr[id].len = f_size(id) - arr[id].offset; } }
void LogSave(uint8_t type) { FRESULT f_result; FIL file; uint32_t cnt, tmp; struct Date date; f_result = f_open(&file, "system/log.f", FA_OPEN_EXISTING | FA_WRITE | FA_READ); if (f_result != FR_OK) { f_open(&file, "system/log.f", FA_CREATE_NEW | FA_WRITE); cnt = 1; } else { f_read(&file, (void *) &cnt, 4, &tmp); cnt++; } f_lseek(&file, 0); // save log file size f_write(&file, (void *) &cnt, 4, &tmp); vTaskDelay(100); // go to end of file f_lseek(&file, f_size(&file)); // save log data GetCurrentDate(&date); f_write(&file, (void *) (void *) (&date), sizeof(struct Date), &tmp); vTaskDelay(100); // save log type f_write(&file, (void *) (void *) (&type), 1, &tmp); vTaskDelay(100); f_close(&file); }
static off_t _lseek(vfs_file_t *filp, off_t off, int whence) { fatfs_file_desc_t *fd = (fatfs_file_desc_t *)filp->private_data.buffer; FRESULT res; off_t new_pos = 0; if (whence == SEEK_SET) { new_pos = off; } else if (whence == SEEK_CUR) { new_pos = f_tell(&fd->file) + off; } else if (whence == SEEK_END) { new_pos = f_size(&fd->file) + off; } else { return fatfs_err_to_errno(FR_INVALID_PARAMETER); } res = f_lseek(&fd->file, new_pos); if (res == FR_OK) { return new_pos; } return fatfs_err_to_errno(res); }
int save_buffer (FileType FT, char *buff){ FIL file; char* filename = "log.txt"; switch (FT) { case DATA: filename = "actual.dat"; break; case LOG: filename = "log.txt"; break; case SETTINGS: filename = "settings.ini"; break; } unsigned int bw; //Кол-во записанных байтов if (f_mount(&Fatfs, "0:", 1) == FR_OK){ //Монтируемся f_open (&file, filename, FA_WRITE | FA_OPEN_ALWAYS); //Открываем или создаем f_lseek(&file, f_size(&file)); //Идем в конец файла f_write(&file, buff, strlen(buff), &bw); //Write data to the file f_close(&file); //Закрываем и тем самым производим запись на диск f_mount(NULL, "0:", 1); //Unmount } return 0; }
STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { pyb_file_obj_t *self = MP_OBJ_TO_PTR(o_in); if (request == MP_STREAM_SEEK) { struct mp_stream_seek_t *s = (struct mp_stream_seek_t*)(uintptr_t)arg; switch (s->whence) { case 0: // SEEK_SET f_lseek(&self->fp, s->offset); break; case 1: // SEEK_CUR if (s->offset != 0) { *errcode = MP_EOPNOTSUPP; return MP_STREAM_ERROR; } // no-operation break; case 2: // SEEK_END f_lseek(&self->fp, f_size(&self->fp) + s->offset); break; } s->offset = f_tell(&self->fp); return 0; } else { *errcode = MP_EINVAL; return MP_STREAM_ERROR; } }
/*---------------------------------------------------------------------------*/ void initialize_userland(void) { FIL paramFile; //J パラメータファイルからパラメータを読み込む char fileName[16] = "uparam.txt"; int8_t ret = f_open(¶mFile, fileName, FA_READ); if (ret == FR_OK) { char line[100]; while (f_gets(line, 100, ¶mFile) != NULL) { setupParams(line, sCheckAndStoreParam); } f_close(¶mFile); } else { } //J ユーザログファイルを開く char logFileName[16] = "ulog.txt"; ret = f_open(&sLogFile, logFileName, FA_WRITE | FA_OPEN_ALWAYS); //J 基本追記でやります if (ret == FR_OK) { UINT len = 0; f_lseek(&sLogFile, f_size(&sLogFile)); f_write(&sLogFile, "-- Start Userland\n", 18, &len); f_sync(&sLogFile); } else { } return; }
THD_FUNCTION( sd_logger, p ) { (void) p; struct sdlog_stru * plog; FIL file; UINT nb; BYTE mode; chRegSetThreadName( "sd_logger" ); while( true ) { thread_t * tp = chMsgWait(); plog = (struct sdlog_stru *) chMsgGet( tp ); DEBUG_PRINT( "Write to file %s\r\n%s\r\n", plog->file, plog->line ); mode = FA_WRITE | ( plog->append ? FA_OPEN_ALWAYS : FA_CREATE_ALWAYS ); if( f_open( & file, plog->file, mode ) == FR_OK ) { if( plog->append ) f_lseek( & file, f_size( & file )); f_write( & file, plog->line, strlen( plog->line ), (UINT *) & nb ); f_close( & file ); } chMsgRelease( tp, MSG_OK ); } }
void ZP_CreateLogFile(void) { char file[50]; uint32_t ul_hour, ul_minute, ul_second; uint32_t ul_year, ul_month, ul_day, ul_week; rtc_get_time(RTC, &ul_hour, &ul_minute, &ul_second); rtc_get_date(RTC, &ul_year, &ul_month, &ul_day, &ul_week); f_mkdir("0:Logs"); sprintf(file, "0:logs/%04u", ul_year); f_mkdir((char const *)file); sprintf(file, "0:logs/%04u/%02u", ul_year, ul_month); f_mkdir((char const *)file); sprintf(file, "0:logs/%04u/%02u/%02u", ul_year, ul_month, ul_day); f_mkdir((char const *)file); sprintf(file, "0:Logs/%04u/%02u/%02u/Flight_Log_%02u.%02u.%02u.log", ul_year, ul_month, ul_day, ul_hour, ul_minute, ul_second); f_open(&f_log, (char const *)file, FA_CREATE_ALWAYS | FA_WRITE); f_puts("Goblin-Tech", &f_log); f_puts("GT101-0001", &f_log); f_puts("00.00.00", &f_log); uint16_t size = f_size(&f_script); uint8_t dummy; f_write(&f_log, &size, 2, &dummy); f_write(&f_log, &Script, size, &dummy); f_sync(&f_log); }
int main(void) { DelayInit(); GPIO_QuickInit(HW_GPIOE, 6, kGPIO_Mode_OPP); UART_QuickInit(UART0_RX_PD06_TX_PD07, 115200); printf("FATFS test\r\n"); printf("please insert SD card...\r\n"); if(SD_QuickInit(20*1000*1000)) { printf("SD card init failed!\r\n"); while(1); } printf("SD size:%dMB\r\n", SD_GetSizeInMB()); FRESULT rc; FATFS fs_sd; FIL fil; FATFS *fs; fs = &fs_sd; UINT bw,br; /* bw = byte writted br = byte readed */ DWORD fre_clust, fre_sect, tot_sect; /* 挂载文件系统 */ rc = f_mount(fs, "0:", 0); ERROR_TRACE(rc); rc = f_getfree("0:", &fre_clust, &fs); ERROR_TRACE(rc); /* 计算磁盘空间及剩余空间 */ tot_sect = (fs->n_fatent - 2) * fs->csize; fre_sect = fre_clust * fs->csize; printf("%d KB total drive space.\r\n%d KB available.\r\n", tot_sect / 2, fre_sect / 2); /* 写入文件 */ printf("open or create file\r\n"); rc = f_open(&fil, "0:/fatfs.txt", FA_WRITE | FA_CREATE_ALWAYS); ERROR_TRACE(rc); printf("write file\r\n"); rc = f_write(&fil, "HelloWorld\r\n", 12, &bw); ERROR_TRACE(rc); printf("%d bytes writen\r\n", bw); rc = f_close(&fil); /* 读取文件 */ rc = f_open(&fil, "0:/fatfs.txt", FA_READ); ERROR_TRACE(rc); printf("file size:%l\r\n", f_size(&fil)); printf("file contents:\r\n"); while(1) { rc = f_read(&fil, buf, sizeof(buf), &br); if(rc || !br ) break; printf("%s", buf); } rc = f_close(&fil); ERROR_TRACE(rc); while(1) { GPIO_ToggleBit(HW_GPIOE, 6); DelayMs(500); } }
void OnGetFileSize(nwazetMessageContext_t* nmc){ fileObjectMap_t* fileObj = GetFileObjectById(nmc); if(fileObj){ uint32_t size = f_size(fileObj->file); StartResponse(nmc, FR_OK, false); Put(nmc->respContext, (void*)&size, sizeof(size), 1); EndResponse(nmc); } }
STATIC mp_obj_t file_obj_make_new(mp_obj_t type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); const char *fname = mp_obj_str_get_str(args[0]); int mode = 0; if (n_args == 1) { mode = FA_READ; } else { const char *mode_s = mp_obj_str_get_str(args[1]); // TODO make sure only one of r, w, x, a, and b, t are specified while (*mode_s) { switch (*mode_s++) { case 'r': mode |= FA_READ; break; case 'w': mode |= FA_WRITE | FA_CREATE_ALWAYS; break; case 'x': mode |= FA_WRITE | FA_CREATE_NEW; break; case 'a': mode |= FA_WRITE | FA_OPEN_ALWAYS; break; case '+': mode |= FA_READ | FA_WRITE; break; #if MICROPY_PY_IO_FILEIO case 'b': type = (mp_obj_t)&mp_type_fileio; break; #endif case 't': type = (mp_obj_t)&mp_type_textio; break; } } } pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); o->base.type = type; FRESULT res = f_open(&o->fp, fname, mode); if (res != FR_OK) { m_del_obj(pyb_file_obj_t, o); nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); } // for 'a' mode, we must begin at the end of the file if ((mode & FA_OPEN_ALWAYS) != 0) { f_lseek(&o->fp, f_size(&o->fp)); } return o; }
u32 fileSize(const char *path){ FIL fp; u32 size = 0; if(f_open(&fp, path, FA_READ) == FR_OK) size = f_size(&fp); f_close(&fp); return size; }
off_t FATFileSystem::file_size(fs_file_t file) { FIL *fh = static_cast<FIL*>(file); lock(); off_t res = f_size(fh); unlock(); return res; }
_off_t _lseek(int fd, _off_t offset, int whence) { DWORD ofs = offset; FIL *fp = &fileEntries[fd]; if (whence == SEEK_CUR) ofs += f_tell(fp); else if (whence == SEEK_END) ofs = f_size(fp) - offset; errno = fferr2errno(f_lseek(fp, ofs)); return errno != 0 ? ((off_t) -1) : ((off_t) f_tell(fp)); }
FilePosition FileStore::Length() const { switch (usageMode) { case FileUseMode::free: INTERNAL_ERROR; return 0; case FileUseMode::readOnly: return f_size(&file); case FileUseMode::readWrite: return (writeBuffer != nullptr) ? f_size(&file) + writeBuffer->BytesStored() : f_size(&file); case FileUseMode::invalidated: default: return 0; } }
/* * SDカードのサンプル */ void sd_test() { FRESULT rc; // DIR dir; /* Directory object */ // FILINFO fno; /* File information object */ UINT bw, br, i; char tmp[64]; f_mount(0, &Fatfs); /* Register volume work area (never fails) */ /* * SDカードのMESSAGE.TXTを開いてI2C液晶に表示します。英数カナのみ * 2行分のみ */ rc = f_open(&Fil, "MESSAGE.TXT", FA_READ); if (!rc){ i2c_cmd(0x80); // xprintf("\nType the file content.\n"); for (;;) { rc = f_read(&Fil, buff, sizeof(buff), &br); /* Read a chunk of file */ if (rc || !br) break; /* Error or end of file */ for (i = 0; i < br; i++){ if(i==0x10) i2c_cmd(0xC0); i2c_data(buff[i]); } xprintf("%s\n", buff); } if (rc) die(rc); rc = f_close(&Fil); } /* * ファイル書き込みテスト * SD0001.TXTファイルを作成し、Strawberry Linuxの文字を永遠に書き込む */ rc = f_open(&Fil, "SD0001.TXT", FA_WRITE | FA_OPEN_ALWAYS); f_lseek(&Fil, f_size(&Fil)); if (rc) die(rc); i = 0; // 無限ループでこの関数からは抜けない while(i < 100){ sprintf(tmp, "Strawberry Linux %d\r\n", i); rc = f_write(&Fil, tmp, strlen(tmp), &bw); if (rc) die(rc); xprintf("%s\n", tmp); // SDカードに書き出します。 f_sync(&Fil); i++; } // return; f_mount(0, NULL); }
int logging_init_persistent() { int result; result = f_open(&log_file, "0:evrythng.log", FA_WRITE | FA_OPEN_ALWAYS); if (result != FR_OK) return result; result = f_lseek(&log_file, f_size(&log_file)); if (result != FR_OK) return result; persistent_initialized = true; return FR_OK; }
bool File::open_for_append(const std::string& file_path) { if( open(file_path) ) { const auto seek_result = f_lseek(&f, f_size(&f)); if( seek_result == FR_OK ) { return true; } else { close(); } } return false; }
//funzione che apre il file in modalità "append" FRESULT open_append (FIL* fp, const char* path) { FRESULT fr; /* Apro un file esistente, se non esiste ne creo uno nuovo. */ if (f_open(fp, path, FA_WRITE | FA_OPEN_ALWAYS) == FR_OK) { /* Scorro fino alla fine del file per accodare la scrittura */ fr = f_lseek(fp, f_size(fp)); if (fr != FR_OK) f_close(fp); } return fr; }
void f_dump(void) { int i, j, n; n = sizeof(fs.file) / sizeof(fs.file[0]); for (i = 0; i < n; i++) { printf("FILE %d: addr = %d, len = %d, size = %d\n", i + 1, \ f_addr(i), f_len(i), f_size(i)); f_read((file_id_t)(FILE1 + i), 0, BUF, f_len(i)); for (j = 0 ; j < f_len(i); j++) putchar(BUF[j]); printf("\n"); } }
static int fatfs_fstat(mount_point_t *point, file_t *file, struct stat *buf) { privinfo_t *priv = file->ctx; if (priv == NULL) { seterrno(EINVAL); return -1; } buf->st_dev = (dev_t)point->dev->devno; buf->st_ino = 0; buf->st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_IFREG; buf->st_nlink = 0; buf->st_uid = 0; buf->st_gid = 0; buf->st_rdev = (dev_t)point->dev->devno; buf->st_size = 0; buf->st_atime = 0; buf->st_spare1 = 0; buf->st_mtime = 0; buf->st_spare2 = 0; buf->st_ctime = 0; buf->st_spare3 = 0; buf->st_blksize = 0; buf->st_blocks = 0; buf->st_spare4[0] = 0; buf->st_spare4[1] = 0; buf->st_size = f_size(&priv->file); buf->st_ino = priv->file.sclust; #if _MAX_SS != 512 buf->st_blksize = priv->file.fs->ssize; #else buf->st_blksize = _MAX_SS; #endif buf->st_blocks = f_size(&priv->file) / buf->st_blksize; return 0; }