diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index f63a09c..572b145 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c @@ -404,6 +404,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, if (tmp) { UFSD("EXIT (ALREADY ALLOCATED)\n"); unlock_super(sb); + *err = 0; return 0; } } diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 4320782..34ce4fb 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -273,6 +273,8 @@ repeat: tmp = ufs_new_fragments(inode, p, fragment - blockoff, goal, uspi->s_fpb, err, phys != NULL ? locked_page : NULL); + if (!tmp && ufs_data_ptr_to_cpu(sb, p)) + goto repeat; } if (!tmp) { if ((!blockoff && ufs_data_ptr_to_cpu(sb, p)) || @@ -423,10 +425,13 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head u64 phys64 = 0; if (!create) { - phys64 = ufs_frag_map(inode, fragment); - UFSD("phys64 = %llu\n", (unsigned long long)phys64); - if (phys64) - map_bh(bh_result, sb, phys64); + if (fragment < UFS_I(inode)->i_lastfrag) { + phys64 = ufs_frag_map(inode, fragment); + if (phys64) + map_bh(bh_result, sb, phys64); + } + UFSD("fragment %llu, phys64 = %llu\n", + (unsigned long long)fragment, (unsigned long long)phys64); return 0; } @@ -502,6 +507,7 @@ out: map_bh(bh_result, sb, phys); abort: unlock_kernel(); + UFSD("EXIT: err %d, new %d\n", err, new); return err; abort_negative: diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 311ded3..ef09426 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -390,6 +390,7 @@ static int ufs_alloc_lastblock(struct inode *inode) u64 phys64; lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; + UFSD("BEGIN lastfrag %llu\n", (unsigned long long)lastfrag); if (!lastfrag) goto out; @@ -418,13 +419,13 @@ static int ufs_alloc_lastblock(struct inode *inode) clear_buffer_new(bh); unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); - /* - * we do not zeroize fragment, because of - * if it maped to hole, it already contains zeroes - */ - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - set_page_dirty(lastpage); + if (!buffer_dirty(bh)) { + zero_user_page(lastpage, end * sb->s_blocksize, + sb->s_blocksize, KM_USER0); + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + set_page_dirty(lastpage); + } } if (lastfrag >= UFS_IND_FRAGMENT) {