int ext2_truncate(inode_t *inode, off_t off) { __u32 size = off; ext2_fs_instance_t *instance = (ext2_fs_instance_t*)inode->i_instance; struct ext2_inode *einode = read_inode(instance, inode->i_ino); if (einode) { __u32 n_blk; if (size > 0) { n_blk = (size - 1) / (1024 << instance->superblock.s_log_block_size) + 1; } else { n_blk = 1; } __u32 addr = get_data_block (instance,einode, n_blk);; if (addr) { while (addr) { if (off <= 0) { free_block(instance, addr / (1024 << instance->superblock.s_log_block_size)); } else { off -= 1024 << instance->superblock.s_log_block_size; } n_blk++; addr = get_data_block (instance,einode, n_blk); } } else { while (off > 0) { set_block_inode_data(instance, einode, n_blk, alloc_block(instance)); n_blk++; off -= 1024 << instance->superblock.s_log_block_size; } } einode->i_size = size; write_inode(instance, inode->i_ino, einode); ext2inode_2_inode(inode, inode->i_instance, inode->i_ino, einode); return 0; } return -ENOENT; }
int ext2_truncate(inode_t *inode, off_t off) { uint32_t size = off; ext2_fs_instance_t *instance = (ext2_fs_instance_t*)inode->i_instance; struct ext2_inode *einode = read_inode(instance, inode->i_ino); if (einode) { // TODO vérifier le bon fonctionnement. int n_blk; if (size > 0) { n_blk = (size - 1) / (1024 << instance->superblock.s_log_block_size) + 1; } else { n_blk = 1; } int addr = addr_inode_data2(instance, einode, n_blk); if (addr) { // 1er cas : off est plus petit que la taille du fichier. while (addr) { if (off <= 0) { free_block(instance, addr / (1024 << instance->superblock.s_log_block_size)); } else { off -= 1024 << instance->superblock.s_log_block_size; } n_blk++; addr = addr_inode_data2(instance, einode, n_blk); } } else { // 2er cas : off est plus grand. while (off > 0) { set_block_inode_data(instance, einode, n_blk, alloc_block(instance)); n_blk++; off -= 1024 << instance->superblock.s_log_block_size; } } einode->i_size = size; write_inode(instance, inode->i_ino, einode); ext2inode_2_inode(inode, inode->i_instance, inode->i_ino, einode); return 0; } return -ENOENT; }
int ext2_write(open_file_descriptor * ofd, const void *buf, size_t size) { if ((ofd->flags & O_ACCMODE) == O_RDONLY) { return 0; } int inode = ofd->inode->i_ino; if (inode >= 0) { ext2_fs_instance_t *instance = (ext2_fs_instance_t*) ofd->fs_instance; struct ext2_inode *einode = read_inode(instance, inode); if (einode != NULL) { unsigned int offset; if (ofd->flags & O_APPEND) { offset = einode->i_size; } else { offset = ofd->current_octet; } int count = 0; __u32 n_blk = 0; int off = offset; while (off >= (1024 << instance->superblock.s_log_block_size)) { if (get_data_block (instance,einode, n_blk) == 0) { int addr = alloc_block(instance); set_block_inode_data(instance, einode, n_blk, addr); } off -= 1024 << instance->superblock.s_log_block_size; n_blk++; } while (size > 0) { __u32 addr = get_data_block (instance,einode, n_blk); if (addr == 0) { addr = alloc_block(instance); set_block_inode_data(instance, einode, n_blk, addr); addr *= (1024 << instance->superblock.s_log_block_size); } addr += off; size_t size2 = (1024 << instance->superblock.s_log_block_size) - off; off = 0; if (size2 > size) { size2 = size; } instance->write_data(instance->super.device, ((char*)buf) + count, size2, addr); size -= size2; count += size2; n_blk++; } einode->i_size = max(einode->i_size, offset + count); // struct timeval tv; // gettimeofday(&tv, NULL); // einode.i_mtime = tv.tv_sec; write_inode(instance, inode, einode); return count; } else { return -ENOENT; } return size; } else { return inode; } }