diff --git a/[refs] b/[refs] index c557dcb0c864..f324bc29bcb9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b27256439568950f30864ccecaeb6dfb588089d5 +refs/heads/master: b3a27d0529c6e5206f1b60f60263e3ecfd0d77cb diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 6690e8bae7bb..413284a51ccc 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -1287,6 +1287,8 @@ struct block_device_operations { unsigned long long); int (*revalidate_disk) (struct gendisk *); int (*getgeo)(struct block_device *, struct hd_geometry *); + /* this callback is with swap_lock and sometimes page table lock held */ + void (*swap_slot_free_notify) (struct block_device *, unsigned long); struct module *owner; }; diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index ecb069e213d0..f5ccc476aa51 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -574,6 +574,7 @@ static unsigned char swap_entry_free(struct swap_info_struct *p, /* free if no reference */ if (!usage) { + struct gendisk *disk = p->bdev->bd_disk; if (offset < p->lowest_bit) p->lowest_bit = offset; if (offset > p->highest_bit) @@ -583,6 +584,9 @@ static unsigned char swap_entry_free(struct swap_info_struct *p, swap_list.next = p->type; nr_swap_pages++; p->inuse_pages--; + if ((p->flags & SWP_BLKDEV) && + disk->fops->swap_slot_free_notify) + disk->fops->swap_slot_free_notify(p->bdev, offset); } return usage;