Commit 0965549d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'vfs-6.17-rc1.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull superblock callback update from Christian Brauner:
 "Currently all filesystems which implement super_operations::shutdown()
  can not afford losing a device.

  Thus fs_bdev_mark_dead() will just call the ->shutdown() callback for
  the involved filesystem.

  But it will no longer be the case, as multi-device filesystems like
  btrfs can handle certain device loss without the need to shutdown the
  whole filesystem.

  To allow those multi-device filesystems to be integrated to use
  fs_holder_ops:

   - Add a new super_operations::remove_bdev() callback

   - Try ->remove_bdev() callback first inside fs_bdev_mark_dead().

     If the callback returned 0, meaning the fs can handling the device
     loss, then exit without doing anything else.

     If there is no such callback or the callback returned non-zero
     value, continue to shutdown the filesystem as usual.

  This means the new remove_bdev() should only do the check on whether
  the operation can continue, and if so do the fs specific handlings.
  The shutdown handling should still be handled by the existing
  ->shutdown() callback.

  For all existing filesystems with shutdown callback, there is no
  change to the code nor behavior.

  Btrfs is going to implement both the ->remove_bdev() and ->shutdown()
  callbacks soon"

* tag 'vfs-6.17-rc1.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  fs: add a new remove_bdev() callback
parents 57fcb7d9 d9c37a49
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1459,6 +1459,17 @@ static void fs_bdev_mark_dead(struct block_device *bdev, bool surprise)
	if (!sb)
		return;

	if (sb->s_op->remove_bdev) {
		int ret;

		ret = sb->s_op->remove_bdev(sb, bdev);
		if (!ret) {
			super_unlock_shared(sb);
			return;
		}
		/* Fallback to shutdown. */
	}

	if (!surprise)
		sync_filesystem(sb);
	shrink_dcache_sb(sb);
+9 −0
Original line number Diff line number Diff line
@@ -2367,6 +2367,15 @@ struct super_operations {
				  struct shrink_control *);
	long (*free_cached_objects)(struct super_block *,
				    struct shrink_control *);
	/*
	 * If a filesystem can support graceful removal of a device and
	 * continue read-write operations, implement this callback.
	 *
	 * Return 0 if the filesystem can continue read-write.
	 * Non-zero return value or no such callback means the fs will be shutdown
	 * as usual.
	 */
	int (*remove_bdev)(struct super_block *sb, struct block_device *bdev);
	void (*shutdown)(struct super_block *sb);
};