Commit 87d8fe1e authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

add releasepage hooks to block devices which can be used by file systems



Implement blkdev_releasepage() to release the buffer_heads and pages
after we release private data belonging to a mounted filesystem.

Cc: Toshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 0087d9fb
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1220,6 +1220,20 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
	return blkdev_ioctl(bdev, mode, cmd, arg);
}

/*
 * Try to release a page associated with block device when the system
 * is under memory pressure.
 */
static int blkdev_releasepage(struct page *page, gfp_t wait)
{
	struct super_block *super = BDEV_I(page->mapping->host)->bdev.bd_super;

	if (super && super->s_op->bdev_try_to_free_page)
		return super->s_op->bdev_try_to_free_page(super, page, wait);

	return try_to_free_buffers(page);
}

static const struct address_space_operations def_blk_aops = {
	.readpage	= blkdev_readpage,
	.writepage	= blkdev_writepage,
@@ -1227,6 +1241,7 @@ static const struct address_space_operations def_blk_aops = {
	.write_begin	= blkdev_write_begin,
	.write_end	= blkdev_write_end,
	.writepages	= generic_writepages,
	.releasepage	= blkdev_releasepage,
	.direct_IO	= blkdev_direct_IO,
};

+2 −0
Original line number Diff line number Diff line
@@ -800,6 +800,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
		}

		s->s_flags |= MS_ACTIVE;
		bdev->bd_super = s;
	}

	return simple_set_mnt(mnt, s);
@@ -819,6 +820,7 @@ void kill_block_super(struct super_block *sb)
	struct block_device *bdev = sb->s_bdev;
	fmode_t mode = sb->s_mode;

	bdev->bd_super = 0;
	generic_shutdown_super(sb);
	sync_blockdev(bdev);
	close_bdev_exclusive(bdev, mode);
+2 −0
Original line number Diff line number Diff line
@@ -565,6 +565,7 @@ struct address_space {
struct block_device {
	dev_t			bd_dev;  /* not a kdev_t - it's a search key */
	struct inode *		bd_inode;	/* will die */
	struct super_block *	bd_super;
	int			bd_openers;
	struct mutex		bd_mutex;	/* open/close mutex */
	struct semaphore	bd_mount_sem;
@@ -1385,6 +1386,7 @@ struct super_operations {
	ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
	ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
#endif
	int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
};

/*