]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
Fix reading after end of file for file-backed LUNs.
authormav <mav@FreeBSD.org>
Wed, 16 Sep 2015 21:43:51 +0000 (21:43 +0000)
committermav <mav@FreeBSD.org>
Wed, 16 Sep 2015 21:43:51 +0000 (21:43 +0000)
If backing file is smaller then the LUN size, we have to explicitly clear
the rest of the buffer to not leak some random data from previous I/Os.

sys/cam/ctl/ctl_backend_block.c

index 753501530366b875634f4b65fff5e52eed119a26..975de2c9b5ae6e457dd4a41d8b2b20793ff17d4c 100644 (file)
@@ -632,8 +632,8 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
        union ctl_io *io;
        struct uio xuio;
        struct iovec *xiovec;
-       int flags;
-       int error, i;
+       size_t s;
+       int error, flags, i;
 
        DPRINTF("entered\n");
 
@@ -694,6 +694,22 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
 
                VOP_UNLOCK(be_lun->vn, 0);
                SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
+               if (error == 0 && xuio.uio_resid > 0) {
+                       /*
+                        * If we red less then requested (EOF), then
+                        * we should clean the rest of the buffer.
+                        */
+                       s = beio->io_len - xuio.uio_resid;
+                       for (i = 0; i < beio->num_segs; i++) {
+                               if (s >= beio->sg_segs[i].len) {
+                                       s -= beio->sg_segs[i].len;
+                                       continue;
+                               }
+                               bzero((uint8_t *)beio->sg_segs[i].addr + s,
+                                   beio->sg_segs[i].len - s);
+                               s = 0;
+                       }
+               }
        } else {
                struct mount *mountpoint;
                int lock_flags;