Subject: 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. Written and tested on 2.6.32.11 and made apply to the 2.6.18 tree without further testing. Signed-off-by: Jan Beulich --- sle11sp1-2010-04-12.orig/drivers/xen/blktap/blktap.c 2010-01-04 13:22:46.000000000 +0100 +++ sle11sp1-2010-04-12/drivers/xen/blktap/blktap.c 2010-04-19 09:24:00.000000000 +0200 @@ -638,6 +638,7 @@ static int blktap_open(struct inode *ino 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) @@ -646,7 +647,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; @@ -1089,7 +1092,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); @@ -1147,6 +1150,7 @@ static void print_stats(blkif_t *blkif) int tap_blkif_schedule(void *arg) { blkif_t *blkif = arg; + tap_blkif_t *info; blkif_get(blkif); @@ -1180,8 +1184,16 @@ 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; }