1 /**
2 * f2fs_format_utils.c
3 *
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * Dual licensed under the GPL or LGPL version 2 licenses.
8 */
9 #define _LARGEFILE_SOURCE
10 #define _LARGEFILE64_SOURCE
11 #ifndef _GNU_SOURCE
12 #define _GNU_SOURCE
13 #endif
14
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <sys/ioctl.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20
21 #include "f2fs_fs.h"
22
23 #ifdef HAVE_LINUX_FS_H
24 #include <linux/fs.h>
25 #endif
26 #ifdef HAVE_LINUX_FALLOC_H
27 #include <linux/falloc.h>
28 #endif
29
30 #ifndef BLKDISCARD
31 #define BLKDISCARD _IO(0x12,119)
32 #endif
33 #ifndef BLKSECDISCARD
34 #define BLKSECDISCARD _IO(0x12,125)
35 #endif
36
trim_device(int i)37 static int trim_device(int i)
38 {
39 unsigned long long range[2];
40 struct stat stat_buf;
41 struct device_info *dev = c.devices + i;
42 u_int64_t bytes = dev->total_sectors * dev->sector_size;
43 int fd = dev->fd;
44
45 if (fstat(fd, &stat_buf) < 0 ) {
46 MSG(1, "\tError: Failed to get the device stat!!!\n");
47 return -1;
48 }
49
50 range[0] = 0;
51 range[1] = bytes;
52
53 #if defined(WITH_BLKDISCARD) && defined(BLKDISCARD)
54 MSG(0, "Info: [%s] Discarding device\n", dev->path);
55 if (S_ISREG(stat_buf.st_mode)) {
56 #if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE)
57 if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
58 range[0], range[1]) < 0) {
59 MSG(0, "Info: fallocate(PUNCH_HOLE|KEEP_SIZE) is failed\n");
60 }
61 #endif
62 return 0;
63 } else if (S_ISBLK(stat_buf.st_mode)) {
64 if (dev->zoned_model != F2FS_ZONED_NONE)
65 return f2fs_reset_zones(i);
66 #ifdef BLKSECDISCARD
67 if (ioctl(fd, BLKSECDISCARD, &range) < 0) {
68 MSG(0, "Info: This device doesn't support BLKSECDISCARD\n");
69 } else {
70 MSG(0, "Info: Secure Discarded %lu MB\n",
71 stat_buf.st_size >> 20);
72 return 0;
73 }
74 #endif
75 if (ioctl(fd, BLKDISCARD, &range) < 0) {
76 MSG(0, "Info: This device doesn't support BLKDISCARD\n");
77 } else {
78 MSG(0, "Info: Discarded %llu MB\n", range[1] >> 20);
79 }
80 } else
81 return -1;
82 #endif
83 return 0;
84 }
85
f2fs_trim_devices(void)86 int f2fs_trim_devices(void)
87 {
88 int i;
89
90 for (i = 0; i < c.ndevs; i++)
91 if (trim_device(i))
92 return -1;
93 c.trimmed = 1;
94 return 0;
95 }
96