Messages in this thread Patch in this message | | | Date | Fri, 15 Jul 2011 15:12:50 -0400 | From | Phillip Susi <> | Subject | Re: loop device auto release patch |
| |
On 7/14/2011 2:56 PM, Ayan George wrote: > > Hi Philip, > > This is the patch I'd like to submit for the loop device. I'm in the > process of testing it now. I'm pretty confident it will work.
Looks good to me. Forwarding to Andrew Morton. Andrew, please disregard my previous patch as I think this one is better.
From c783ba6a26eff42d3cb0061e4fcb8ee8a16b3e67 Mon Sep 17 00:00:00 2001 From: Ayan George <ayan.george@canonical.com> Date: Thu, 14 Jul 2011 14:16:58 -0400 Subject: [PATCH] Always invalidate cleared loop block devices
The API for loop_clr_fd() is confusing -- the second argument (bdev) isn't necessesary as struct loop_device contains a pointer to the block device it is assocated with.
There is a cases where loop_clr_fd() is called with NULL for bdev which prevents the block device from ever being invalidated with invalidate_bdev() and prevents a uevent from being emitted.
This patch removes the bdev argument from loop_clr_fd(), unconditionally invalidates lo->lo_device when cleared, and unconditionally emits a uevent for removed loops.
Launchpad bug for reference:
BugLink: https://bugs.launchpad.net/bugs/548546
Signed-off-by: Ayan George <ayan.george@canonical.com> --- drivers/block/loop.c | 24 ++++++++++++++---------- 1 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 76c8da7..a40e12b 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -987,11 +987,13 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, return err; } -static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) +static int loop_clr_fd(struct loop_device *lo) { struct file *filp = lo->lo_backing_file; gfp_t gfp = lo->old_gfp_mask; + struct block_device *bdev = lo->lo_device; + if (lo->lo_state != Lo_bound) return -ENXIO; @@ -1022,15 +1024,17 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - if (bdev) - invalidate_bdev(bdev); + + invalidate_bdev(bdev); + set_capacity(lo->lo_disk, 0); loop_sysfs_exit(lo); - if (bdev) { - bd_set_size(bdev, 0); - /* let user-space know about this change */ - kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); - } + + bd_set_size(bdev, 0); + + /* let user-space know about this change */ + kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); + mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = Lo_unbound; /* This is safe: open() is still holding a reference. */ @@ -1298,7 +1302,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, break; case LOOP_CLR_FD: /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ - err = loop_clr_fd(lo, bdev); + err = loop_clr_fd(lo); if (!err) goto out_unlocked; break; @@ -1509,7 +1513,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) * In autoclear mode, stop the loop thread * and remove configuration after last close. */ - err = loop_clr_fd(lo, NULL); + err = loop_clr_fd(lo); if (!err) goto out_unlocked; } else { -- 1.7.4.1
| |