1437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall/**
2437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall * f2fs_format_utils.c
3437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall *
4437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall *             http://www.samsung.com/
6437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall *
7e35b8afb34822ccc0835b453c7a3417bc0825569Jaegeuk Kim * Dual licensed under the GPL or LGPL version 2 licenses.
8437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall */
99a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#define _LARGEFILE_SOURCE
10437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall#define _LARGEFILE64_SOURCE
119a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#ifndef _GNU_SOURCE
129a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#define _GNU_SOURCE
139a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#endif
14437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall
15437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall#include <stdio.h>
16437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall#include <unistd.h>
174f267323a28c3fb50fa08256517e2dae4e347b2dJaegeuk Kim#include <sys/ioctl.h>
18437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall#include <sys/stat.h>
199a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#include <fcntl.h>
20437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall
21437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall#include "f2fs_fs.h"
22437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall
2392a65a44e5637b1f86f5d6e10cb058b6aa21db41Sankalp Bose#ifdef HAVE_LINUX_FS_H
2492a65a44e5637b1f86f5d6e10cb058b6aa21db41Sankalp Bose#include <linux/fs.h>
2592a65a44e5637b1f86f5d6e10cb058b6aa21db41Sankalp Bose#endif
269a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#ifdef HAVE_LINUX_FALLOC_H
279a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#include <linux/falloc.h>
289a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#endif
2992a65a44e5637b1f86f5d6e10cb058b6aa21db41Sankalp Bose
307b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#ifndef BLKDISCARD
317b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#define BLKDISCARD	_IO(0x12,119)
327b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#endif
337b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#ifndef BLKSECDISCARD
347b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#define BLKSECDISCARD	_IO(0x12,125)
357b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#endif
367b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim
37de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kimstatic int trim_device(int i)
38437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall{
39437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall	unsigned long long range[2];
40437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall	struct stat stat_buf;
41de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	struct device_info *dev = c.devices + i;
42de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	u_int64_t bytes = dev->total_sectors * dev->sector_size;
43de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	int fd = dev->fd;
44437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall
45932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim	if (fstat(fd, &stat_buf) < 0 ) {
46437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall		MSG(1, "\tError: Failed to get the device stat!!!\n");
47437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall		return -1;
48437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall	}
49437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall
50932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim	range[0] = 0;
516e7c503a8048b700b4d252e41db2d4dd144ae3c8Jaegeuk Kim	range[1] = bytes;
52932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim
5392a65a44e5637b1f86f5d6e10cb058b6aa21db41Sankalp Bose#if defined(WITH_BLKDISCARD) && defined(BLKDISCARD)
54de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	MSG(0, "Info: [%s] Discarding device\n", dev->path);
559a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee	if (S_ISREG(stat_buf.st_mode)) {
563c160e7d111c4a9fcd54f30b944b6a260fb77998Gustavo Zacarias#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE)
57932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim		if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
589a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee				range[0], range[1]) < 0) {
599a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee			MSG(0, "Info: fallocate(PUNCH_HOLE|KEEP_SIZE) is failed\n");
609a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee		}
619a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee#endif
62437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall		return 0;
639a5808cfb7e49bf640a10767d13e16579e8cda30Changman Lee	} else if (S_ISBLK(stat_buf.st_mode)) {
64de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim		if (dev->zoned_model != F2FS_ZONED_NONE)
65de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim			return f2fs_reset_zones(i);
667b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#ifdef BLKSECDISCARD
67932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim		if (ioctl(fd, BLKSECDISCARD, &range) < 0) {
687b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim			MSG(0, "Info: This device doesn't support BLKSECDISCARD\n");
697b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim		} else {
70932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim			MSG(0, "Info: Secure Discarded %lu MB\n",
71932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim						stat_buf.st_size >> 20);
727b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim			return 0;
737b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim		}
747b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim#endif
75932d596a86f35b1e52110570e1b0c6e7f031cb6fJaegeuk Kim		if (ioctl(fd, BLKDISCARD, &range) < 0) {
767b9c5fcdf11f0e8e080bac0f7c2f3218e00bd88bJaegeuk Kim			MSG(0, "Info: This device doesn't support BLKDISCARD\n");
7709f8f56066efd3a9fadb4c731f7184980383f9f9Jaegeuk Kim		} else {
786e7c503a8048b700b4d252e41db2d4dd144ae3c8Jaegeuk Kim			MSG(0, "Info: Discarded %llu MB\n", range[1] >> 20);
7909f8f56066efd3a9fadb4c731f7184980383f9f9Jaegeuk Kim		}
80437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall	} else
81437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall		return -1;
82a68ee58a5d1485be637bcc4e4fbddc5da727fc62JP Abgrall#endif
83437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall	return 0;
84437dbf67730d2765c4dfc8539b07258e1ca3966fJP Abgrall}
85de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim
86de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kimint f2fs_trim_devices(void)
87de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim{
88de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	int i;
89de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim
90de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	for (i = 0; i < c.ndevs; i++)
91de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim		if (trim_device(i))
92de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim			return -1;
93f070415c0bededac9ca300e4cac1560bbbd9d44fJaegeuk Kim	c.trimmed = 1;
94de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim	return 0;
95de7e07e011004a0264e27d7134ee32cbcd9695ecJaegeuk Kim}
96