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 50 struct 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 #include <selinux/android.h> 82 83 #define O_BINARY 0 84 85 #endif 86 87 struct f2fs_configuration config; 88 struct sparse_file *f2fs_sparse_file; 89 90 struct buf_item { 91 void *buf; 92 size_t len; 93 struct buf_item *next; 94 }; 95 96 struct buf_item *buf_list; 97 98 static int dev_write_fd(void *buf, __u64 offset, size_t len) 99 { 100 if (lseek64(config.fd, (off64_t)offset, SEEK_SET) < 0) 101 return -1; 102 if (write(config.fd, buf, len) != len) 103 return -1; 104 return 0; 105 } 106 107 void flush_sparse_buffs() 108 { 109 while (buf_list) { 110 struct buf_item *bi = buf_list; 111 buf_list = buf_list->next; 112 free(bi->buf); 113 free(bi); 114 } 115 } 116 117 static int dev_write_sparse(void *buf, __u64 byte_offset, size_t byte_len) 118 { 119 struct buf_item *bi = calloc(1, sizeof(struct buf_item)); 120 121 if (bi == NULL) { 122 return -ENOMEM; 123 } 124 bi->buf = malloc(byte_len); 125 if (bi->buf == NULL) { 126 free(bi); 127 return -ENOMEM; 128 } 129 130 bi->len = byte_len; 131 memcpy(bi->buf, buf, byte_len); 132 bi->next = buf_list; 133 buf_list = bi; 134 135 sparse_file_add_data(f2fs_sparse_file, bi->buf, byte_len, byte_offset/F2FS_BLKSIZE); 136 return 0; 137 } 138 139 void f2fs_finalize_device(struct f2fs_configuration *c) 140 { 141 } 142 143 int f2fs_trim_device() 144 { 145 return 0; 146 } 147 148 /* 149 * IO interfaces 150 */ 151 int dev_read(void *buf, __u64 offset, size_t len) 152 { 153 return 0; 154 } 155 156 int dev_write(void *buf, __u64 offset, size_t len) 157 { 158 if (config.fd >= 0) { 159 return dev_write_fd(buf, offset, len); 160 } else { 161 return dev_write_sparse(buf, offset, len); 162 } 163 } 164 165 166 int dev_fill(void *buf, __u64 offset, size_t len) 167 { 168 int ret; 169 if (config.fd >= 0) { 170 return dev_write_fd(buf, offset, len); 171 } 172 // sparse file fills with zero by default. 173 // return sparse_file_add_fill(f2fs_sparse_file, ((__u8*)(bi->buf))[0], byte_len, byte_offset/F2FS_BLKSIZE); 174 return 0; 175 } 176 177 int dev_read_block(void *buf, __u64 blk_addr) 178 { 179 assert(false); // Must not be invoked. 180 return 0; 181 } 182 183 int dev_read_blocks(void *buf, __u64 addr, __u32 nr_blks) 184 { 185 assert(false); // Must not be invoked. 186 return 0; 187 } 188 189