read.c revision 0cb61411eadd92b7202e045c1c9ec8df7fb636fe
1f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle/* 2f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Copyright (C) 2010 The Android Open Source Project 3f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 4f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Licensed under the Apache License, Version 2.0 (the "License"); 5f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * you may not use this file except in compliance with the License. 6f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * You may obtain a copy of the License at 7f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 8f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * http://www.apache.org/licenses/LICENSE-2.0 9f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 10f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Unless required by applicable law or agreed to in writing, software 11f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * distributed under the License is distributed on an "AS IS" BASIS, 12f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * See the License for the specific language governing permissions and 14f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * limitations under the License. 15f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle */ 16f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 17f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <assert.h> 18f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <errno.h> 19f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <fcntl.h> 20f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <string.h> 21f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <unistd.h> 22f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <sys/stat.h> 23f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 240cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle#include "fatblock.h" 25f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fs.h" 26f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "utils.h" 27f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 280cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttlestatic int buffer_read(char *buf, offset_t buf_len, char *out, 290cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle offset_t off, offset_t len) 300cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle{ 31f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(buf); 32f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(out); 33f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 34f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (off >= buf_len) { 35f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(out, 0, len); 36f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 37f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 38f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 39f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (off + len > buf_len) { 40f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(out + (buf_len - off), 0, len - (buf_len - off)); 41f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle len = buf_len - off; 42f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 43f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 44f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(off < buf_len); 45f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(off + len <= buf_len); 46f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 47f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(out, buf + off, len); 48f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 49f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 50f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 51f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 520cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttlestatic int file_check_metadata(struct file *f) 530cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle{ 54f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct stat st; 55f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int ret; 56f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 57f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(f); 58f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 59f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = stat(f->path, &st); 60f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret) { 610cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("checking metadata of %s: stat failed: %s\n", 620cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle f->path, strerror(errno)); 63f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 64f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 65f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 66f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (f->mtime != st.st_mtime) 67f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 68f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 69f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 70f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 71f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 720cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttlestatic int file_read(struct file *f, char *buf, offset_t off, offset_t len) 730cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle{ 74f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int fd; 75f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle off_t sought; 76f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ssize_t ret; 77f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 78f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(f); 79f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(buf); 80f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 81f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (off >= UINT32_MAX) { 820cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("reading %s (%llu, %llu): " 830cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle "ignoring read that starts past 2^32\n", 840cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle f->path, off, len); 85f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 86f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 87f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 88f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (off + len > UINT32_MAX) { 890cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("reading %s (%llu, %llu): " 900cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle "truncating read that ends past 2^32\n", 910cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle f->path, off, len); 92f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle len = UINT32_MAX - off; 93f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 94f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 95f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (file_check_metadata(f)) { 960cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("reading %s (%llu, %llu): metadata has changed\n", 970cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle f->path, off, len); 98f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return SKY_IS_FALLING; 99f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 100f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 101f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fd = fdpool_open(&f->pfd, f->path, O_RDONLY); 102f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (fd < 0) { 103f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("reading %s: open failed: %s\n", f->path, strerror(errno)); 104f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 105f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 106f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 107f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sought = lseek(fd, (off_t)len, SEEK_SET); 108f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (sought != (off_t)len) { 1090cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("reading %s (%llu, %llu): seek failed: %s\n", 1100cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle f->path, off, len, strerror(errno)); 111f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 112f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 113f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 114f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = read(fd, buf, (size_t)len); 115f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret != (ssize_t)len) { 1160cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("reading %s (%llu, %llu): read failed: %s\n", 1170cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle f->path, off, len, strerror(errno)); 118f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 119f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 120f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 121f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* leave fd open; fdpool will close it if needed. */ 122f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 123f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 124f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 125f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 1260cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttlestatic int dir_read(struct dir *d, char *buf, offset_t off, offset_t len) 1270cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle{ 128f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(d); 129f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(buf); 130f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 131f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return buffer_read((char*)d->entries, d->size, buf, off, len); 132f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 133f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 1340cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttlestatic int extent_read(struct fs *fs, struct extent *e, char *buf, 1350cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle offset_t off, offset_t len) 1360cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle{ 137f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 138f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(e); 139f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(buf); 140f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 141f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle switch (e->type) { 142f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case EXTENT_TYPE_BOOT: 1430cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle return buffer_read((char*)&fs->boot, sizeof(fs->boot), buf, 1440cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle off, len); 145f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case EXTENT_TYPE_INFO: 1460cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle return buffer_read((char*)&fs->info, sizeof(fs->info), buf, 1470cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle off, len); 148f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case EXTENT_TYPE_FAT: 1490cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle return buffer_read((char*)fs->fat, fs->fat_size, buf, 1500cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle off, len); 151f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case EXTENT_TYPE_FILE: 152f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return file_read((struct file *)e, buf, off, len); 153f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case EXTENT_TYPE_DIR: 154f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return dir_read((struct dir *)e, buf, off, len); 155f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle default: 156f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("reading extent: unexpected type %d\n", e->type); 157f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 158f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 159f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 160f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 1610cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttleint fs_read(struct fs *fs, char *buf, offset_t start, offset_t len) 1620cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle{ 163f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct extent *e = NULL; 164f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t e_start, r_start, rel_len; 165f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int ret; 166f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 167f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(buf, 0, len); 168f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 1690cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle while ((e = fs_find_extent(fs, start, len, e, 1700cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle &r_start, &e_start, &rel_len))) { 171f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = extent_read(fs, e, buf + r_start, e_start, rel_len); 172f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret == SKY_IS_FALLING) 173f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return SKY_IS_FALLING; 174f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret) 175f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return ret; 176f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 177f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 178f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 179f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 180