aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ufs')
-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);