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

[Xen-devel] [BLKTAP]: Fix potential grant entry leaks on error



Hi Keir:

[BLKTAP]: Fix potential grant entry leaks on error

As it stands grant entries for the actual data are mapped in bulk.
If one of the earlier entries fail to be mapped, it can cause all
subsequent entries to be leaked if they were successfully mapped.

This patch changes it so that we will continue to reap grant entries
even when an error is detected.

There is still a potential leak if create_lookup_pte_addr fails
in fast_flush_area.  This leak is not affected by this patch.

Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -r 4c40bed66ade linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Thu Oct 19 22:05:07 
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Fri Oct 20 15:58:54 
2006 +1000
@@ -845,27 +845,28 @@ static void fast_flush_area(pending_req_
                uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i);
 
                khandle = &pending_handle(mmap_idx, k_idx, i);
-               if (BLKTAP_INVALID_HANDLE(khandle)) {
-                       WPRINTK("BLKTAP_INVALID_HANDLE\n");
-                       continue;
-               }
-               gnttab_set_unmap_op(&unmap[invcount], 
-                                   idx_to_kaddr(mmap_idx, k_idx, i), 
-                                   GNTMAP_host_map, khandle->kernel);
-               invcount++;
-
-               if (create_lookup_pte_addr(
-                   info->vma->vm_mm,
-                   MMAP_VADDR(info->user_vstart, u_idx, i), 
-                   &ptep) !=0) {
-                       WPRINTK("Couldn't get a pte addr!\n");
-                       return;
-               }
-
-               gnttab_set_unmap_op(&unmap[invcount], 
-                       ptep, GNTMAP_host_map,
-                       khandle->user);
-               invcount++;
+
+               if (khandle->kernel != 0xFFFF) {
+                       gnttab_set_unmap_op(&unmap[invcount], 
+                                           idx_to_kaddr(mmap_idx, k_idx, i), 
+                                           GNTMAP_host_map, khandle->kernel);
+                       invcount++;
+               }
+
+               if (khandle->user != 0xFFFF) {
+                       if (create_lookup_pte_addr(
+                           info->vma->vm_mm,
+                           MMAP_VADDR(info->user_vstart, u_idx, i), 
+                           &ptep) !=0) {
+                               WPRINTK("Couldn't get a pte addr!\n");
+                               return;
+                       }
+
+                       gnttab_set_unmap_op(&unmap[invcount], 
+                               ptep, GNTMAP_host_map,
+                               khandle->user);
+                       invcount++;
+               }
             
                BLKTAP_INVALIDATE_HANDLE(khandle);
        }
@@ -1224,19 +1224,25 @@ static void dispatch_rw_block_io(blkif_t
                if (unlikely(map[i].status != 0)) {
                        WPRINTK("invalid kernel buffer -- "
                                "could not remap it\n");
-                       goto fail_flush;
+                       ret |= 1;
+                       map[i].handle = 0xFFFF;
                }
 
                if (unlikely(map[i+1].status != 0)) {
                        WPRINTK("invalid user buffer -- "
                                "could not remap it\n");
-                       goto fail_flush;
+                       ret |= 1;
+                       map[i+1].handle = 0xFFFF;
                }
 
                pending_handle(mmap_idx, pending_idx, i/2).kernel 
                        = map[i].handle;
                pending_handle(mmap_idx, pending_idx, i/2).user   
                        = map[i+1].handle;
+
+               if (ret)
+                       continue;
+
                set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
                        FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
                offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
@@ -1244,6 +1250,10 @@ static void dispatch_rw_block_io(blkif_t
                ((struct page **)info->vma->vm_private_data)[offset] =
                        pg;
        }
+
+       if (ret)
+               goto fail_flush;
+
        /* Mark mapped pages as reserved: */
        for (i = 0; i < req->nr_segments; i++) {
                unsigned long kvaddr;

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


 


Rackspace

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