]> err.no Git - linux-2.6/blobdiff - fs/ext4/inode.c
PCI: powerpc: use generic pci_enable_resources()
[linux-2.6] / fs / ext4 / inode.c
index 34f3eb615fd5eaa0fdc077b4da6ad6d43a0bc3d8..945cbf6cb1fc6d686c5ef89ba2663ce753dab160 100644 (file)
@@ -908,11 +908,38 @@ out:
  */
 #define DIO_CREDITS 25
 
+
+/*
+ *
+ *
+ * ext4_ext4 get_block() wrapper function
+ * It will do a look up first, and returns if the blocks already mapped.
+ * Otherwise it takes the write lock of the i_data_sem and allocate blocks
+ * and store the allocated blocks in the result buffer head and mark it
+ * mapped.
+ *
+ * If file type is extents based, it will call ext4_ext_get_blocks(),
+ * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping
+ * based files
+ *
+ * On success, it returns the number of blocks being mapped or allocate.
+ * if create==0 and the blocks are pre-allocated and uninitialized block,
+ * the result buffer head is unmapped. If the create ==1, it will make sure
+ * the buffer head is mapped.
+ *
+ * It returns 0 if plain look up failed (blocks have not been allocated), in
+ * that casem, buffer head is unmapped
+ *
+ * It returns the error in case of allocation failure.
+ */
 int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
                        unsigned long max_blocks, struct buffer_head *bh,
                        int create, int extend_disksize)
 {
        int retval;
+
+       clear_buffer_mapped(bh);
+
        /*
         * Try to see if we can get  the block without requesting
         * for new file system block.
@@ -926,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
                                inode, block, max_blocks, bh, 0, 0);
        }
        up_read((&EXT4_I(inode)->i_data_sem));
-       if (!create || (retval > 0))
+
+       /* If it is only a block(s) look up */
+       if (!create)
+               return retval;
+
+       /*
+        * Returns if the blocks have already allocated
+        *
+        * Note that if blocks have been preallocated
+        * ext4_ext_get_block() returns th create = 0
+        * with buffer head unmapped.
+        */
+       if (retval > 0 && buffer_mapped(bh))
                return retval;
 
        /*
-        * We need to allocate new blocks which will result
-        * in i_data update
+        * New blocks allocate and/or writing to uninitialized extent
+        * will possibly result in updating i_data, so we take
+        * the write lock of i_data_sem, and call get_blocks()
+        * with create == 1 flag.
         */
        down_write((&EXT4_I(inode)->i_data_sem));
        /*