]> code.delx.au - refind/blobdiff - filesystems/fsw_core.c
Version 0.7.0 release with misc. filesystem driver improvements.
[refind] / filesystems / fsw_core.c
index dbc71983b17d55ab3ed6f2af067a13ae99c23ba1..1ecb75fad5b2ab0f0a9323200081ff9538d9807d 100644 (file)
@@ -178,7 +178,7 @@ void fsw_set_blocksize(struct fsw_volume *vol, fsw_u32 phys_blocksize, fsw_u32 l
  * caller calls fsw_block_release.
  */
 
-fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32 cache_level, void **buffer_out)
+fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u64 phys_bno, fsw_u32 cache_level, void **buffer_out)
 {
     fsw_status_t    status;
     fsw_u32         i, discard_level, new_bcache_size;
@@ -191,18 +191,18 @@ fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32
         cache_level = MAX_CACHE_LEVEL;
 
     if (vol->bcache_size > 0 && vol->bcache == NULL) {
-       /* driver set the initial cache size */
+        /* driver set the initial cache size */
         status = fsw_alloc(vol->bcache_size * sizeof(struct fsw_blockcache), &vol->bcache);
-       if(status)
-           return status;
-       for( i = 0; i < vol->bcache_size; i++) {
+        if(status)
+            return status;
+        for (i = 0; i < vol->bcache_size; i++) {
             vol->bcache[i].refcount = 0;
             vol->bcache[i].cache_level = 0;
-            vol->bcache[i].phys_bno = (fsw_u32)FSW_INVALID_BNO;
+            vol->bcache[i].phys_bno = (fsw_u64)FSW_INVALID_BNO;
             vol->bcache[i].data = NULL;
-       }
-       i = 0;
-       goto miss;
+        }
+        i = 0;
+        goto miss;
     }
 
     // check block cache
@@ -219,7 +219,7 @@ fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32
 
     // find a free entry in the cache table
     for (i = 0; i < vol->bcache_size; i++) {
-        if (vol->bcache[i].phys_bno == (fsw_u32)FSW_INVALID_BNO)
+        if (vol->bcache[i].phys_bno == (fsw_u64)FSW_INVALID_BNO)
             break;
     }
     if (i >= vol->bcache_size) {
@@ -246,7 +246,7 @@ fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32
         for (i = vol->bcache_size; i < new_bcache_size; i++) {
             new_bcache[i].refcount = 0;
             new_bcache[i].cache_level = 0;
-            new_bcache[i].phys_bno = (fsw_u32)FSW_INVALID_BNO;
+            new_bcache[i].phys_bno = (fsw_u64)FSW_INVALID_BNO;
             new_bcache[i].data = NULL;
         }
         i = vol->bcache_size;
@@ -257,7 +257,7 @@ fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32
         vol->bcache = new_bcache;
         vol->bcache_size = new_bcache_size;
     }
-    vol->bcache[i].phys_bno = (fsw_u32)FSW_INVALID_BNO;
+    vol->bcache[i].phys_bno = (fsw_u64)FSW_INVALID_BNO;
 miss:
 
     // read the data
@@ -282,7 +282,7 @@ miss:
  * from fsw_block_get.
  */
 
-void fsw_block_release(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, void *buffer)
+void fsw_block_release(struct VOLSTRUCTNAME *vol, fsw_u64 phys_bno, void *buffer)
 {
     fsw_u32 i;
 
@@ -777,10 +777,12 @@ fsw_status_t fsw_dnode_resolve(struct fsw_dnode *dno, struct fsw_dnode **target_
     fsw_status_t    status;
     struct fsw_string target_name;
     struct fsw_dnode *target_dno;
+    /* Linux kernel max link count is 40 */
+    int link_count = 40;
 
     fsw_dnode_retain(dno);
 
-    while (1) {
+    while (--link_count > 0) {
         // get full information
         status = fsw_dnode_fill(dno);
         if (status)
@@ -810,6 +812,8 @@ fsw_status_t fsw_dnode_resolve(struct fsw_dnode *dno, struct fsw_dnode **target_
         fsw_dnode_release(dno);
         dno = target_dno;   // is already retained
     }
+    if(link_count == 0)
+      status = FSW_NOT_FOUND;
 
 errorexit:
     fsw_dnode_release(dno);
@@ -875,8 +879,8 @@ fsw_status_t fsw_shandle_read(struct fsw_shandle *shand, fsw_u32 *buffer_size_in
     struct fsw_dnode *dno = shand->dnode;
     struct fsw_volume *vol = dno->vol;
     fsw_u8          *buffer, *block_buffer;
-    fsw_u32         buflen, copylen, pos;
-    fsw_u32         log_bno, pos_in_extent, phys_bno, pos_in_physblock;
+    fsw_u64         buflen, copylen, pos;
+    fsw_u64         log_bno, pos_in_extent, phys_bno, pos_in_physblock;
     fsw_u32         cache_level;
 
     if (shand->pos >= dno->size) {   // already at EOF
@@ -895,7 +899,7 @@ fsw_status_t fsw_shandle_read(struct fsw_shandle *shand, fsw_u32 *buffer_size_in
 
     while (buflen > 0) {
         // get extent for the current logical block
-        log_bno = pos / vol->log_blocksize;
+        log_bno = FSW_U64_DIV(pos, vol->log_blocksize);
         if (shand->extent.type == FSW_EXTENT_TYPE_INVALID ||
             log_bno < shand->extent.log_start ||
             log_bno >= shand->extent.log_start + shand->extent.log_count) {
@@ -917,7 +921,7 @@ fsw_status_t fsw_shandle_read(struct fsw_shandle *shand, fsw_u32 *buffer_size_in
         // dispatch by extent type
         if (shand->extent.type == FSW_EXTENT_TYPE_PHYSBLOCK) {
             // convert to physical block number and offset
-            phys_bno = shand->extent.phys_start + pos_in_extent / vol->phys_blocksize;
+            phys_bno = shand->extent.phys_start + FSW_U64_DIV(pos_in_extent, vol->phys_blocksize);
             pos_in_physblock = pos_in_extent & (vol->phys_blocksize - 1);
             copylen = vol->phys_blocksize - pos_in_physblock;
             if (copylen > buflen)