1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#define _LARGEFILE64_SOURCE 30 31#include <asm/types.h> 32#include <errno.h> 33#include <linux/fs.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <string.h> /* memset() */ 37#include <sys/param.h> 38#include <sys/stat.h> 39#include <sys/types.h> 40#include <fcntl.h> 41#include <dlfcn.h> 42 43#include <assert.h> 44 45#include <f2fs_fs.h> 46#include <f2fs_format_utils.h> 47 48#include <sparse/sparse.h> 49 50struct selabel_handle; 51 52#include "make_f2fs.h" 53 54#ifdef USE_MINGW 55 56#include <winsock2.h> 57 58/* These match the Linux definitions of these flags. 59 L_xx is defined to avoid conflicting with the win32 versions. 60*/ 61#define L_S_IRUSR 00400 62#define L_S_IWUSR 00200 63#define L_S_IXUSR 00100 64#define S_IRWXU (L_S_IRUSR | L_S_IWUSR | L_S_IXUSR) 65#define S_IRGRP 00040 66#define S_IWGRP 00020 67#define S_IXGRP 00010 68#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) 69#define S_IROTH 00004 70#define S_IWOTH 00002 71#define S_IXOTH 00001 72#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) 73#define S_ISUID 0004000 74#define S_ISGID 0002000 75#define S_ISVTX 0001000 76 77#else 78 79#include <selinux/selinux.h> 80#include <selinux/label.h> 81 82#define O_BINARY 0 83 84#endif 85 86struct f2fs_configuration config; 87struct sparse_file *f2fs_sparse_file; 88 89struct buf_item { 90 void *buf; 91 size_t len; 92 struct buf_item *next; 93}; 94 95struct buf_item *buf_list; 96 97static int dev_write_fd(void *buf, __u64 offset, size_t len) 98{ 99 if (lseek64(config.fd, (off64_t)offset, SEEK_SET) < 0) 100 return -1; 101 if (write(config.fd, buf, len) != len) 102 return -1; 103 return 0; 104} 105 106void flush_sparse_buffs() 107{ 108 while (buf_list) { 109 struct buf_item *bi = buf_list; 110 buf_list = buf_list->next; 111 free(bi->buf); 112 free(bi); 113 } 114} 115 116static int dev_write_sparse(void *buf, __u64 byte_offset, size_t byte_len) 117{ 118 struct buf_item *bi = calloc(1, sizeof(struct buf_item)); 119 120 if (bi == NULL) { 121 return -ENOMEM; 122 } 123 bi->buf = malloc(byte_len); 124 if (bi->buf == NULL) { 125 free(bi); 126 return -ENOMEM; 127 } 128 129 bi->len = byte_len; 130 memcpy(bi->buf, buf, byte_len); 131 bi->next = buf_list; 132 buf_list = bi; 133 134 sparse_file_add_data(f2fs_sparse_file, bi->buf, byte_len, byte_offset/F2FS_BLKSIZE); 135 return 0; 136} 137 138void f2fs_finalize_device(struct f2fs_configuration *c) 139{ 140} 141 142int f2fs_trim_device() 143{ 144 return 0; 145} 146 147/* 148 * IO interfaces 149 */ 150int dev_read_version(void *buf, __u64 offset, size_t len) 151{ 152 return 0; 153} 154 155int dev_read(void *buf, __u64 offset, size_t len) 156{ 157 return 0; 158} 159 160int dev_write(void *buf, __u64 offset, size_t len) 161{ 162 if (config.fd >= 0) { 163 return dev_write_fd(buf, offset, len); 164 } else { 165 return dev_write_sparse(buf, offset, len); 166 } 167} 168 169 170int dev_fill(void *buf, __u64 offset, size_t len) 171{ 172 int ret; 173 if (config.fd >= 0) { 174 return dev_write_fd(buf, offset, len); 175 } 176 // sparse file fills with zero by default. 177 // return sparse_file_add_fill(f2fs_sparse_file, ((__u8*)(bi->buf))[0], byte_len, byte_offset/F2FS_BLKSIZE); 178 return 0; 179} 180 181int dev_read_block(void *buf, __u64 blk_addr) 182{ 183 assert(false); // Must not be invoked. 184 return 0; 185} 186 187int dev_read_blocks(void *buf, __u64 addr, __u32 nr_blks) 188{ 189 assert(false); // Must not be invoked. 190 return 0; 191} 192 193