ext2_get_ino_metablock() will allocate blocks
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 13 Oct 2010 01:17:39 +0000 (18:17 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:55 +0000 (17:35 -0700)
If there isn't a block already for ino_block, it will allocate and 0
one, similar to what goes on in mappage and readpage (just smoother,
since it's in the blockdev buffer cache).

kern/src/ext2fs.c

index 2d1cb3d..9a538f5 100644 (file)
@@ -347,11 +347,31 @@ uint32_t ext2_find_inoblock(struct inode *inode, unsigned int ino_block)
 }
 
 /* Returns an incref'd metadata block for the contents of the ino block.  Don't
 }
 
 /* Returns an incref'd metadata block for the contents of the ino block.  Don't
- * use this for regular files - use their inode's page cache instead. */
+ * use this for regular files - use their inode's page cache instead (used for
+ * directories for now).  If there isn't a block allocated yet, it will provide
+ * a zeroed one. */
 void *ext2_get_ino_metablock(struct inode *inode, unsigned long ino_block)
 {
 void *ext2_get_ino_metablock(struct inode *inode, unsigned long ino_block)
 {
-       uint32_t blkid = ext2_find_inoblock(inode, ino_block);
-       return ext2_get_metablock(inode->i_sb, blkid);
+       uint32_t blkid, *retval, *blk_slot;
+       blk_slot = ext2_lookup_inotable_slot(inode, ino_block);
+       blkid = le32_to_cpu(*blk_slot);
+       if (blkid) {
+               ext2_put_metablock(inode->i_sb, blk_slot);
+               return ext2_get_metablock(inode->i_sb, blkid);
+       }
+       /* If there isn't a block there, alloc and insert one.  This block will be
+        * the next big chunk of "file" data for this inode. */
+       blkid = ext2_alloc_block(inode, ext2_bgidx2block(inode->i_sb,
+                                                        ext2_inode2bg(inode),
+                                                        0));
+       *blk_slot = cpu_to_le32(blkid);
+       ext2_dirty_metablock(inode->i_sb, blk_slot);
+       ext2_put_metablock(inode->i_sb, blk_slot);
+       inode->i_blocks += inode->i_sb->s_blocksize >> 9;       /* inc by 1 FS block */
+       inode->i_size += inode->i_sb->s_blocksize;
+       retval = ext2_get_metablock(inode->i_sb, blkid);
+       memset(retval, 0, inode->i_sb->s_blocksize);            /* 0 the new block */
+       return retval;
 }
 
 /* This should help with degubbing.  In read_inode(), print out the i_block, and
 }
 
 /* This should help with degubbing.  In read_inode(), print out the i_block, and
@@ -359,9 +379,9 @@ void *ext2_get_ino_metablock(struct inode *inode, unsigned long ino_block)
  * the 2x and 3x walks are jacked up. */
 void ext2_print_ino_blocks(struct inode *inode)
 {
  * the 2x and 3x walks are jacked up. */
 void ext2_print_ino_blocks(struct inode *inode)
 {
-       printk("Inode %08p, Size: %d, 512B 'blocks;: %d\n-------------\n", inode,
+       printk("Inode %08p, Size: %d, 512B 'blocks': %d\n-------------\n", inode,
               inode->i_size, inode->i_blocks);
               inode->i_size, inode->i_blocks);
-       for (int i = 0; i < inode->i_blocks; i++)
+       for (int i = 0; i < inode->i_blocks * (inode->i_sb->s_blocksize / 512); i++)
                printk("# %03d, Block %03d\n", i, ext2_find_inoblock(inode, i));
 }
 
                printk("# %03d, Block %03d\n", i, ext2_find_inoblock(inode, i));
 }