static void ext2_truncate_nocheck (struct inode * inode);
+/*
+ * Called at each iput().
+ *
+ * The inode may be "bad" if ext2_read_inode() saw an error from
+ * ext2_get_inode(), so we need to check that to avoid freeing random disk
+ * blocks.
+ */
+void ext2_put_inode(struct inode *inode)
+{
+ if (!is_bad_inode(inode))
+ ext2_discard_prealloc(inode);
+}
+
+static void ext2_truncate_nocheck (struct inode * inode);
+
/*
* Called at the last iput() if i_nlink is zero.
*/
{
struct ext2_inode_info *ei = EXT2_I(inode);
write_lock(&ei->i_meta_lock);
- if (block == ei->i_next_alloc_block + 1) {
+ if ((block == ei->i_next_alloc_block + 1) && ei->i_next_alloc_goal) {
ei->i_next_alloc_block++;
ei->i_next_alloc_goal++;
}
/* We are done with atomic stuff, now do the rest of housekeeping */
- inode->i_ctime = CURRENT_TIME;
+ inode->i_ctime = CURRENT_TIME_SEC;
/* had we spliced it onto indirect block? */
if (where->bh)
* reachable from inode.
*/
-static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
+int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{
int err = -EIO;
int offsets[4];
return nobh_prepare_write(page,from,to,ext2_get_block);
}
+static int ext2_nobh_writepage(struct page *page,
+ struct writeback_control *wbc)
+{
+ return nobh_writepage(page, ext2_get_block, wbc);
+}
+
static sector_t ext2_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,ext2_get_block);
struct address_space_operations ext2_nobh_aops = {
.readpage = ext2_readpage,
.readpages = ext2_readpages,
- .writepage = ext2_writepage,
+ .writepage = ext2_nobh_writepage,
.sync_page = block_sync_page,
.prepare_write = ext2_nobh_prepare_write,
.commit_write = nobh_commit_write,
case EXT2_TIND_BLOCK:
;
}
- inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
if (inode_needs_sync(inode)) {
sync_mapping_buffers(inode->i_mapping);
ext2_sync_inode (inode);