jaegeuk / f2fs-tools

Other
40 stars 31 forks source link

mkfs.f2fs should reset zone pointers on zoned devices #13

Open joshcarter opened 3 years ago

joshcarter commented 3 years ago

I have discovered (the hard way of course) that mkfs.f2fs -m does not reset zone pointers on a SMR disk. This leads to unaligned write errors once the file system hits one of those zones. I believe mkfs should reset the write pointers of any sequential zones when the -m option is used.

If you have a drive that has been use before (some zone WP's not zero), in this example /dev/sdb1 is a 16TiB partition of a large host-managed SMR drive:

  1. blkzone report /dev/sdb1 | grep "(fu)" | wc -l # note number of full zones
  2. mkfs.f2fs -m /dev/sdb1
  3. blkzone report /dev/sdb1 | grep "(fu)" | wc -l # same number of full zones!

The worst part is that, depending on where the full zones are, the file system may work fine for some amount of time before you hit a previously-used zone. I have also noticed that fsck.f2fs doesn't fix this problem, despite patches that indicate it should. I've built and installed the latest f2fs-tools from source. I am running on Ubuntu 20.04 LTS, kernel 5.4.0-73-generic.

The work-around is to make sure you run blkzone reset /dev/sdb1 before creating the file system.

jaegeuk commented 3 years ago

Interesting. In f2fs-tools, I see f2fs_reset_zones() which calls ioctl(dev->fd, BLKRESETZONE, &range); Could you please check if your build is calling that path?

2021년 6월 2일 (수) 오전 9:42, Josh Carter @.***>님이 작성:

I have discovered (the hard way of course) that mkfs.f2fs -m does not reset zone pointers on a SMR disk. This leads to unaligned write errors once the file system hits one of those zones. I believe mkfs should reset the write pointers of any sequential zones when the -m option is used.

If you have a drive that has been use before (some zone WP's not zero):

  1. blkzone report /dev/device | grep "(fu)" | wc -l # note number of full zones
  2. mkfs.f2fs -m /dev/device
  3. `blkzone report /dev/device | grep "(fu)" | wc -l' # same number of full zones!

The worst part is that, depending on where the full zones are, the file system may work fine for some amount of time before you hit a previously-used zone. I have also noticed that fsck.f2fs doesn't fix this problem, despite patches that indicate it should. I've built and installed the latest f2fs-tools from source. I am running on Ubuntu 20.04 LTS, kernel 5.4.0-73-generic.

The work-around is to make sure you run blkzone reset /dev/device before creating the file system.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jaegeuk/f2fs-tools/issues/13, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE4EPAQP72C3Y5Y4UL2PXO3TQZNQ5ANCNFSM457DJWYA .

joshcarter commented 3 years ago

Yes, certainly, I will investigate and report back.

joshcarter commented 3 years ago

The issue appears to be that I'm formatting a partition of the device, and f2fs_get_zoned_model() does not handle that scenario correctly. It attempts to open /sys/block/sdb1/queue/zoned to check if the device is host-managed or drive-managed, however this file does not exist. It would need to check /sys/block/sdb/queue/zoned instead. This particular device is 16.4TiB (18TB) so F2FS cannot format the entire device, hence my need to partition.

I tried this using dm-linear before using partitioning, however that had its own problems. For example, when I used dm-linear and then attempted to mount the file system, mount failed with bad address. I didn't investigate further; I switched to using parted to partition the device, and that appeared to work correctly, so I continued down that path.

What's the correct solution here? Should f2fs_get_zoned_model() remove the partition number, if one is present? [Edit: I quickly hacked f2fs_get_zoned_model() and f2fs_get_zone_blocks() to use the sdb instead of sdb1 and the mkfs appears to work properly. It detects the zone layout correctly and resets the zone pointers as expected.]

Thanks for your assistance, I appreciate it!

joshcarter commented 3 years ago

Follow-up to my note about the checks in libf2fs_zoned.c: when using dm-linear to reduce the size of my disk, I have to be careful about what device name I give to mkfs.f2fs. The checks in f2fs_get_zoned_model() and f2fs_get_zone_blocks() only work if mkfs.f2fs is called with a target name like /dev/dm-2, and does not work a target name like /dev/mapper/my-device-name. This is because /sys/block has an entry for dm-2 but not my-device-name.

For that scenario, perhaps it's best to check if the device name is a symlink, and follow the symlink if so. On my Ubuntu 20.04 system, /dev/mapper/my-device-name is a symlink to /dev/dm-2.

Is there another way to get the zone topology than reading files under /sys/block? That technique seems fragile.