1 /** 2 * libf2fs.c 3 * 4 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * Dual licensed under the GPL or LGPL version 2 licenses. 8 */ 9 #define _LARGEFILE64_SOURCE 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <errno.h> 15 #include <unistd.h> 16 #include <fcntl.h> 17 #include <mntent.h> 18 #include <time.h> 19 #include <sys/stat.h> 20 #include <sys/mount.h> 21 #include <sys/ioctl.h> 22 #include <linux/hdreg.h> 23 24 #include <f2fs_fs.h> 25 26 struct f2fs_configuration config; 27 28 /* 29 * IO interfaces 30 */ 31 int dev_read_version(void *buf, __u64 offset, size_t len) 32 { 33 if (lseek64(config.kd, (off64_t)offset, SEEK_SET) < 0) 34 return -1; 35 if (read(config.kd, buf, len) < 0) 36 return -1; 37 return 0; 38 } 39 40 int dev_read(void *buf, __u64 offset, size_t len) 41 { 42 if (lseek64(config.fd, (off64_t)offset, SEEK_SET) < 0) 43 return -1; 44 if (read(config.fd, buf, len) < 0) 45 return -1; 46 return 0; 47 } 48 49 int dev_readahead(__u64 offset, size_t len) 50 { 51 #ifdef POSIX_FADV_WILLNEED 52 return posix_fadvise(config.fd, offset, len, POSIX_FADV_WILLNEED); 53 #else 54 return 0; 55 #endif 56 } 57 58 int dev_write(void *buf, __u64 offset, size_t len) 59 { 60 if (lseek64(config.fd, (off64_t)offset, SEEK_SET) < 0) 61 return -1; 62 if (write(config.fd, buf, len) < 0) 63 return -1; 64 return 0; 65 } 66 67 int dev_write_block(void *buf, __u64 blk_addr) 68 { 69 return dev_write(buf, blk_addr * F2FS_BLKSIZE, F2FS_BLKSIZE); 70 } 71 72 int dev_write_dump(void *buf, __u64 offset, size_t len) 73 { 74 if (lseek64(config.dump_fd, (off64_t)offset, SEEK_SET) < 0) 75 return -1; 76 if (write(config.dump_fd, buf, len) < 0) 77 return -1; 78 return 0; 79 } 80 81 int dev_fill(void *buf, __u64 offset, size_t len) 82 { 83 /* Only allow fill to zero */ 84 if (*((__u8*)buf)) 85 return -1; 86 if (lseek64(config.fd, (off64_t)offset, SEEK_SET) < 0) 87 return -1; 88 if (write(config.fd, buf, len) < 0) 89 return -1; 90 return 0; 91 } 92 93 int dev_read_block(void *buf, __u64 blk_addr) 94 { 95 return dev_read(buf, blk_addr * F2FS_BLKSIZE, F2FS_BLKSIZE); 96 } 97 98 int dev_read_blocks(void *buf, __u64 addr, __u32 nr_blks) 99 { 100 return dev_read(buf, addr * F2FS_BLKSIZE, nr_blks * F2FS_BLKSIZE); 101 } 102 103 int dev_reada_block(__u64 blk_addr) 104 { 105 return dev_readahead(blk_addr * F2FS_BLKSIZE, F2FS_BLKSIZE); 106 } 107 108 void f2fs_finalize_device(struct f2fs_configuration *c) 109 { 110 /* 111 * We should call fsync() to flush out all the dirty pages 112 * in the block device page cache. 113 */ 114 if (fsync(c->fd) < 0) 115 MSG(0, "\tError: Could not conduct fsync!!!\n"); 116 117 if (close(c->fd) < 0) 118 MSG(0, "\tError: Failed to close device file!!!\n"); 119 120 close(c->kd); 121 } 122