119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * fileio.c --- Simple file I/O routines 33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1997 Theodore Ts'o. 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 78558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library 88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2. 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_UNISTD_H 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_fs.h" 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs.h" 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct ext2_file { 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t magic; 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs; 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino; 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags; 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u64 pos; 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blockno; 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t physblock; 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf; 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define BMAP_BUFFER (file->buf + fs->blocksize) 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino, 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode *inode, 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags, ext2_file_t *ret) 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_file_t file; 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Don't let caller create or open a file for writing if the 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * filesystem is read-only. 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((flags & (EXT2_FILE_WRITE | EXT2_FILE_CREATE)) && 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(fs->flags & EXT2_FLAG_RW)) 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_RO_FILSYS; 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_mem(sizeof(struct ext2_file), &file); 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(file, 0, sizeof(struct ext2_file)); 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->magic = EXT2_ET_MAGIC_EXT2_FILE; 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->fs = fs; 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->ino = ino; 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->flags = flags & EXT2_FILE_MASK; 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode) { 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memcpy(&file->inode, inode, sizeof(struct ext2_inode)); 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_read_inode(fs, ino, &file->inode); 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto fail; 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_array(3, fs->blocksize, &file->buf); 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto fail; 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *ret = file; 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectfail: 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file->buf) 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&file->buf); 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&file); 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino, 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags, ext2_file_t *ret) 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ext2fs_file_open2(fs, ino, NULL, flags, ret); 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function returns the filesystem handle of a file from the structure 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectext2_filsys ext2fs_file_get_fs(ext2_file_t file) 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file->magic != EXT2_ET_MAGIC_EXT2_FILE) 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return file->fs; 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function flushes the dirty block buffer out to disk if 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * necessary. 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_flush(ext2_file_t file) 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs; 1063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs = file->fs; 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(file->flags & EXT2_FILE_BUF_VALID) || 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(file->flags & EXT2_FILE_BUF_DIRTY)) 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * OK, the physical block hasn't been allocated yet. 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Allocate it. 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!file->physblock) { 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_bmap(fs, file->ino, &file->inode, 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0, 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->blockno, &file->physblock); 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = io_channel_write_blk(fs->io, file->physblock, 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1, file->buf); 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->flags &= ~EXT2_FILE_BUF_DIRTY; 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function synchronizes the file's block buffer and the current 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * file position, possibly invalidating block buffer if necessary 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t sync_buffer_position(ext2_file_t file) 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t b; 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project b = file->pos / file->fs->blocksize; 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (b != file->blockno) { 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_file_flush(file); 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->flags &= ~EXT2_FILE_BUF_VALID; 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->blockno = b; 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function loads the file's block buffer with valid data from 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the disk as necessary. 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If dontfill is true, then skip initializing the buffer since we're 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * going to be replacing its entire contents anyway. If set, then the 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * function basically only sets file->physblock and EXT2_FILE_BUF_VALID 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define DONTFILL 1 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t load_buffer(ext2_file_t file, int dontfill) 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = file->fs; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(file->flags & EXT2_FILE_BUF_VALID)) { 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_bmap(fs, file->ino, &file->inode, 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project BMAP_BUFFER, 0, file->blockno, 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &file->physblock); 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!dontfill) { 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file->physblock) { 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = io_channel_read_blk(fs->io, 1793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt file->physblock, 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1, file->buf); 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(file->buf, 0, fs->blocksize); 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->flags |= EXT2_FILE_BUF_VALID; 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_close(ext2_file_t file) 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 1953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_file_flush(file); 1993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file->buf) 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&file->buf); 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&file); 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_read(ext2_file_t file, void *buf, 20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int wanted, unsigned int *got) 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs; 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval = 0; 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int start, c, count = 0; 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u64 left; 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *ptr = (char *) buf; 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs = file->fs; 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while ((file->pos < EXT2_I_SIZE(&file->inode)) && (wanted > 0)) { 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = sync_buffer_position(file); 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto fail; 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = load_buffer(file, 0); 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto fail; 22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project start = file->pos % fs->blocksize; 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = fs->blocksize - start; 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (c > wanted) 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = wanted; 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project left = EXT2_I_SIZE(&file->inode) - file->pos ; 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (c > left) 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = left; 2353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memcpy(ptr, file->buf+start, c); 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->pos += c; 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ptr += c; 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project count += c; 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project wanted -= c; 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectfail: 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got) 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *got = count; 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_write(ext2_file_t file, const void *buf, 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int nbytes, unsigned int *written) 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs; 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval = 0; 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int start, c, count = 0; 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const char *ptr = (const char *) buf; 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs = file->fs; 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(file->flags & EXT2_FILE_WRITE)) 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_FILE_RO; 26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (nbytes > 0) { 26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = sync_buffer_position(file); 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto fail; 2683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project start = file->pos % fs->blocksize; 27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = fs->blocksize - start; 27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (c > nbytes) 27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = nbytes; 27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * We only need to do a read-modify-update cycle if 27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * we're doing a partial write. 27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = load_buffer(file, (c == fs->blocksize)); 27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto fail; 28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->flags |= EXT2_FILE_BUF_DIRTY; 28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memcpy(file->buf+start, ptr, c); 28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->pos += c; 28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ptr += c; 28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project count += c; 28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nbytes -= c; 28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectfail: 29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (written) 29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *written = count; 29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset, 29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int whence, __u64 *ret_pos) 29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); 30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (whence == EXT2_SEEK_SET) 30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->pos = offset; 30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (whence == EXT2_SEEK_CUR) 30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->pos += offset; 30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (whence == EXT2_SEEK_END) 30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->pos = EXT2_I_SIZE(&file->inode) + offset; 30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_INVALID_ARGUMENT; 30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ret_pos) 31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *ret_pos = file->pos; 31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset, 31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int whence, ext2_off_t *ret_pos) 31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u64 loffset, ret_loffset; 32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 3213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project loffset = offset; 32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_file_llseek(file, loffset, whence, &ret_loffset); 32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ret_pos) 32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *ret_pos = (ext2_off_t) ret_loffset; 32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function returns the size of the file, according to the inode 33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size) 33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file->magic != EXT2_ET_MAGIC_EXT2_FILE) 33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_MAGIC_EXT2_FILE; 33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *ret_size = EXT2_I_SIZE(&file->inode); 33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function returns the size of the file, according to the inode 34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectext2_off_t ext2fs_file_get_size(ext2_file_t file) 34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u64 size; 34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_file_get_lsize(file, &size)) 34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((size >> 32) != 0) 35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return size; 35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function sets the size of the file, truncating it if necessary 3573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * XXX still need to call truncate 35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size) 36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); 3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->inode.i_size = size; 36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file->inode.i_size_high = 0; 36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file->ino) { 36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_write_inode(file->fs, file->ino, &file->inode); 36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * XXX truncate inode if necessary 37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 379