aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorEvgeniy Dushistov <dushistov@mail.ru>2006-06-25 08:47:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:03 -0400
commit022a6dc5f461a30615bcd1687569abeee7ef8ba2 (patch)
tree8f16f7d70aa443f0d53bed70ac8633ec6febd87c /fs
parent2e006393ba5b599d9c43f94f8d8989e68131433e (diff)
[PATCH] ufs: zero metadata
Presently if we allocate several "metadata" blocks (pointers to indirect blocks for example), we fill with zeroes only the first block. This cause some problems in "truncate" function. Also this patch remove some unused arguments from several functions and add comments. Signed-off-by: Evgeniy Dushistov <dushistov@mail.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ufs/inode.c116
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
155static void ufs_clear_block(struct inode *inode, struct buffer_head *bh) 155static 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
166static struct buffer_head *ufs_inode_getfrag(struct inode *inode, 166static struct buffer_head *
167 unsigned int fragment, unsigned int new_fragment, 167ufs_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 */
195static struct buffer_head *
196ufs_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
301static 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 */
338static struct buffer_head *
339ufs_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_
330repeat: 366repeat:
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
382int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) 418int 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);