[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] xen/blktap: fix cleanup after unclean application exit



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# 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@xxxxxxxxxx>
---
 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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.