diff options
Diffstat (limited to 'fs/ufs/inode.c')
-rw-r--r-- | fs/ufs/inode.c | 116 |
1 files changed, 76 insertions, 40 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index c57612d443d0..72282043a8f4 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -152,7 +152,7 @@ out: | |||
152 | return ret; | 152 | return ret; |
153 | } | 153 | } |
154 | 154 | ||
155 | static void ufs_clear_block(struct inode *inode, struct buffer_head *bh) | 155 | static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh) |
156 | { | 156 | { |
157 | lock_buffer(bh); | 157 | lock_buffer(bh); |
158 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | 158 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); |
@@ -163,27 +163,52 @@ static void ufs_clear_block(struct inode *inode, struct buffer_head *bh) | |||
163 | sync_dirty_buffer(bh); | 163 | sync_dirty_buffer(bh); |
164 | } | 164 | } |
165 | 165 | ||
166 | static struct buffer_head *ufs_inode_getfrag(struct inode *inode, | 166 | static struct buffer_head * |
167 | unsigned int fragment, unsigned int new_fragment, | 167 | ufs_clear_frags(struct inode *inode, sector_t beg, |
168 | unsigned int required, int *err, int metadata, | 168 | unsigned int n) |
169 | long *phys, int *new, struct page *locked_page) | 169 | { |
170 | struct buffer_head *res, *bh; | ||
171 | sector_t end = beg + n; | ||
172 | |||
173 | res = sb_getblk(inode->i_sb, beg); | ||
174 | ufs_clear_frag(inode, res); | ||
175 | for (++beg; beg < end; ++beg) { | ||
176 | bh = sb_getblk(inode->i_sb, beg); | ||
177 | ufs_clear_frag(inode, bh); | ||
178 | } | ||
179 | return res; | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * ufs_inode_getfrag() - allocate new fragment(s) | ||
184 | * @inode - pointer to inode | ||
185 | * @fragment - number of `fragment' which hold pointer | ||
186 | * to new allocated fragment(s) | ||
187 | * @new_fragment - number of new allocated fragment(s) | ||
188 | * @required - how many fragment(s) we require | ||
189 | * @err - we set it if something wrong | ||
190 | * @phys - pointer to where we save physical number of new allocated fragments, | ||
191 | * NULL if we allocate not data(indirect blocks for example). | ||
192 | * @new - we set it if we allocate new block | ||
193 | * @locked_page - for ufs_new_fragments() | ||
194 | */ | ||
195 | static struct buffer_head * | ||
196 | ufs_inode_getfrag(struct inode *inode, unsigned int fragment, | ||
197 | sector_t new_fragment, unsigned int required, int *err, | ||
198 | long *phys, int *new, struct page *locked_page) | ||
170 | { | 199 | { |
171 | struct ufs_inode_info *ufsi = UFS_I(inode); | 200 | struct ufs_inode_info *ufsi = UFS_I(inode); |
172 | struct super_block * sb; | 201 | struct super_block *sb = inode->i_sb; |
173 | struct ufs_sb_private_info * uspi; | 202 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
174 | struct buffer_head * result; | 203 | struct buffer_head * result; |
175 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; | 204 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; |
176 | unsigned tmp, goal; | 205 | unsigned tmp, goal; |
177 | __fs32 * p, * p2; | 206 | __fs32 * p, * p2; |
178 | unsigned flags = 0; | ||
179 | 207 | ||
180 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %u, required %u\n", | 208 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, required %u, " |
181 | inode->i_ino, fragment, new_fragment, required); | 209 | "metadata %d\n", inode->i_ino, fragment, |
210 | (unsigned long long)new_fragment, required, !phys); | ||
182 | 211 | ||
183 | sb = inode->i_sb; | ||
184 | uspi = UFS_SB(sb)->s_uspi; | ||
185 | |||
186 | flags = UFS_SB(sb)->s_flags; | ||
187 | /* TODO : to be done for write support | 212 | /* TODO : to be done for write support |
188 | if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 213 | if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) |
189 | goto ufs2; | 214 | goto ufs2; |
@@ -198,7 +223,7 @@ repeat: | |||
198 | tmp = fs32_to_cpu(sb, *p); | 223 | tmp = fs32_to_cpu(sb, *p); |
199 | lastfrag = ufsi->i_lastfrag; | 224 | lastfrag = ufsi->i_lastfrag; |
200 | if (tmp && fragment < lastfrag) { | 225 | if (tmp && fragment < lastfrag) { |
201 | if (metadata) { | 226 | if (!phys) { |
202 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 227 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
203 | if (tmp == fs32_to_cpu(sb, *p)) { | 228 | if (tmp == fs32_to_cpu(sb, *p)) { |
204 | UFSD("EXIT, result %u\n", tmp + blockoff); | 229 | UFSD("EXIT, result %u\n", tmp + blockoff); |
@@ -265,9 +290,8 @@ repeat: | |||
265 | return NULL; | 290 | return NULL; |
266 | } | 291 | } |
267 | 292 | ||
268 | if (metadata) { | 293 | if (!phys) { |
269 | result = sb_getblk(inode->i_sb, tmp + blockoff); | 294 | result = ufs_clear_frags(inode, tmp + blockoff, required); |
270 | ufs_clear_block(inode, result); | ||
271 | } else { | 295 | } else { |
272 | *phys = tmp + blockoff; | 296 | *phys = tmp + blockoff; |
273 | result = NULL; | 297 | result = NULL; |
@@ -298,23 +322,35 @@ repeat2: | |||
298 | */ | 322 | */ |
299 | } | 323 | } |
300 | 324 | ||
301 | static struct buffer_head *ufs_block_getfrag(struct inode *inode, struct buffer_head *bh, | 325 | /** |
302 | unsigned int fragment, unsigned int new_fragment, | 326 | * ufs_inode_getblock() - allocate new block |
303 | unsigned int blocksize, int * err, int metadata, | 327 | * @inode - pointer to inode |
304 | long *phys, int *new, struct page *locked_page) | 328 | * @bh - pointer to block which hold "pointer" to new allocated block |
329 | * @fragment - number of `fragment' which hold pointer | ||
330 | * to new allocated block | ||
331 | * @new_fragment - number of new allocated fragment | ||
332 | * (block will hold this fragment and also uspi->s_fpb-1) | ||
333 | * @err - see ufs_inode_getfrag() | ||
334 | * @phys - see ufs_inode_getfrag() | ||
335 | * @new - see ufs_inode_getfrag() | ||
336 | * @locked_page - see ufs_inode_getfrag() | ||
337 | */ | ||
338 | static struct buffer_head * | ||
339 | ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, | ||
340 | unsigned int fragment, sector_t new_fragment, int *err, | ||
341 | long *phys, int *new, struct page *locked_page) | ||
305 | { | 342 | { |
306 | struct super_block * sb; | 343 | struct super_block *sb = inode->i_sb; |
307 | struct ufs_sb_private_info * uspi; | 344 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
308 | struct buffer_head * result; | 345 | struct buffer_head * result; |
309 | unsigned tmp, goal, block, blockoff; | 346 | unsigned tmp, goal, block, blockoff; |
310 | __fs32 * p; | 347 | __fs32 * p; |
311 | 348 | ||
312 | sb = inode->i_sb; | ||
313 | uspi = UFS_SB(sb)->s_uspi; | ||
314 | block = ufs_fragstoblks (fragment); | 349 | block = ufs_fragstoblks (fragment); |
315 | blockoff = ufs_fragnum (fragment); | 350 | blockoff = ufs_fragnum (fragment); |
316 | 351 | ||
317 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %u\n", inode->i_ino, fragment, new_fragment); | 352 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, metadata %d\n", |
353 | inode->i_ino, fragment, (unsigned long long)new_fragment, !phys); | ||
318 | 354 | ||
319 | result = NULL; | 355 | result = NULL; |
320 | if (!bh) | 356 | if (!bh) |
@@ -330,7 +366,7 @@ static struct buffer_head *ufs_block_getfrag(struct inode *inode, struct buffer_ | |||
330 | repeat: | 366 | repeat: |
331 | tmp = fs32_to_cpu(sb, *p); | 367 | tmp = fs32_to_cpu(sb, *p); |
332 | if (tmp) { | 368 | if (tmp) { |
333 | if (metadata) { | 369 | if (!phys) { |
334 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 370 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
335 | if (tmp == fs32_to_cpu(sb, *p)) | 371 | if (tmp == fs32_to_cpu(sb, *p)) |
336 | goto out; | 372 | goto out; |
@@ -355,9 +391,8 @@ repeat: | |||
355 | } | 391 | } |
356 | 392 | ||
357 | 393 | ||
358 | if (metadata) { | 394 | if (!phys) { |
359 | result = sb_getblk(sb, tmp + blockoff); | 395 | result = ufs_clear_frags(inode, tmp + blockoff, uspi->s_fpb); |
360 | ufs_clear_block(inode, result); | ||
361 | } else { | 396 | } else { |
362 | *phys = tmp + blockoff; | 397 | *phys = tmp + blockoff; |
363 | *new = 1; | 398 | *new = 1; |
@@ -375,11 +410,12 @@ out: | |||
375 | return result; | 410 | return result; |
376 | } | 411 | } |
377 | 412 | ||
378 | /* | 413 | /** |
379 | * This function gets the block which contains the fragment. | 414 | * ufs_getfrag_bloc() - `get_block_t' function, interface between UFS and |
415 | * readpage, writepage and so on | ||
380 | */ | 416 | */ |
381 | 417 | ||
382 | int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) | 418 | int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) |
383 | { | 419 | { |
384 | struct super_block * sb = inode->i_sb; | 420 | struct super_block * sb = inode->i_sb; |
385 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; | 421 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; |
@@ -421,15 +457,15 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
421 | * it much more readable: | 457 | * it much more readable: |
422 | */ | 458 | */ |
423 | #define GET_INODE_DATABLOCK(x) \ | 459 | #define GET_INODE_DATABLOCK(x) \ |
424 | ufs_inode_getfrag(inode, x, fragment, 1, &err, 0, &phys, &new, bh_result->b_page) | 460 | ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page) |
425 | #define GET_INODE_PTR(x) \ | 461 | #define GET_INODE_PTR(x) \ |
426 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, 1, NULL, NULL, bh_result->b_page) | 462 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, bh_result->b_page) |
427 | #define GET_INDIRECT_DATABLOCK(x) \ | 463 | #define GET_INDIRECT_DATABLOCK(x) \ |
428 | ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ | 464 | ufs_inode_getblock(inode, bh, x, fragment, \ |
429 | &err, 0, &phys, &new, bh_result->b_page); | 465 | &err, &phys, &new, bh_result->b_page); |
430 | #define GET_INDIRECT_PTR(x) \ | 466 | #define GET_INDIRECT_PTR(x) \ |
431 | ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ | 467 | ufs_inode_getblock(inode, bh, x, fragment, \ |
432 | &err, 1, NULL, NULL, bh_result->b_page); | 468 | &err, NULL, NULL, bh_result->b_page); |
433 | 469 | ||
434 | if (ptr < UFS_NDIR_FRAGMENT) { | 470 | if (ptr < UFS_NDIR_FRAGMENT) { |
435 | bh = GET_INODE_DATABLOCK(ptr); | 471 | bh = GET_INODE_DATABLOCK(ptr); |