Skip to contentSkip to conversation

tune2fs: touch the device node after setting the label via ioctl

PATCH In review Baokun Li 2 participants 2 messages Sep 23 VFS

lore
Share & tools
lore

Baokun Li

author
#0 lore raw

PATCH 1/1 tune2fs: touch the device node after setting the label via ioctl

When the file system is mounted, tune2fs sets the label through FS_IOC_SETFSLABEL, which updates the label without touching the mtime of the device node. Consumers such as blkid use that mtime to validate their cached superblock information, so the old label can still be returned right after the change:

  blkid -s LABEL /dev/sdb    # gets "old" and caches it
  tune2fs -L new /dev/sdb    # online path, node mtime unchanged
  blkid -s LABEL /dev/sdb    # still gets "old" within 2s

The offline path is unaffected because writing the superblock through the device node updates its mtime as a side effect. The ioctl path has no such side effect, so add an explicit utime() on the device after a successful FS_IOC_SETFSLABEL.

The return value is ignored; if the touch fails, the behavior is no worse than before.

---
 misc/tune2fs.c | 9 +++++++++
 1 file changed, 9 insertions(+)
misc/tune2fs.c +9 -0
index 2d85fb704e15..87b8e6830bb9 100644
@@ -48,6 +48,7 @@ extern int optind;
 #endif
 #include <string.h>
 #include <time.h>
+#include <utime.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <libgen.h>
@@ -3167,6 +3168,14 @@ static int handle_fslabel(int setlabel)
 		return 1;
 	}
 	close(fd);
+
+	/*
+	 * FS_IOC_SETFSLABEL does not touch the device mtime that
+	 * blkid uses to validate its cache; touch the device so
+	 * mtime-based consumers see the change.
+	 */
+	utime(device_name, NULL);
+
 	return 0;
 #else
 	return -1;
Signature · 1 line
2.43.7
#1 lore raw

[cc linux-fsdevel]

Quoted 38 lines · Baokun Li

When the file system is mounted, tune2fs sets the label through FS_IOC_SETFSLABEL, which updates the label without touching the mtime of the device node. Consumers such as blkid use that mtime to validate their cached superblock information, so the old label can still be returned right after the change:

  blkid -s LABEL /dev/sdb    # gets "old" and caches it
  tune2fs -L new /dev/sdb    # online path, node mtime unchanged
  blkid -s LABEL /dev/sdb    # still gets "old" within 2s

The offline path is unaffected because writing the superblock through the device node updates its mtime as a side effect. The ioctl path has no such side effect, so add an explicit utime() on the device after a successful FS_IOC_SETFSLABEL.

The return value is ignored; if the touch fails, the behavior is no worse than before.

---
 misc/tune2fs.c | 9 +++++++++
 1 file changed, 9 insertions(+)
misc/tune2fs.c +1 -0
index 2d85fb704e15..87b8e6830bb9 100644
@@ -48,6 +48,7 @@ extern int optind;
 #endif
 #include <string.h>
 #include <time.h>
+#include <utime.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <libgen.h>

misc/tune2fs.c static int handle_fslabel(int setlabel) · line 3177

Quoted 10 lines
misc/tune2fs.c +7 -0
@@ -3167,6 +3168,14 @@ static int handle_fslabel(int setlabel)
 		return 1;
 	}
 	close(fd);
+
+	/*
+	 * FS_IOC_SETFSLABEL does not touch the device mtime that
+	 * blkid uses to validate its cache; touch the device so
+	 * mtime-based consumers see the change.
+	 */
+	utime(device_name, NULL);

For everyone on fsdevel who might be seeing this for the first time, there was a problem report in which it was discovered that the libblkid cache invalidates its knowledge if something updates the block device mtime. This is done whenever userspace tools update a block device (e.g. mkfs) but not done by the kernel when it rewrites the primary superblock (e.g. FS_IOC_SETFSLABEL).

This patch fixes tune2fs to add the missing mtime update, but I think a better way to solve this is to fix the ~8 or so implementations inside the kernel. And maybe the FS_IOC_SETFSUUID implementations too.

A bigger question, then, is whether filesystems should bump mtime /any/ time they update their own superblock? There aren't any published specs mandating this behavior by the kernel, but I suppose it falls under "someone observed a behavior and started relying on it" :P

Thoughts?

--D

[1] https://lore.kernel.org/linux-ext4/[email protected]/

Quoted 8 lines
misc/tune2fs.c +1 -0
+
 	return 0;
 #else
 	return -1;
Signature · 1 line
2.43.7