[libbluray-devel] udfread_read_blocks(): read multiple blocks at once

Petri Hintukainen git at videolan.org
Sat Jun 24 14:43:00 CEST 2017


libudfread | branch: master | Petri Hintukainen <phintuka at gmail.com> | Fri Jun 23 15:33:10 2017 +0300| [bb93b35f756cc52131461a03dddda80266d93896] | committer: Petri Hintukainen

udfread_read_blocks(): read multiple blocks at once

> http://git.videolan.org/gitweb.cgi/libudfread.git/?a=commit;h=bb93b35f756cc52131461a03dddda80266d93896
---

 src/udfread.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/udfread.c b/src/udfread.c
index ce51e1d..169de3b 100644
--- a/src/udfread.c
+++ b/src/udfread.c
@@ -1427,7 +1427,7 @@ void udfread_file_close(UDFFILE *p)
  * block access
  */
 
-static uint32_t _file_lba(UDFFILE *p, uint32_t file_block)
+static uint32_t _file_lba(UDFFILE *p, uint32_t file_block, uint32_t *extent_length)
 {
     const struct file_entry *fe;
     unsigned int i;
@@ -1455,6 +1455,10 @@ static uint32_t _file_lba(UDFFILE *p, uint32_t file_block)
             if (ad[i].partition != p->udf->part.p[0].number) {
                 udf_error("file partition %u != %u\n", ad[i].partition, p->udf->part.p[0].number);
             }
+
+            if (extent_length) {
+                *extent_length = ad_size - file_block;
+            }
             return p->udf->part.p[0].lba + ad[i].lba + file_block;
         }
 
@@ -1484,7 +1488,7 @@ uint32_t udfread_file_lba(UDFFILE *p, uint32_t file_block)
         return 0;
     }
 
-    return _file_lba(p, file_block);
+    return _file_lba(p, file_block, NULL);
 }
 
 uint32_t udfread_read_blocks(UDFFILE *p, void *buf, uint32_t file_block, uint32_t num_blocks, int flags)
@@ -1499,10 +1503,12 @@ uint32_t udfread_read_blocks(UDFFILE *p, void *buf, uint32_t file_block, uint32_
         return 0;
     }
 
-    for (i = 0; i < num_blocks; i++) {
-        uint32_t lba = _file_lba(p, file_block + i);
+    for (i = 0; i < num_blocks; ) {
+        uint32_t extent_length = 0;
+        uint32_t lba;
         uint8_t *block = (uint8_t *)buf + UDF_BLOCK_SIZE * i;
 
+        lba = _file_lba(p, file_block + i, &extent_length);
         udf_trace("map block %u to lba %u\n", file_block + i, lba);
 
         if (!lba) {
@@ -1511,15 +1517,22 @@ uint32_t udfread_read_blocks(UDFFILE *p, void *buf, uint32_t file_block, uint32_
             if (file_block + i < file_blocks) {
                 udf_trace("zero-fill unallocated / unwritten block %u\n", file_block + i);
                 memset(block, 0, UDF_BLOCK_SIZE);
+                i++;
                 continue;
             }
             udf_error("block %u outside of file (size %u blocks)\n", file_block + i, file_blocks);
             break;
         }
 
-        if (_read_blocks(p->udf->input, lba, block, 1, flags) != 1) {
+        if (extent_length > num_blocks - i) {
+            extent_length = num_blocks - i;
+        }
+
+        extent_length = _read_blocks(p->udf->input, lba, block, extent_length, flags);
+        if (extent_length < 1) {
             break;
         }
+        i += extent_length;
     }
     return i;
 }



More information about the libbluray-devel mailing list