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 <assert.h> 32#include <asm/types.h> 33#include <dlfcn.h> 34#include <errno.h> 35#include <fcntl.h> 36#include <linux/fs.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> /* memset() */ 40#include <sys/param.h> 41#include <sys/stat.h> 42#include <sys/types.h> 43#include <unistd.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 _WIN32 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 ssize_t written = write(config.fd, buf, len); 102 if (written == -1) 103 return -1; 104 if ((size_t)written != len) 105 return -1; 106 return 0; 107} 108 109void flush_sparse_buffs() 110{ 111 while (buf_list) { 112 struct buf_item *bi = buf_list; 113 buf_list = buf_list->next; 114 free(bi->buf); 115 free(bi); 116 } 117} 118 119static int dev_write_sparse(void *buf, __u64 byte_offset, size_t byte_len) 120{ 121 struct buf_item *bi = calloc(1, sizeof(struct buf_item)); 122 123 if (bi == NULL) { 124 return -ENOMEM; 125 } 126 bi->buf = malloc(byte_len); 127 if (bi->buf == NULL) { 128 free(bi); 129 return -ENOMEM; 130 } 131 132 bi->len = byte_len; 133 memcpy(bi->buf, buf, byte_len); 134 bi->next = buf_list; 135 buf_list = bi; 136 137 sparse_file_add_data(f2fs_sparse_file, bi->buf, byte_len, byte_offset/F2FS_BLKSIZE); 138 return 0; 139} 140 141void f2fs_finalize_device(struct f2fs_configuration *c) 142{ 143} 144 145int f2fs_trim_device() 146{ 147 return 0; 148} 149 150/* 151 * IO interfaces 152 */ 153int dev_read_version(void *buf, __u64 offset, size_t len) 154{ 155 return 0; 156} 157 158int dev_read(void *buf, __u64 offset, size_t len) 159{ 160 return 0; 161} 162 163int dev_write(void *buf, __u64 offset, size_t len) 164{ 165 if (config.fd >= 0) { 166 return dev_write_fd(buf, offset, len); 167 } else { 168 return dev_write_sparse(buf, offset, len); 169 } 170} 171 172 173int dev_fill(void *buf, __u64 offset, size_t len) 174{ 175 int ret; 176 if (config.fd >= 0) { 177 return dev_write_fd(buf, offset, len); 178 } 179 // sparse file fills with zero by default. 180 // return sparse_file_add_fill(f2fs_sparse_file, ((__u8*)(bi->buf))[0], byte_len, byte_offset/F2FS_BLKSIZE); 181 return 0; 182} 183 184int dev_read_block(void *buf, __u64 blk_addr) 185{ 186 assert(false); // Must not be invoked. 187 return 0; 188} 189 190int dev_read_blocks(void *buf, __u64 addr, __u32 nr_blks) 191{ 192 assert(false); // Must not be invoked. 193 return 0; 194} 195 196