Whamcloud - gitweb
ext2fs.h (BMAP_SET), bmap.c (ext2fs_bmap): Add support for new
authorTheodore Ts'o <tytso@mit.edu>
Thu, 23 Dec 2004 18:55:34 +0000 (13:55 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 23 Dec 2004 18:55:34 +0000 (13:55 -0500)
flag, BMAP_SET, which allows the caller to set a
particular logical->physical block mapping.

lib/ext2fs/ChangeLog
lib/ext2fs/bmap.c
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext2fs.h

index 2df731a..f2ce518 100644 (file)
@@ -1,5 +1,11 @@
 2004-12-23  Theodore Ts'o  <tytso@mit.edu>
 
+       * ext2fs.h (BMAP_SET), bmap.c (ext2fs_bmap): Add support for new
+               flag, BMAP_SET, which allows the caller to set a
+               particular logical->physical block mapping.
+
+       * ext2_err.et.in (EXT2_ET_SET_BMAP_NO_IND): New error code
+
        * initialize.c (calc_reserved_gdt_blocks): #ifdef out all
                debugging printf statements.
        
index 45053dc..e840044 100644 (file)
@@ -29,8 +29,6 @@ extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
                             char *block_buf, int bmap_flags,
                             blk_t block, blk_t *phys_blk);
 
-#define BMAP_ALLOC     1
-
 #define inode_bmap(inode, nr) ((inode)->i_block[(nr)])
 
 static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags, 
@@ -42,6 +40,8 @@ static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags,
        blk_t           b;
 
        if (!ind) {
+               if (flags & BMAP_SET)
+                       return EXT2_ET_SET_BMAP_NO_IND;
                *ret_blk = 0;
                return 0;
        }
@@ -49,6 +49,17 @@ static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags,
        if (retval)
                return retval;
 
+       if (flags & BMAP_SET) {
+               b = *ret_blk;
+#ifdef EXT2FS_ENABLE_SWAPFS
+               if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+                   (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
+                       b = ext2fs_swab32(b);
+#endif
+               ((blk_t *) block_buf)[nr] = b;
+               return io_channel_write_blk(fs->io, ind, 1, block_buf);
+       }
+
        b = ((blk_t *) block_buf)[nr];
 
 #ifdef EXT2FS_ENABLE_SWAPFS
@@ -94,8 +105,8 @@ static _BMAP_INLINE_ errcode_t block_dind_bmap(ext2_filsys fs, int flags,
        
        addr_per_block = (blk_t) fs->blocksize >> 2;
 
-       retval = block_ind_bmap(fs, flags, dind, block_buf, blocks_alloc,
-                               nr / addr_per_block, &b);
+       retval = block_ind_bmap(fs, flags & ~BMAP_SET, dind, block_buf, 
+                               blocks_alloc, nr / addr_per_block, &b);
        if (retval)
                return retval;
        retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
@@ -114,8 +125,8 @@ static _BMAP_INLINE_ errcode_t block_tind_bmap(ext2_filsys fs, int flags,
        
        addr_per_block = (blk_t) fs->blocksize >> 2;
 
-       retval = block_dind_bmap(fs, flags, tind, block_buf, blocks_alloc,
-                                nr / addr_per_block, &b);
+       retval = block_dind_bmap(fs, flags & ~BMAP_SET, tind, block_buf, 
+                                blocks_alloc, nr / addr_per_block, &b);
        if (retval)
                return retval;
        retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
@@ -132,9 +143,10 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
        blk_t   b;
        char    *buf = 0;
        errcode_t       retval = 0;
-       int             blocks_alloc = 0;
+       int             blocks_alloc = 0, inode_dirty = 0;
 
-       *phys_blk = 0;
+       if (!(bmap_flags & BMAP_SET))
+               *phys_blk = 0;
 
        /* Read inode structure if necessary */
        if (!inode) {
@@ -153,6 +165,18 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
        }
 
        if (block < EXT2_NDIR_BLOCKS) {
+               if (bmap_flags & BMAP_SET) {
+                       b = *phys_blk;
+#ifdef EXT2FS_ENABLE_SWAPFS
+                       if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+                           (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
+                               b = ext2fs_swab32(b);
+#endif
+                       inode_bmap(inode, block) = b;
+                       inode_dirty++;
+                       goto done;
+               }
+
                *phys_blk = inode_bmap(inode, block);
                b = block ? inode_bmap(inode, block-1) : 0;
                
@@ -172,8 +196,11 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
        if (block < addr_per_block) {
                b = inode_bmap(inode, EXT2_IND_BLOCK);
                if (!b) {
-                       if (!(bmap_flags & BMAP_ALLOC))
-                           goto done;
+                       if (!(bmap_flags & BMAP_ALLOC)) {
+                               if (bmap_flags & BMAP_SET)
+                                       retval = EXT2_ET_SET_BMAP_NO_IND;
+                               goto done;
+                       }
 
                        b = inode_bmap(inode, EXT2_IND_BLOCK-1);
                        retval = ext2fs_alloc_block(fs, b, block_buf, &b);
@@ -192,8 +219,11 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
        if (block < addr_per_block * addr_per_block) {
                b = inode_bmap(inode, EXT2_DIND_BLOCK);
                if (!b) {
-                       if (!(bmap_flags & BMAP_ALLOC))
-                           goto done;
+                       if (!(bmap_flags & BMAP_ALLOC)) {
+                               if (bmap_flags & BMAP_SET)
+                                       retval = EXT2_ET_SET_BMAP_NO_IND;
+                               goto done;
+                       }
 
                        b = inode_bmap(inode, EXT2_IND_BLOCK);
                        retval = ext2fs_alloc_block(fs, b, block_buf, &b);
@@ -211,8 +241,11 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
        block -= addr_per_block * addr_per_block;
        b = inode_bmap(inode, EXT2_TIND_BLOCK);
        if (!b) {
-               if (!(bmap_flags & BMAP_ALLOC))
+               if (!(bmap_flags & BMAP_ALLOC)) {
+                       if (bmap_flags & BMAP_SET)
+                               retval = EXT2_ET_SET_BMAP_NO_IND;
                        goto done;
+               }
 
                b = inode_bmap(inode, EXT2_DIND_BLOCK);
                retval = ext2fs_alloc_block(fs, b, block_buf, &b);
@@ -226,7 +259,7 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
 done:
        if (buf)
                ext2fs_free_mem(&buf);
-       if ((retval == 0) && blocks_alloc) {
+       if ((retval == 0) && (blocks_alloc || inode_dirty)) {
                inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
                retval = ext2fs_write_inode(fs, ino, inode);
        }
index 5314c6c..907b475 100644 (file)
@@ -293,5 +293,8 @@ ec  EXT2_ET_RES_GDT_BLOCKS,
 ec     EXT2_ET_RESIZE_INODE_CORRUPT,
        "Resize inode is corrupt"
 
+ec     EXT2_ET_SET_BMAP_NO_IND,
+       "Missing indirect block not present"
+
        end
 
index 8d358b4..55bc547 100644 (file)
@@ -402,7 +402,8 @@ typedef struct ext2_icount *ext2_icount_t;
 /*
  * Flags for ext2fs_bmap
  */
-#define BMAP_ALLOC     1
+#define BMAP_ALLOC     0x0001
+#define BMAP_SET       0x0002
 
 /*
  * Flags for imager.c functions