diff options
Diffstat (limited to 'fs/ufs/inode.c')
| -rw-r--r-- | fs/ufs/inode.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index e7c8615beb65..30c6e8a9446c 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
| @@ -169,18 +169,20 @@ static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh) | |||
| 169 | 169 | ||
| 170 | static struct buffer_head * | 170 | static struct buffer_head * |
| 171 | ufs_clear_frags(struct inode *inode, sector_t beg, | 171 | ufs_clear_frags(struct inode *inode, sector_t beg, |
| 172 | unsigned int n) | 172 | unsigned int n, sector_t want) |
| 173 | { | 173 | { |
| 174 | struct buffer_head *res, *bh; | 174 | struct buffer_head *res = NULL, *bh; |
| 175 | sector_t end = beg + n; | 175 | sector_t end = beg + n; |
| 176 | 176 | ||
| 177 | res = sb_getblk(inode->i_sb, beg); | 177 | for (; beg < end; ++beg) { |
| 178 | ufs_clear_frag(inode, res); | ||
| 179 | for (++beg; beg < end; ++beg) { | ||
| 180 | bh = sb_getblk(inode->i_sb, beg); | 178 | bh = sb_getblk(inode->i_sb, beg); |
| 181 | ufs_clear_frag(inode, bh); | 179 | ufs_clear_frag(inode, bh); |
| 182 | brelse(bh); | 180 | if (want != beg) |
| 181 | brelse(bh); | ||
| 182 | else | ||
| 183 | res = bh; | ||
| 183 | } | 184 | } |
| 185 | BUG_ON(!res); | ||
| 184 | return res; | 186 | return res; |
| 185 | } | 187 | } |
| 186 | 188 | ||
| @@ -265,7 +267,9 @@ repeat: | |||
| 265 | lastfrag = ufsi->i_lastfrag; | 267 | lastfrag = ufsi->i_lastfrag; |
| 266 | 268 | ||
| 267 | } | 269 | } |
| 268 | goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb; | 270 | tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]); |
| 271 | if (tmp) | ||
| 272 | goal = tmp + uspi->s_fpb; | ||
| 269 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, | 273 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, |
| 270 | goal, required + blockoff, | 274 | goal, required + blockoff, |
| 271 | err, locked_page); | 275 | err, locked_page); |
| @@ -277,13 +281,15 @@ repeat: | |||
| 277 | tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), | 281 | tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), |
| 278 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), | 282 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), |
| 279 | err, locked_page); | 283 | err, locked_page); |
| 280 | } | 284 | } else /* (lastblock > block) */ { |
| 281 | /* | 285 | /* |
| 282 | * We will allocate new block before last allocated block | 286 | * We will allocate new block before last allocated block |
| 283 | */ | 287 | */ |
| 284 | else /* (lastblock > block) */ { | 288 | if (block) { |
| 285 | if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1]))) | 289 | tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[block-1]); |
| 286 | goal = tmp + uspi->s_fpb; | 290 | if (tmp) |
| 291 | goal = tmp + uspi->s_fpb; | ||
| 292 | } | ||
| 287 | tmp = ufs_new_fragments(inode, p, fragment - blockoff, | 293 | tmp = ufs_new_fragments(inode, p, fragment - blockoff, |
| 288 | goal, uspi->s_fpb, err, locked_page); | 294 | goal, uspi->s_fpb, err, locked_page); |
| 289 | } | 295 | } |
| @@ -296,7 +302,7 @@ repeat: | |||
| 296 | } | 302 | } |
| 297 | 303 | ||
| 298 | if (!phys) { | 304 | if (!phys) { |
| 299 | result = ufs_clear_frags(inode, tmp + blockoff, required); | 305 | result = ufs_clear_frags(inode, tmp, required, tmp + blockoff); |
| 300 | } else { | 306 | } else { |
| 301 | *phys = tmp + blockoff; | 307 | *phys = tmp + blockoff; |
| 302 | result = NULL; | 308 | result = NULL; |
| @@ -383,7 +389,7 @@ repeat: | |||
| 383 | } | 389 | } |
| 384 | } | 390 | } |
| 385 | 391 | ||
| 386 | if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1]) + uspi->s_fpb)) | 392 | if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1]))) |
| 387 | goal = tmp + uspi->s_fpb; | 393 | goal = tmp + uspi->s_fpb; |
| 388 | else | 394 | else |
| 389 | goal = bh->b_blocknr + uspi->s_fpb; | 395 | goal = bh->b_blocknr + uspi->s_fpb; |
| @@ -397,7 +403,8 @@ repeat: | |||
| 397 | 403 | ||
| 398 | 404 | ||
| 399 | if (!phys) { | 405 | if (!phys) { |
| 400 | result = ufs_clear_frags(inode, tmp + blockoff, uspi->s_fpb); | 406 | result = ufs_clear_frags(inode, tmp, uspi->s_fpb, |
| 407 | tmp + blockoff); | ||
| 401 | } else { | 408 | } else { |
| 402 | *phys = tmp + blockoff; | 409 | *phys = tmp + blockoff; |
| 403 | *new = 1; | 410 | *new = 1; |
