diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-01-03 09:47:09 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-01-03 09:47:09 -0500 |
commit | 87d8fe1ee6b8d2f95076142d58c440dba4e7bdc2 (patch) | |
tree | 8c91506978a16c22268b086f693e307de0ca57db | |
parent | 0087d9fb3f29f59e8d42c8b058376d80e5adde4c (diff) |
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: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/block_dev.c | 15 | ||||
-rw-r--r-- | fs/super.c | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 2 |
3 files changed, 19 insertions, 0 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 349a26c10001..1dd07e66e98a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1220,6 +1220,20 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
1220 | return blkdev_ioctl(bdev, mode, cmd, arg); | 1220 | return blkdev_ioctl(bdev, mode, cmd, arg); |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | /* | ||
1224 | * Try to release a page associated with block device when the system | ||
1225 | * is under memory pressure. | ||
1226 | */ | ||
1227 | static int blkdev_releasepage(struct page *page, gfp_t wait) | ||
1228 | { | ||
1229 | struct super_block *super = BDEV_I(page->mapping->host)->bdev.bd_super; | ||
1230 | |||
1231 | if (super && super->s_op->bdev_try_to_free_page) | ||
1232 | return super->s_op->bdev_try_to_free_page(super, page, wait); | ||
1233 | |||
1234 | return try_to_free_buffers(page); | ||
1235 | } | ||
1236 | |||
1223 | static const struct address_space_operations def_blk_aops = { | 1237 | static const struct address_space_operations def_blk_aops = { |
1224 | .readpage = blkdev_readpage, | 1238 | .readpage = blkdev_readpage, |
1225 | .writepage = blkdev_writepage, | 1239 | .writepage = blkdev_writepage, |
@@ -1227,6 +1241,7 @@ static const struct address_space_operations def_blk_aops = { | |||
1227 | .write_begin = blkdev_write_begin, | 1241 | .write_begin = blkdev_write_begin, |
1228 | .write_end = blkdev_write_end, | 1242 | .write_end = blkdev_write_end, |
1229 | .writepages = generic_writepages, | 1243 | .writepages = generic_writepages, |
1244 | .releasepage = blkdev_releasepage, | ||
1230 | .direct_IO = blkdev_direct_IO, | 1245 | .direct_IO = blkdev_direct_IO, |
1231 | }; | 1246 | }; |
1232 | 1247 | ||
diff --git a/fs/super.c b/fs/super.c index ddba069d7a99..d5fd4498548a 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -800,6 +800,7 @@ int get_sb_bdev(struct file_system_type *fs_type, | |||
800 | } | 800 | } |
801 | 801 | ||
802 | s->s_flags |= MS_ACTIVE; | 802 | s->s_flags |= MS_ACTIVE; |
803 | bdev->bd_super = s; | ||
803 | } | 804 | } |
804 | 805 | ||
805 | return simple_set_mnt(mnt, s); | 806 | return simple_set_mnt(mnt, s); |
@@ -819,6 +820,7 @@ void kill_block_super(struct super_block *sb) | |||
819 | struct block_device *bdev = sb->s_bdev; | 820 | struct block_device *bdev = sb->s_bdev; |
820 | fmode_t mode = sb->s_mode; | 821 | fmode_t mode = sb->s_mode; |
821 | 822 | ||
823 | bdev->bd_super = 0; | ||
822 | generic_shutdown_super(sb); | 824 | generic_shutdown_super(sb); |
823 | sync_blockdev(bdev); | 825 | sync_blockdev(bdev); |
824 | close_bdev_exclusive(bdev, mode); | 826 | close_bdev_exclusive(bdev, mode); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index f2a3010140e3..0f54ae0f0ccd 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -565,6 +565,7 @@ struct address_space { | |||
565 | struct block_device { | 565 | struct block_device { |
566 | dev_t bd_dev; /* not a kdev_t - it's a search key */ | 566 | dev_t bd_dev; /* not a kdev_t - it's a search key */ |
567 | struct inode * bd_inode; /* will die */ | 567 | struct inode * bd_inode; /* will die */ |
568 | struct super_block * bd_super; | ||
568 | int bd_openers; | 569 | int bd_openers; |
569 | struct mutex bd_mutex; /* open/close mutex */ | 570 | struct mutex bd_mutex; /* open/close mutex */ |
570 | struct semaphore bd_mount_sem; | 571 | struct semaphore bd_mount_sem; |
@@ -1385,6 +1386,7 @@ struct super_operations { | |||
1385 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); | 1386 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); |
1386 | ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); | 1387 | ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); |
1387 | #endif | 1388 | #endif |
1389 | int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); | ||
1388 | }; | 1390 | }; |
1389 | 1391 | ||
1390 | /* | 1392 | /* |