xref: /aosp_15_r20/external/f2fs-tools/lib/libf2fs_zoned.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker /**
2*59bfda1fSAndroid Build Coastguard Worker  * libf2fs_zoned.c
3*59bfda1fSAndroid Build Coastguard Worker  *
4*59bfda1fSAndroid Build Coastguard Worker  * Copyright (c) 2016 Western Digital Corporation.
5*59bfda1fSAndroid Build Coastguard Worker  * Written by: Damien Le Moal <[email protected]>
6*59bfda1fSAndroid Build Coastguard Worker  *
7*59bfda1fSAndroid Build Coastguard Worker  * Dual licensed under the GPL or LGPL version 2 licenses.
8*59bfda1fSAndroid Build Coastguard Worker  */
9*59bfda1fSAndroid Build Coastguard Worker 
10*59bfda1fSAndroid Build Coastguard Worker #include <f2fs_fs.h>
11*59bfda1fSAndroid Build Coastguard Worker #include <stdio.h>
12*59bfda1fSAndroid Build Coastguard Worker #include <stdlib.h>
13*59bfda1fSAndroid Build Coastguard Worker #include <string.h>
14*59bfda1fSAndroid Build Coastguard Worker #include <errno.h>
15*59bfda1fSAndroid Build Coastguard Worker #include <unistd.h>
16*59bfda1fSAndroid Build Coastguard Worker #include <fcntl.h>
17*59bfda1fSAndroid Build Coastguard Worker #include <sys/stat.h>
18*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SYS_SYSMACROS_H
19*59bfda1fSAndroid Build Coastguard Worker #include <sys/sysmacros.h>
20*59bfda1fSAndroid Build Coastguard Worker #endif
21*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_LIMITS_H
22*59bfda1fSAndroid Build Coastguard Worker #include <linux/limits.h>
23*59bfda1fSAndroid Build Coastguard Worker #endif
24*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_SYS_IOCTL_H
25*59bfda1fSAndroid Build Coastguard Worker #include <sys/ioctl.h>
26*59bfda1fSAndroid Build Coastguard Worker #endif
27*59bfda1fSAndroid Build Coastguard Worker #include <libgen.h>
28*59bfda1fSAndroid Build Coastguard Worker 
29*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_BLKZONED_H
30*59bfda1fSAndroid Build Coastguard Worker #ifndef BLKFINISHZONE
31*59bfda1fSAndroid Build Coastguard Worker #define BLKFINISHZONE   _IOW(0x12, 136, struct blk_zone_range)
32*59bfda1fSAndroid Build Coastguard Worker #endif
33*59bfda1fSAndroid Build Coastguard Worker 
get_sysfs_path(struct device_info * dev,const char * attr,char * buf,size_t buflen)34*59bfda1fSAndroid Build Coastguard Worker int get_sysfs_path(struct device_info *dev, const char *attr,
35*59bfda1fSAndroid Build Coastguard Worker 		   char *buf, size_t buflen)
36*59bfda1fSAndroid Build Coastguard Worker {
37*59bfda1fSAndroid Build Coastguard Worker 	struct stat statbuf;
38*59bfda1fSAndroid Build Coastguard Worker 	char str[PATH_MAX];
39*59bfda1fSAndroid Build Coastguard Worker 	char sysfs_path[PATH_MAX];
40*59bfda1fSAndroid Build Coastguard Worker 	ssize_t len;
41*59bfda1fSAndroid Build Coastguard Worker 	char *delim;
42*59bfda1fSAndroid Build Coastguard Worker 	int ret;
43*59bfda1fSAndroid Build Coastguard Worker 
44*59bfda1fSAndroid Build Coastguard Worker 	if (stat(dev->path, &statbuf) < 0)
45*59bfda1fSAndroid Build Coastguard Worker 		return -1;
46*59bfda1fSAndroid Build Coastguard Worker 
47*59bfda1fSAndroid Build Coastguard Worker 	snprintf(str, sizeof(str), "/sys/dev/block/%d:%d",
48*59bfda1fSAndroid Build Coastguard Worker 		 major(statbuf.st_rdev), minor(statbuf.st_rdev));
49*59bfda1fSAndroid Build Coastguard Worker 	len = readlink(str, buf, buflen - 1);
50*59bfda1fSAndroid Build Coastguard Worker 	if (len < 0)
51*59bfda1fSAndroid Build Coastguard Worker 		return -1;
52*59bfda1fSAndroid Build Coastguard Worker 	buf[len] = '\0';
53*59bfda1fSAndroid Build Coastguard Worker 
54*59bfda1fSAndroid Build Coastguard Worker 	ret = snprintf(sysfs_path, sizeof(sysfs_path),
55*59bfda1fSAndroid Build Coastguard Worker 		       "/sys/dev/block/%s", buf);
56*59bfda1fSAndroid Build Coastguard Worker 	if (ret >= sizeof(sysfs_path))
57*59bfda1fSAndroid Build Coastguard Worker 		return -1;
58*59bfda1fSAndroid Build Coastguard Worker 
59*59bfda1fSAndroid Build Coastguard Worker 	/* Test if the device is a partition */
60*59bfda1fSAndroid Build Coastguard Worker 	ret = snprintf(str, sizeof(str), "%s/partition", sysfs_path);
61*59bfda1fSAndroid Build Coastguard Worker 	if (ret >= sizeof(str))
62*59bfda1fSAndroid Build Coastguard Worker 		return -1;
63*59bfda1fSAndroid Build Coastguard Worker 	ret = stat(str, &statbuf);
64*59bfda1fSAndroid Build Coastguard Worker 	if (ret) {
65*59bfda1fSAndroid Build Coastguard Worker 		if (errno == ENOENT) {
66*59bfda1fSAndroid Build Coastguard Worker 			/* Not a partition */
67*59bfda1fSAndroid Build Coastguard Worker 			goto out;
68*59bfda1fSAndroid Build Coastguard Worker 		}
69*59bfda1fSAndroid Build Coastguard Worker 		return -1;
70*59bfda1fSAndroid Build Coastguard Worker 	}
71*59bfda1fSAndroid Build Coastguard Worker 
72*59bfda1fSAndroid Build Coastguard Worker 	/*
73*59bfda1fSAndroid Build Coastguard Worker 	 * The device is a partition: remove the device name from the
74*59bfda1fSAndroid Build Coastguard Worker 	 * attribute file path to obtain the sysfs path of the holder device.
75*59bfda1fSAndroid Build Coastguard Worker 	 *   e.g.:  /sys/dev/block/.../sda/sda1 -> /sys/dev/block/.../sda
76*59bfda1fSAndroid Build Coastguard Worker 	 */
77*59bfda1fSAndroid Build Coastguard Worker 	delim = strrchr(sysfs_path, '/');
78*59bfda1fSAndroid Build Coastguard Worker 	if (!delim)
79*59bfda1fSAndroid Build Coastguard Worker 		return -1;
80*59bfda1fSAndroid Build Coastguard Worker 	*delim = '\0';
81*59bfda1fSAndroid Build Coastguard Worker 
82*59bfda1fSAndroid Build Coastguard Worker out:
83*59bfda1fSAndroid Build Coastguard Worker 	ret = snprintf(buf, buflen, "%s/%s", sysfs_path, attr);
84*59bfda1fSAndroid Build Coastguard Worker 	if (ret >= buflen)
85*59bfda1fSAndroid Build Coastguard Worker 		return -1;
86*59bfda1fSAndroid Build Coastguard Worker 
87*59bfda1fSAndroid Build Coastguard Worker 	return 0;
88*59bfda1fSAndroid Build Coastguard Worker }
89*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_zoned_model(int i)90*59bfda1fSAndroid Build Coastguard Worker int f2fs_get_zoned_model(int i)
91*59bfda1fSAndroid Build Coastguard Worker {
92*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + i;
93*59bfda1fSAndroid Build Coastguard Worker 	char str[PATH_MAX];
94*59bfda1fSAndroid Build Coastguard Worker 	FILE *file;
95*59bfda1fSAndroid Build Coastguard Worker 	int res;
96*59bfda1fSAndroid Build Coastguard Worker 
97*59bfda1fSAndroid Build Coastguard Worker 	/* Check that this is a zoned block device */
98*59bfda1fSAndroid Build Coastguard Worker 	res = get_sysfs_path(dev, "queue/zoned", str, sizeof(str));
99*59bfda1fSAndroid Build Coastguard Worker 	if (res != 0) {
100*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\tInfo: can't find /sys, assuming normal block device\n");
101*59bfda1fSAndroid Build Coastguard Worker 		dev->zoned_model = F2FS_ZONED_NONE;
102*59bfda1fSAndroid Build Coastguard Worker 		return 0;
103*59bfda1fSAndroid Build Coastguard Worker 	}
104*59bfda1fSAndroid Build Coastguard Worker 
105*59bfda1fSAndroid Build Coastguard Worker 	file = fopen(str, "r");
106*59bfda1fSAndroid Build Coastguard Worker 	if (!file) {
107*59bfda1fSAndroid Build Coastguard Worker 		/*
108*59bfda1fSAndroid Build Coastguard Worker 		 * The kernel does not support zoned block devices, but we have
109*59bfda1fSAndroid Build Coastguard Worker 		 * a block device file. This means that if the zoned file is
110*59bfda1fSAndroid Build Coastguard Worker 		 * not found, then the device is not zoned or is zoned but can
111*59bfda1fSAndroid Build Coastguard Worker 		 * be randomly written (i.e. host-aware zoned model).
112*59bfda1fSAndroid Build Coastguard Worker 		 * Treat the device as a regular block device. Otherwise, signal
113*59bfda1fSAndroid Build Coastguard Worker 		 * the failure to verify the disk zone model.
114*59bfda1fSAndroid Build Coastguard Worker 		 */
115*59bfda1fSAndroid Build Coastguard Worker 		if (errno == ENOENT) {
116*59bfda1fSAndroid Build Coastguard Worker 			dev->zoned_model = F2FS_ZONED_NONE;
117*59bfda1fSAndroid Build Coastguard Worker 			return 0;
118*59bfda1fSAndroid Build Coastguard Worker 		}
119*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\tError: Failed to check the device zoned model\n");
120*59bfda1fSAndroid Build Coastguard Worker 		return -1;
121*59bfda1fSAndroid Build Coastguard Worker 	}
122*59bfda1fSAndroid Build Coastguard Worker 
123*59bfda1fSAndroid Build Coastguard Worker 	memset(str, 0, sizeof(str));
124*59bfda1fSAndroid Build Coastguard Worker 	res = fscanf(file, "%s", str);
125*59bfda1fSAndroid Build Coastguard Worker 	fclose(file);
126*59bfda1fSAndroid Build Coastguard Worker 
127*59bfda1fSAndroid Build Coastguard Worker 	if (res != 1) {
128*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\tError: Failed to parse the device zoned model\n");
129*59bfda1fSAndroid Build Coastguard Worker 		return -1;
130*59bfda1fSAndroid Build Coastguard Worker 	}
131*59bfda1fSAndroid Build Coastguard Worker 
132*59bfda1fSAndroid Build Coastguard Worker 	if (strcmp(str, "none") == 0) {
133*59bfda1fSAndroid Build Coastguard Worker 		/* Regular block device */
134*59bfda1fSAndroid Build Coastguard Worker 		dev->zoned_model = F2FS_ZONED_NONE;
135*59bfda1fSAndroid Build Coastguard Worker 	} else if (strcmp(str, "host-aware") == 0) {
136*59bfda1fSAndroid Build Coastguard Worker 		/* Host-aware zoned block device: can be randomly written */
137*59bfda1fSAndroid Build Coastguard Worker 		dev->zoned_model = F2FS_ZONED_HA;
138*59bfda1fSAndroid Build Coastguard Worker 	} else if (strcmp(str, "host-managed") == 0) {
139*59bfda1fSAndroid Build Coastguard Worker 		/* Host-managed zoned block device: sequential writes needed */
140*59bfda1fSAndroid Build Coastguard Worker 		dev->zoned_model = F2FS_ZONED_HM;
141*59bfda1fSAndroid Build Coastguard Worker 	} else {
142*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\tError: Unsupported device zoned model\n");
143*59bfda1fSAndroid Build Coastguard Worker 		return -1;
144*59bfda1fSAndroid Build Coastguard Worker 	}
145*59bfda1fSAndroid Build Coastguard Worker 
146*59bfda1fSAndroid Build Coastguard Worker 	return 0;
147*59bfda1fSAndroid Build Coastguard Worker }
148*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_zone_chunk_sectors(struct device_info * dev)149*59bfda1fSAndroid Build Coastguard Worker uint32_t f2fs_get_zone_chunk_sectors(struct device_info *dev)
150*59bfda1fSAndroid Build Coastguard Worker {
151*59bfda1fSAndroid Build Coastguard Worker 	uint32_t sectors;
152*59bfda1fSAndroid Build Coastguard Worker 	char str[PATH_MAX];
153*59bfda1fSAndroid Build Coastguard Worker 	FILE *file;
154*59bfda1fSAndroid Build Coastguard Worker 	int res;
155*59bfda1fSAndroid Build Coastguard Worker 
156*59bfda1fSAndroid Build Coastguard Worker 	res = get_sysfs_path(dev, "queue/chunk_sectors", str, sizeof(str));
157*59bfda1fSAndroid Build Coastguard Worker 	if (res != 0) {
158*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\tError: Failed to get device sysfs attribute path\n");
159*59bfda1fSAndroid Build Coastguard Worker 		return 0;
160*59bfda1fSAndroid Build Coastguard Worker 	}
161*59bfda1fSAndroid Build Coastguard Worker 
162*59bfda1fSAndroid Build Coastguard Worker 	file = fopen(str, "r");
163*59bfda1fSAndroid Build Coastguard Worker 	if (!file)
164*59bfda1fSAndroid Build Coastguard Worker 		return 0;
165*59bfda1fSAndroid Build Coastguard Worker 
166*59bfda1fSAndroid Build Coastguard Worker 	memset(str, 0, sizeof(str));
167*59bfda1fSAndroid Build Coastguard Worker 	res = fscanf(file, "%s", str);
168*59bfda1fSAndroid Build Coastguard Worker 	fclose(file);
169*59bfda1fSAndroid Build Coastguard Worker 
170*59bfda1fSAndroid Build Coastguard Worker 	if (res != 1)
171*59bfda1fSAndroid Build Coastguard Worker 		return 0;
172*59bfda1fSAndroid Build Coastguard Worker 
173*59bfda1fSAndroid Build Coastguard Worker 	sectors = atoi(str);
174*59bfda1fSAndroid Build Coastguard Worker 
175*59bfda1fSAndroid Build Coastguard Worker 	return sectors;
176*59bfda1fSAndroid Build Coastguard Worker }
177*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_zone_blocks(int i)178*59bfda1fSAndroid Build Coastguard Worker int f2fs_get_zone_blocks(int i)
179*59bfda1fSAndroid Build Coastguard Worker {
180*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + i;
181*59bfda1fSAndroid Build Coastguard Worker 	uint64_t sectors;
182*59bfda1fSAndroid Build Coastguard Worker 
183*59bfda1fSAndroid Build Coastguard Worker 	/* Get zone size */
184*59bfda1fSAndroid Build Coastguard Worker 	dev->zone_blocks = 0;
185*59bfda1fSAndroid Build Coastguard Worker 
186*59bfda1fSAndroid Build Coastguard Worker 	sectors = f2fs_get_zone_chunk_sectors(dev);
187*59bfda1fSAndroid Build Coastguard Worker 	if (!sectors)
188*59bfda1fSAndroid Build Coastguard Worker 		return -1;
189*59bfda1fSAndroid Build Coastguard Worker 
190*59bfda1fSAndroid Build Coastguard Worker 	dev->zone_size = sectors << SECTOR_SHIFT;
191*59bfda1fSAndroid Build Coastguard Worker 	dev->zone_blocks = sectors >> (F2FS_BLKSIZE_BITS - SECTOR_SHIFT);
192*59bfda1fSAndroid Build Coastguard Worker 	sectors = dev->zone_size / c.sector_size;
193*59bfda1fSAndroid Build Coastguard Worker 
194*59bfda1fSAndroid Build Coastguard Worker 	/*
195*59bfda1fSAndroid Build Coastguard Worker 	 * Total number of zones: there may
196*59bfda1fSAndroid Build Coastguard Worker 	 * be a last smaller runt zone.
197*59bfda1fSAndroid Build Coastguard Worker 	 */
198*59bfda1fSAndroid Build Coastguard Worker 	dev->nr_zones = dev->total_sectors / sectors;
199*59bfda1fSAndroid Build Coastguard Worker 	if (dev->total_sectors % sectors)
200*59bfda1fSAndroid Build Coastguard Worker 		dev->nr_zones++;
201*59bfda1fSAndroid Build Coastguard Worker 
202*59bfda1fSAndroid Build Coastguard Worker 	return 0;
203*59bfda1fSAndroid Build Coastguard Worker }
204*59bfda1fSAndroid Build Coastguard Worker 
f2fs_report_zone(int i,uint64_t sector,struct blk_zone * blkzone)205*59bfda1fSAndroid Build Coastguard Worker int f2fs_report_zone(int i, uint64_t sector, struct blk_zone *blkzone)
206*59bfda1fSAndroid Build Coastguard Worker {
207*59bfda1fSAndroid Build Coastguard Worker 	struct one_zone_report {
208*59bfda1fSAndroid Build Coastguard Worker 		struct blk_zone_report	rep;
209*59bfda1fSAndroid Build Coastguard Worker 		struct blk_zone		zone;
210*59bfda1fSAndroid Build Coastguard Worker 	} *rep;
211*59bfda1fSAndroid Build Coastguard Worker 	int ret = -1;
212*59bfda1fSAndroid Build Coastguard Worker 
213*59bfda1fSAndroid Build Coastguard Worker 	static_assert(sizeof(*rep) == sizeof(rep->rep) + sizeof(rep->zone), "");
214*59bfda1fSAndroid Build Coastguard Worker 
215*59bfda1fSAndroid Build Coastguard Worker 	rep = calloc(1, sizeof(*rep));
216*59bfda1fSAndroid Build Coastguard Worker 	if (!rep) {
217*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("No memory for report zones\n");
218*59bfda1fSAndroid Build Coastguard Worker 		return -ENOMEM;
219*59bfda1fSAndroid Build Coastguard Worker 	}
220*59bfda1fSAndroid Build Coastguard Worker 
221*59bfda1fSAndroid Build Coastguard Worker 	rep->rep = (struct blk_zone_report){
222*59bfda1fSAndroid Build Coastguard Worker 		.sector = sector,
223*59bfda1fSAndroid Build Coastguard Worker 		.nr_zones = 1,
224*59bfda1fSAndroid Build Coastguard Worker 	};
225*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(c.devices[i].fd, BLKREPORTZONE, rep);
226*59bfda1fSAndroid Build Coastguard Worker 	if (ret != 0) {
227*59bfda1fSAndroid Build Coastguard Worker 		ret = -errno;
228*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("ioctl BLKREPORTZONE failed: errno=%d\n", errno);
229*59bfda1fSAndroid Build Coastguard Worker 		goto out;
230*59bfda1fSAndroid Build Coastguard Worker 	}
231*59bfda1fSAndroid Build Coastguard Worker 
232*59bfda1fSAndroid Build Coastguard Worker 	*blkzone = rep->zone;
233*59bfda1fSAndroid Build Coastguard Worker out:
234*59bfda1fSAndroid Build Coastguard Worker 	free(rep);
235*59bfda1fSAndroid Build Coastguard Worker 	return ret;
236*59bfda1fSAndroid Build Coastguard Worker }
237*59bfda1fSAndroid Build Coastguard Worker 
238*59bfda1fSAndroid Build Coastguard Worker #define F2FS_REPORT_ZONES_BUFSZ	524288
239*59bfda1fSAndroid Build Coastguard Worker 
f2fs_report_zones(int j,report_zones_cb_t * report_zones_cb,void * opaque)240*59bfda1fSAndroid Build Coastguard Worker int f2fs_report_zones(int j, report_zones_cb_t *report_zones_cb, void *opaque)
241*59bfda1fSAndroid Build Coastguard Worker {
242*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + j;
243*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone_report *rep;
244*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone *blkz;
245*59bfda1fSAndroid Build Coastguard Worker 	unsigned int i, n = 0;
246*59bfda1fSAndroid Build Coastguard Worker 	uint64_t total_sectors = (dev->total_sectors * c.sector_size)
247*59bfda1fSAndroid Build Coastguard Worker 		>> SECTOR_SHIFT;
248*59bfda1fSAndroid Build Coastguard Worker 	uint64_t sector = 0;
249*59bfda1fSAndroid Build Coastguard Worker 	int ret = -1;
250*59bfda1fSAndroid Build Coastguard Worker 
251*59bfda1fSAndroid Build Coastguard Worker 	rep = malloc(F2FS_REPORT_ZONES_BUFSZ);
252*59bfda1fSAndroid Build Coastguard Worker 	if (!rep) {
253*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("No memory for report zones\n");
254*59bfda1fSAndroid Build Coastguard Worker 		return -ENOMEM;
255*59bfda1fSAndroid Build Coastguard Worker 	}
256*59bfda1fSAndroid Build Coastguard Worker 
257*59bfda1fSAndroid Build Coastguard Worker 	while (sector < total_sectors) {
258*59bfda1fSAndroid Build Coastguard Worker 
259*59bfda1fSAndroid Build Coastguard Worker 		/* Get zone info */
260*59bfda1fSAndroid Build Coastguard Worker 		rep->sector = sector;
261*59bfda1fSAndroid Build Coastguard Worker 		rep->nr_zones = (F2FS_REPORT_ZONES_BUFSZ - sizeof(struct blk_zone_report))
262*59bfda1fSAndroid Build Coastguard Worker 			/ sizeof(struct blk_zone);
263*59bfda1fSAndroid Build Coastguard Worker 
264*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(dev->fd, BLKREPORTZONE, rep);
265*59bfda1fSAndroid Build Coastguard Worker 		if (ret != 0) {
266*59bfda1fSAndroid Build Coastguard Worker 			ret = -errno;
267*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("ioctl BLKREPORTZONE failed: errno=%d\n",
268*59bfda1fSAndroid Build Coastguard Worker 				errno);
269*59bfda1fSAndroid Build Coastguard Worker 			goto out;
270*59bfda1fSAndroid Build Coastguard Worker 		}
271*59bfda1fSAndroid Build Coastguard Worker 
272*59bfda1fSAndroid Build Coastguard Worker 		if (!rep->nr_zones) {
273*59bfda1fSAndroid Build Coastguard Worker 			ret = -EIO;
274*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("Unexpected ioctl BLKREPORTZONE result\n");
275*59bfda1fSAndroid Build Coastguard Worker 			goto out;
276*59bfda1fSAndroid Build Coastguard Worker 		}
277*59bfda1fSAndroid Build Coastguard Worker 
278*59bfda1fSAndroid Build Coastguard Worker 		blkz = (struct blk_zone *)(rep + 1);
279*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < rep->nr_zones; i++) {
280*59bfda1fSAndroid Build Coastguard Worker 			ret = report_zones_cb(n, blkz, opaque);
281*59bfda1fSAndroid Build Coastguard Worker 			if (ret)
282*59bfda1fSAndroid Build Coastguard Worker 				goto out;
283*59bfda1fSAndroid Build Coastguard Worker 			sector = blk_zone_sector(blkz) + blk_zone_length(blkz);
284*59bfda1fSAndroid Build Coastguard Worker 			n++;
285*59bfda1fSAndroid Build Coastguard Worker 			blkz++;
286*59bfda1fSAndroid Build Coastguard Worker 		}
287*59bfda1fSAndroid Build Coastguard Worker 	}
288*59bfda1fSAndroid Build Coastguard Worker out:
289*59bfda1fSAndroid Build Coastguard Worker 	free(rep);
290*59bfda1fSAndroid Build Coastguard Worker 	return ret;
291*59bfda1fSAndroid Build Coastguard Worker }
292*59bfda1fSAndroid Build Coastguard Worker 
f2fs_check_zones(int j)293*59bfda1fSAndroid Build Coastguard Worker int f2fs_check_zones(int j)
294*59bfda1fSAndroid Build Coastguard Worker {
295*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + j;
296*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone_report *rep;
297*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone *blkz;
298*59bfda1fSAndroid Build Coastguard Worker 	unsigned int i, n = 0;
299*59bfda1fSAndroid Build Coastguard Worker 	uint64_t total_sectors;
300*59bfda1fSAndroid Build Coastguard Worker 	uint64_t sector;
301*59bfda1fSAndroid Build Coastguard Worker 	int last_is_conv = 1;
302*59bfda1fSAndroid Build Coastguard Worker 	int ret = -1;
303*59bfda1fSAndroid Build Coastguard Worker 
304*59bfda1fSAndroid Build Coastguard Worker 	rep = malloc(F2FS_REPORT_ZONES_BUFSZ);
305*59bfda1fSAndroid Build Coastguard Worker 	if (!rep) {
306*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("No memory for report zones\n");
307*59bfda1fSAndroid Build Coastguard Worker 		return -ENOMEM;
308*59bfda1fSAndroid Build Coastguard Worker 	}
309*59bfda1fSAndroid Build Coastguard Worker 
310*59bfda1fSAndroid Build Coastguard Worker 	dev->zone_cap_blocks = malloc(dev->nr_zones * sizeof(size_t));
311*59bfda1fSAndroid Build Coastguard Worker 	if (!dev->zone_cap_blocks) {
312*59bfda1fSAndroid Build Coastguard Worker 		free(rep);
313*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("No memory for zone capacity list.\n");
314*59bfda1fSAndroid Build Coastguard Worker 		return -ENOMEM;
315*59bfda1fSAndroid Build Coastguard Worker 	}
316*59bfda1fSAndroid Build Coastguard Worker 	memset(dev->zone_cap_blocks, 0, (dev->nr_zones * sizeof(size_t)));
317*59bfda1fSAndroid Build Coastguard Worker 
318*59bfda1fSAndroid Build Coastguard Worker 	dev->nr_rnd_zones = 0;
319*59bfda1fSAndroid Build Coastguard Worker 	sector = 0;
320*59bfda1fSAndroid Build Coastguard Worker 	total_sectors = (dev->total_sectors * c.sector_size) >> 9;
321*59bfda1fSAndroid Build Coastguard Worker 
322*59bfda1fSAndroid Build Coastguard Worker 	while (sector < total_sectors) {
323*59bfda1fSAndroid Build Coastguard Worker 
324*59bfda1fSAndroid Build Coastguard Worker 		/* Get zone info */
325*59bfda1fSAndroid Build Coastguard Worker 		memset(rep, 0, F2FS_REPORT_ZONES_BUFSZ);
326*59bfda1fSAndroid Build Coastguard Worker 		rep->sector = sector;
327*59bfda1fSAndroid Build Coastguard Worker 		rep->nr_zones = (F2FS_REPORT_ZONES_BUFSZ - sizeof(struct blk_zone_report))
328*59bfda1fSAndroid Build Coastguard Worker 			/ sizeof(struct blk_zone);
329*59bfda1fSAndroid Build Coastguard Worker 
330*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(dev->fd, BLKREPORTZONE, rep);
331*59bfda1fSAndroid Build Coastguard Worker 		if (ret != 0) {
332*59bfda1fSAndroid Build Coastguard Worker 			ret = -errno;
333*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("ioctl BLKREPORTZONE failed\n");
334*59bfda1fSAndroid Build Coastguard Worker 			goto out;
335*59bfda1fSAndroid Build Coastguard Worker 		}
336*59bfda1fSAndroid Build Coastguard Worker 
337*59bfda1fSAndroid Build Coastguard Worker 		if (!rep->nr_zones)
338*59bfda1fSAndroid Build Coastguard Worker 			break;
339*59bfda1fSAndroid Build Coastguard Worker 
340*59bfda1fSAndroid Build Coastguard Worker 		blkz = (struct blk_zone *)(rep + 1);
341*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < rep->nr_zones && sector < total_sectors; i++) {
342*59bfda1fSAndroid Build Coastguard Worker 
343*59bfda1fSAndroid Build Coastguard Worker 			if (blk_zone_cond(blkz) == BLK_ZONE_COND_READONLY ||
344*59bfda1fSAndroid Build Coastguard Worker 			    blk_zone_cond(blkz) == BLK_ZONE_COND_OFFLINE)
345*59bfda1fSAndroid Build Coastguard Worker 				last_is_conv = 0;
346*59bfda1fSAndroid Build Coastguard Worker 			if (blk_zone_conv(blkz) ||
347*59bfda1fSAndroid Build Coastguard Worker 			    blk_zone_seq_pref(blkz)) {
348*59bfda1fSAndroid Build Coastguard Worker 				if (last_is_conv)
349*59bfda1fSAndroid Build Coastguard Worker 					dev->nr_rnd_zones++;
350*59bfda1fSAndroid Build Coastguard Worker 			} else {
351*59bfda1fSAndroid Build Coastguard Worker 				last_is_conv = 0;
352*59bfda1fSAndroid Build Coastguard Worker 			}
353*59bfda1fSAndroid Build Coastguard Worker 
354*59bfda1fSAndroid Build Coastguard Worker 			if (blk_zone_conv(blkz)) {
355*59bfda1fSAndroid Build Coastguard Worker 				DBG(2,
356*59bfda1fSAndroid Build Coastguard Worker 				    "Zone %05u: Conventional, cond 0x%x (%s), sector %llu, %llu sectors\n",
357*59bfda1fSAndroid Build Coastguard Worker 				    n,
358*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_cond(blkz),
359*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_cond_str(blkz),
360*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_sector(blkz),
361*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_length(blkz));
362*59bfda1fSAndroid Build Coastguard Worker 				dev->zone_cap_blocks[n] =
363*59bfda1fSAndroid Build Coastguard Worker 					blk_zone_length(blkz) >>
364*59bfda1fSAndroid Build Coastguard Worker 					(F2FS_BLKSIZE_BITS - SECTOR_SHIFT);
365*59bfda1fSAndroid Build Coastguard Worker 			} else {
366*59bfda1fSAndroid Build Coastguard Worker 				DBG(2,
367*59bfda1fSAndroid Build Coastguard Worker 				    "Zone %05u: type 0x%x (%s), cond 0x%x (%s),"
368*59bfda1fSAndroid Build Coastguard Worker 				    " need_reset %d, non_seq %d, sector %llu,"
369*59bfda1fSAndroid Build Coastguard Worker 				    " %llu sectors, capacity %llu,"
370*59bfda1fSAndroid Build Coastguard Worker 				    " wp sector %llu\n",
371*59bfda1fSAndroid Build Coastguard Worker 				    n,
372*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_type(blkz),
373*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_type_str(blkz),
374*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_cond(blkz),
375*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_cond_str(blkz),
376*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_need_reset(blkz),
377*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_non_seq(blkz),
378*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_sector(blkz),
379*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_length(blkz),
380*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_capacity(blkz, rep->flags),
381*59bfda1fSAndroid Build Coastguard Worker 				    blk_zone_wp_sector(blkz));
382*59bfda1fSAndroid Build Coastguard Worker 				dev->zone_cap_blocks[n] =
383*59bfda1fSAndroid Build Coastguard Worker 					blk_zone_capacity(blkz, rep->flags) >>
384*59bfda1fSAndroid Build Coastguard Worker 					(F2FS_BLKSIZE_BITS - SECTOR_SHIFT);
385*59bfda1fSAndroid Build Coastguard Worker 			}
386*59bfda1fSAndroid Build Coastguard Worker 
387*59bfda1fSAndroid Build Coastguard Worker 			sector = blk_zone_sector(blkz) + blk_zone_length(blkz);
388*59bfda1fSAndroid Build Coastguard Worker 			n++;
389*59bfda1fSAndroid Build Coastguard Worker 			blkz++;
390*59bfda1fSAndroid Build Coastguard Worker 		}
391*59bfda1fSAndroid Build Coastguard Worker 	}
392*59bfda1fSAndroid Build Coastguard Worker 
393*59bfda1fSAndroid Build Coastguard Worker 	if (sector != total_sectors) {
394*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("Invalid zones: last sector reported is %llu, expected %llu\n",
395*59bfda1fSAndroid Build Coastguard Worker 			(unsigned long long)(sector << 9) / c.sector_size,
396*59bfda1fSAndroid Build Coastguard Worker 			(unsigned long long)dev->total_sectors);
397*59bfda1fSAndroid Build Coastguard Worker 		ret = -1;
398*59bfda1fSAndroid Build Coastguard Worker 		goto out;
399*59bfda1fSAndroid Build Coastguard Worker 	}
400*59bfda1fSAndroid Build Coastguard Worker 
401*59bfda1fSAndroid Build Coastguard Worker 	if (n != dev->nr_zones) {
402*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("Inconsistent number of zones: expected %u zones, got %u\n",
403*59bfda1fSAndroid Build Coastguard Worker 			dev->nr_zones, n);
404*59bfda1fSAndroid Build Coastguard Worker 		ret = -1;
405*59bfda1fSAndroid Build Coastguard Worker 		goto out;
406*59bfda1fSAndroid Build Coastguard Worker 	}
407*59bfda1fSAndroid Build Coastguard Worker 
408*59bfda1fSAndroid Build Coastguard Worker 	/*
409*59bfda1fSAndroid Build Coastguard Worker 	 * For a multi-device volume, fixed position metadata blocks are
410*59bfda1fSAndroid Build Coastguard Worker 	 * stored * only on the first device of the volume. Checking for the
411*59bfda1fSAndroid Build Coastguard Worker 	 * presence of * conventional zones (randomly writeabl zones) for
412*59bfda1fSAndroid Build Coastguard Worker 	 * storing these blocks * on a host-managed device is thus needed only
413*59bfda1fSAndroid Build Coastguard Worker 	 * for the device index 0.
414*59bfda1fSAndroid Build Coastguard Worker 	 */
415*59bfda1fSAndroid Build Coastguard Worker 	if (j == 0 && dev->zoned_model == F2FS_ZONED_HM &&
416*59bfda1fSAndroid Build Coastguard Worker 			!dev->nr_rnd_zones) {
417*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("No conventional zone for super block\n");
418*59bfda1fSAndroid Build Coastguard Worker 		ret = -1;
419*59bfda1fSAndroid Build Coastguard Worker 	}
420*59bfda1fSAndroid Build Coastguard Worker out:
421*59bfda1fSAndroid Build Coastguard Worker 	free(rep);
422*59bfda1fSAndroid Build Coastguard Worker 	return ret;
423*59bfda1fSAndroid Build Coastguard Worker }
424*59bfda1fSAndroid Build Coastguard Worker 
f2fs_reset_zone(int i,void * blkzone)425*59bfda1fSAndroid Build Coastguard Worker int f2fs_reset_zone(int i, void *blkzone)
426*59bfda1fSAndroid Build Coastguard Worker {
427*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone *blkz = (struct blk_zone *)blkzone;
428*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + i;
429*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone_range range;
430*59bfda1fSAndroid Build Coastguard Worker 	int ret;
431*59bfda1fSAndroid Build Coastguard Worker 
432*59bfda1fSAndroid Build Coastguard Worker 	if (!blk_zone_seq(blkz) || blk_zone_empty(blkz))
433*59bfda1fSAndroid Build Coastguard Worker 		return 0;
434*59bfda1fSAndroid Build Coastguard Worker 
435*59bfda1fSAndroid Build Coastguard Worker 	/* Non empty sequential zone: reset */
436*59bfda1fSAndroid Build Coastguard Worker 	range.sector = blk_zone_sector(blkz);
437*59bfda1fSAndroid Build Coastguard Worker 	range.nr_sectors = blk_zone_length(blkz);
438*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(dev->fd, BLKRESETZONE, &range);
439*59bfda1fSAndroid Build Coastguard Worker 	if (ret != 0) {
440*59bfda1fSAndroid Build Coastguard Worker 		ret = -errno;
441*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("ioctl BLKRESETZONE failed: errno=%d\n", errno);
442*59bfda1fSAndroid Build Coastguard Worker 	}
443*59bfda1fSAndroid Build Coastguard Worker 
444*59bfda1fSAndroid Build Coastguard Worker 	return ret;
445*59bfda1fSAndroid Build Coastguard Worker }
446*59bfda1fSAndroid Build Coastguard Worker 
f2fs_reset_zones(int j)447*59bfda1fSAndroid Build Coastguard Worker int f2fs_reset_zones(int j)
448*59bfda1fSAndroid Build Coastguard Worker {
449*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + j;
450*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone_report *rep;
451*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone *blkz;
452*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone_range range;
453*59bfda1fSAndroid Build Coastguard Worker 	uint64_t total_sectors;
454*59bfda1fSAndroid Build Coastguard Worker 	uint64_t sector;
455*59bfda1fSAndroid Build Coastguard Worker 	unsigned int i;
456*59bfda1fSAndroid Build Coastguard Worker 	int ret = -1;
457*59bfda1fSAndroid Build Coastguard Worker 
458*59bfda1fSAndroid Build Coastguard Worker 	rep = malloc(F2FS_REPORT_ZONES_BUFSZ);
459*59bfda1fSAndroid Build Coastguard Worker 	if (!rep) {
460*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("No memory for report zones\n");
461*59bfda1fSAndroid Build Coastguard Worker 		return -1;
462*59bfda1fSAndroid Build Coastguard Worker 	}
463*59bfda1fSAndroid Build Coastguard Worker 
464*59bfda1fSAndroid Build Coastguard Worker 	sector = 0;
465*59bfda1fSAndroid Build Coastguard Worker 	total_sectors = (dev->total_sectors * c.sector_size) >> 9;
466*59bfda1fSAndroid Build Coastguard Worker 	while (sector < total_sectors) {
467*59bfda1fSAndroid Build Coastguard Worker 
468*59bfda1fSAndroid Build Coastguard Worker 		/* Get zone info */
469*59bfda1fSAndroid Build Coastguard Worker 		memset(rep, 0, F2FS_REPORT_ZONES_BUFSZ);
470*59bfda1fSAndroid Build Coastguard Worker 		rep->sector = sector;
471*59bfda1fSAndroid Build Coastguard Worker 		rep->nr_zones = (F2FS_REPORT_ZONES_BUFSZ - sizeof(struct blk_zone_report))
472*59bfda1fSAndroid Build Coastguard Worker 			/ sizeof(struct blk_zone);
473*59bfda1fSAndroid Build Coastguard Worker 
474*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(dev->fd, BLKREPORTZONE, rep);
475*59bfda1fSAndroid Build Coastguard Worker 		if (ret != 0) {
476*59bfda1fSAndroid Build Coastguard Worker 			ret = -errno;
477*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("ioctl BLKREPORTZONES failed\n");
478*59bfda1fSAndroid Build Coastguard Worker 			goto out;
479*59bfda1fSAndroid Build Coastguard Worker 		}
480*59bfda1fSAndroid Build Coastguard Worker 
481*59bfda1fSAndroid Build Coastguard Worker 		if (!rep->nr_zones)
482*59bfda1fSAndroid Build Coastguard Worker 			break;
483*59bfda1fSAndroid Build Coastguard Worker 
484*59bfda1fSAndroid Build Coastguard Worker 		blkz = (struct blk_zone *)(rep + 1);
485*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < rep->nr_zones && sector < total_sectors; i++) {
486*59bfda1fSAndroid Build Coastguard Worker 			if (blk_zone_seq(blkz) &&
487*59bfda1fSAndroid Build Coastguard Worker 			    !blk_zone_empty(blkz)) {
488*59bfda1fSAndroid Build Coastguard Worker 				/* Non empty sequential zone: reset */
489*59bfda1fSAndroid Build Coastguard Worker 				range.sector = blk_zone_sector(blkz);
490*59bfda1fSAndroid Build Coastguard Worker 				range.nr_sectors = blk_zone_length(blkz);
491*59bfda1fSAndroid Build Coastguard Worker 				ret = ioctl(dev->fd, BLKRESETZONE, &range);
492*59bfda1fSAndroid Build Coastguard Worker 				if (ret != 0) {
493*59bfda1fSAndroid Build Coastguard Worker 					ret = -errno;
494*59bfda1fSAndroid Build Coastguard Worker 					ERR_MSG("ioctl BLKRESETZONE failed\n");
495*59bfda1fSAndroid Build Coastguard Worker 					goto out;
496*59bfda1fSAndroid Build Coastguard Worker 				}
497*59bfda1fSAndroid Build Coastguard Worker 			}
498*59bfda1fSAndroid Build Coastguard Worker 			sector = blk_zone_sector(blkz) + blk_zone_length(blkz);
499*59bfda1fSAndroid Build Coastguard Worker 			blkz++;
500*59bfda1fSAndroid Build Coastguard Worker 		}
501*59bfda1fSAndroid Build Coastguard Worker 	}
502*59bfda1fSAndroid Build Coastguard Worker out:
503*59bfda1fSAndroid Build Coastguard Worker 	free(rep);
504*59bfda1fSAndroid Build Coastguard Worker 	if (!ret)
505*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: Discarded %"PRIu64" MB\n", (sector << 9) >> 20);
506*59bfda1fSAndroid Build Coastguard Worker 	return ret;
507*59bfda1fSAndroid Build Coastguard Worker }
508*59bfda1fSAndroid Build Coastguard Worker 
f2fs_finish_zone(int i,void * blkzone)509*59bfda1fSAndroid Build Coastguard Worker int f2fs_finish_zone(int i, void *blkzone)
510*59bfda1fSAndroid Build Coastguard Worker {
511*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone *blkz = (struct blk_zone *)blkzone;
512*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + i;
513*59bfda1fSAndroid Build Coastguard Worker 	struct blk_zone_range range;
514*59bfda1fSAndroid Build Coastguard Worker 	int ret;
515*59bfda1fSAndroid Build Coastguard Worker 
516*59bfda1fSAndroid Build Coastguard Worker 	if (!blk_zone_seq(blkz) || !blk_zone_open(blkz))
517*59bfda1fSAndroid Build Coastguard Worker 		return 0;
518*59bfda1fSAndroid Build Coastguard Worker 
519*59bfda1fSAndroid Build Coastguard Worker 	/* Non empty sequential zone: finish */
520*59bfda1fSAndroid Build Coastguard Worker 	range.sector = blk_zone_sector(blkz);
521*59bfda1fSAndroid Build Coastguard Worker 	range.nr_sectors = blk_zone_length(blkz);
522*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(dev->fd, BLKFINISHZONE, &range);
523*59bfda1fSAndroid Build Coastguard Worker 	if (ret != 0) {
524*59bfda1fSAndroid Build Coastguard Worker 		ret = -errno;
525*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("ioctl BLKFINISHZONE failed: errno=%d, status=%s\n",
526*59bfda1fSAndroid Build Coastguard Worker 			errno, blk_zone_cond_str(blkz));
527*59bfda1fSAndroid Build Coastguard Worker 	}
528*59bfda1fSAndroid Build Coastguard Worker 
529*59bfda1fSAndroid Build Coastguard Worker 	return ret;
530*59bfda1fSAndroid Build Coastguard Worker }
531*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_usable_segments(struct f2fs_super_block * sb)532*59bfda1fSAndroid Build Coastguard Worker uint32_t f2fs_get_usable_segments(struct f2fs_super_block *sb)
533*59bfda1fSAndroid Build Coastguard Worker {
534*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_BLK_ZONE_REP_V2
535*59bfda1fSAndroid Build Coastguard Worker 	int i, j;
536*59bfda1fSAndroid Build Coastguard Worker 	uint32_t usable_segs = 0, zone_segs;
537*59bfda1fSAndroid Build Coastguard Worker 
538*59bfda1fSAndroid Build Coastguard Worker 	if (c.func == RESIZE)
539*59bfda1fSAndroid Build Coastguard Worker 		return get_sb(segment_count_main);
540*59bfda1fSAndroid Build Coastguard Worker 
541*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < c.ndevs; i++) {
542*59bfda1fSAndroid Build Coastguard Worker 		if (c.devices[i].zoned_model != F2FS_ZONED_HM) {
543*59bfda1fSAndroid Build Coastguard Worker 			usable_segs += c.devices[i].total_segments;
544*59bfda1fSAndroid Build Coastguard Worker 			continue;
545*59bfda1fSAndroid Build Coastguard Worker 		}
546*59bfda1fSAndroid Build Coastguard Worker 		for (j = 0; j < c.devices[i].nr_zones; j++) {
547*59bfda1fSAndroid Build Coastguard Worker 			zone_segs = c.devices[i].zone_cap_blocks[j] >>
548*59bfda1fSAndroid Build Coastguard Worker 					get_sb(log_blocks_per_seg);
549*59bfda1fSAndroid Build Coastguard Worker 			if (c.devices[i].zone_cap_blocks[j] %
550*59bfda1fSAndroid Build Coastguard Worker 						DEFAULT_BLOCKS_PER_SEGMENT)
551*59bfda1fSAndroid Build Coastguard Worker 				usable_segs += zone_segs + 1;
552*59bfda1fSAndroid Build Coastguard Worker 			else
553*59bfda1fSAndroid Build Coastguard Worker 				usable_segs += zone_segs;
554*59bfda1fSAndroid Build Coastguard Worker 		}
555*59bfda1fSAndroid Build Coastguard Worker 	}
556*59bfda1fSAndroid Build Coastguard Worker 	usable_segs -= (get_sb(main_blkaddr) - get_sb(segment0_blkaddr)) >>
557*59bfda1fSAndroid Build Coastguard Worker 						get_sb(log_blocks_per_seg);
558*59bfda1fSAndroid Build Coastguard Worker 	return usable_segs;
559*59bfda1fSAndroid Build Coastguard Worker #endif
560*59bfda1fSAndroid Build Coastguard Worker 	return get_sb(segment_count_main);
561*59bfda1fSAndroid Build Coastguard Worker }
562*59bfda1fSAndroid Build Coastguard Worker 
563*59bfda1fSAndroid Build Coastguard Worker #else
564*59bfda1fSAndroid Build Coastguard Worker 
f2fs_report_zone(int i,uint64_t UNUSED (sector),struct blk_zone * UNUSED (blkzone))565*59bfda1fSAndroid Build Coastguard Worker int f2fs_report_zone(int i, uint64_t UNUSED(sector),
566*59bfda1fSAndroid Build Coastguard Worker 		     struct blk_zone *UNUSED(blkzone))
567*59bfda1fSAndroid Build Coastguard Worker {
568*59bfda1fSAndroid Build Coastguard Worker 	ERR_MSG("%d: Unsupported zoned block device\n", i);
569*59bfda1fSAndroid Build Coastguard Worker 	return -1;
570*59bfda1fSAndroid Build Coastguard Worker }
571*59bfda1fSAndroid Build Coastguard Worker 
f2fs_report_zones(int i,report_zones_cb_t * UNUSED (report_zones_cb),void * UNUSED (opaque))572*59bfda1fSAndroid Build Coastguard Worker int f2fs_report_zones(int i, report_zones_cb_t *UNUSED(report_zones_cb),
573*59bfda1fSAndroid Build Coastguard Worker 					void *UNUSED(opaque))
574*59bfda1fSAndroid Build Coastguard Worker {
575*59bfda1fSAndroid Build Coastguard Worker 	ERR_MSG("%d: Unsupported zoned block device\n", i);
576*59bfda1fSAndroid Build Coastguard Worker 	return -1;
577*59bfda1fSAndroid Build Coastguard Worker }
578*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_zoned_model(int i)579*59bfda1fSAndroid Build Coastguard Worker int f2fs_get_zoned_model(int i)
580*59bfda1fSAndroid Build Coastguard Worker {
581*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + i;
582*59bfda1fSAndroid Build Coastguard Worker 
583*59bfda1fSAndroid Build Coastguard Worker 	c.zoned_mode = 0;
584*59bfda1fSAndroid Build Coastguard Worker 	dev->zoned_model = F2FS_ZONED_NONE;
585*59bfda1fSAndroid Build Coastguard Worker 	return 0;
586*59bfda1fSAndroid Build Coastguard Worker }
587*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_zone_blocks(int i)588*59bfda1fSAndroid Build Coastguard Worker int f2fs_get_zone_blocks(int i)
589*59bfda1fSAndroid Build Coastguard Worker {
590*59bfda1fSAndroid Build Coastguard Worker 	struct device_info *dev = c.devices + i;
591*59bfda1fSAndroid Build Coastguard Worker 
592*59bfda1fSAndroid Build Coastguard Worker 	c.zoned_mode = 0;
593*59bfda1fSAndroid Build Coastguard Worker 	dev->nr_zones = 0;
594*59bfda1fSAndroid Build Coastguard Worker 	dev->zone_blocks = 0;
595*59bfda1fSAndroid Build Coastguard Worker 	dev->zoned_model = F2FS_ZONED_NONE;
596*59bfda1fSAndroid Build Coastguard Worker 
597*59bfda1fSAndroid Build Coastguard Worker 	return 0;
598*59bfda1fSAndroid Build Coastguard Worker }
599*59bfda1fSAndroid Build Coastguard Worker 
f2fs_check_zones(int i)600*59bfda1fSAndroid Build Coastguard Worker int f2fs_check_zones(int i)
601*59bfda1fSAndroid Build Coastguard Worker {
602*59bfda1fSAndroid Build Coastguard Worker 	ERR_MSG("%d: Unsupported zoned block device\n", i);
603*59bfda1fSAndroid Build Coastguard Worker 	return -1;
604*59bfda1fSAndroid Build Coastguard Worker }
605*59bfda1fSAndroid Build Coastguard Worker 
f2fs_reset_zone(int i,void * UNUSED (blkzone))606*59bfda1fSAndroid Build Coastguard Worker int f2fs_reset_zone(int i, void *UNUSED(blkzone))
607*59bfda1fSAndroid Build Coastguard Worker {
608*59bfda1fSAndroid Build Coastguard Worker 	ERR_MSG("%d: Unsupported zoned block device\n", i);
609*59bfda1fSAndroid Build Coastguard Worker 	return -1;
610*59bfda1fSAndroid Build Coastguard Worker }
611*59bfda1fSAndroid Build Coastguard Worker 
f2fs_reset_zones(int i)612*59bfda1fSAndroid Build Coastguard Worker int f2fs_reset_zones(int i)
613*59bfda1fSAndroid Build Coastguard Worker {
614*59bfda1fSAndroid Build Coastguard Worker 	ERR_MSG("%d: Unsupported zoned block device\n", i);
615*59bfda1fSAndroid Build Coastguard Worker 	return -1;
616*59bfda1fSAndroid Build Coastguard Worker }
617*59bfda1fSAndroid Build Coastguard Worker 
f2fs_finish_zone(int i,void * UNUSED (blkzone))618*59bfda1fSAndroid Build Coastguard Worker int f2fs_finish_zone(int i, void *UNUSED(blkzone))
619*59bfda1fSAndroid Build Coastguard Worker {
620*59bfda1fSAndroid Build Coastguard Worker 	ERR_MSG("%d: Unsupported zoned block device\n", i);
621*59bfda1fSAndroid Build Coastguard Worker 	return -1;
622*59bfda1fSAndroid Build Coastguard Worker }
623*59bfda1fSAndroid Build Coastguard Worker 
f2fs_get_usable_segments(struct f2fs_super_block * sb)624*59bfda1fSAndroid Build Coastguard Worker uint32_t f2fs_get_usable_segments(struct f2fs_super_block *sb)
625*59bfda1fSAndroid Build Coastguard Worker {
626*59bfda1fSAndroid Build Coastguard Worker 	return get_sb(segment_count_main);
627*59bfda1fSAndroid Build Coastguard Worker }
628*59bfda1fSAndroid Build Coastguard Worker #endif
629*59bfda1fSAndroid Build Coastguard Worker 
630