Mailing List Archive

[linux-2.6.18-xen] xen/blktap: fix cleanup after unclean application exit
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1271693963 -3600
# Node ID eb21d96a6aaef9719a3c83501e52e21dede2c7a4
# Parent fbe371367af64674d8eefa59924890a7b783f769
xen/blktap: fix cleanup after unclean application exit

When an application using blktap devices doesn't close the file handle
(or mmap-s) of /dev/xen/blktapN, we cannot defer the mmput() on the
stored mm until blktap_release(), as that will never be called without
the mm's reference count dropping to zero.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
---
drivers/xen/blktap/blktap.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)

diff -r fbe371367af6 -r eb21d96a6aae drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c Mon Apr 12 17:34:34 2010 +0100
+++ b/drivers/xen/blktap/blktap.c Mon Apr 19 17:19:23 2010 +0100
@@ -637,6 +637,7 @@ static int blktap_release(struct inode *
static int blktap_release(struct inode *inode, struct file *filp)
{
tap_blkif_t *info = filp->private_data;
+ struct mm_struct *mm;

/* check for control device */
if (!info)
@@ -645,7 +646,9 @@ static int blktap_release(struct inode *
info->ring_ok = 0;
smp_wmb();

- mmput(info->mm);
+ mm = xchg(&info->mm, NULL);
+ if (mm)
+ mmput(mm);
info->mm = NULL;
kfree(info->foreign_map.map);
info->foreign_map.map = NULL;
@@ -1087,7 +1090,7 @@ static void fast_flush_area(pending_req_
INVALID_P2M_ENTRY);
}

- if (khandle->user != INVALID_GRANT_HANDLE) {
+ if (mm != NULL && khandle->user != INVALID_GRANT_HANDLE) {
BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
if (!locked++)
down_write(&mm->mmap_sem);
@@ -1144,6 +1147,7 @@ int tap_blkif_schedule(void *arg)
int tap_blkif_schedule(void *arg)
{
blkif_t *blkif = arg;
+ tap_blkif_t *info;

blkif_get(blkif);

@@ -1177,7 +1181,15 @@ int tap_blkif_schedule(void *arg)
printk(KERN_DEBUG "%s: exiting\n", current->comm);

blkif->xenblkd = NULL;
+ info = tapfds[blkif->dev_num];
blkif_put(blkif);
+
+ if (info) {
+ struct mm_struct *mm = xchg(&info->mm, NULL);
+
+ if (mm)
+ mmput(mm);
+ }

return 0;
}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog