diff options
Diffstat (limited to 'fs/ufs/inode.c')
-rw-r--r-- | fs/ufs/inode.c | 267 |
1 files changed, 150 insertions, 117 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 3c3f62ce2ad9..f2dbdf5a8769 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -41,14 +41,7 @@ | |||
41 | #include "swab.h" | 41 | #include "swab.h" |
42 | #include "util.h" | 42 | #include "util.h" |
43 | 43 | ||
44 | #undef UFS_INODE_DEBUG | 44 | static u64 ufs_frag_map(struct inode *inode, sector_t frag); |
45 | #undef UFS_INODE_DEBUG_MORE | ||
46 | |||
47 | #ifdef UFS_INODE_DEBUG | ||
48 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
49 | #else | ||
50 | #define UFSD(x) | ||
51 | #endif | ||
52 | 45 | ||
53 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) | 46 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) |
54 | { | 47 | { |
@@ -61,7 +54,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off | |||
61 | int n = 0; | 54 | int n = 0; |
62 | 55 | ||
63 | 56 | ||
64 | UFSD(("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks)); | 57 | UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks); |
65 | if (i_block < 0) { | 58 | if (i_block < 0) { |
66 | ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); | 59 | ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); |
67 | } else if (i_block < direct_blocks) { | 60 | } else if (i_block < direct_blocks) { |
@@ -89,7 +82,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off | |||
89 | * the begining of the filesystem. | 82 | * the begining of the filesystem. |
90 | */ | 83 | */ |
91 | 84 | ||
92 | u64 ufs_frag_map(struct inode *inode, sector_t frag) | 85 | static u64 ufs_frag_map(struct inode *inode, sector_t frag) |
93 | { | 86 | { |
94 | struct ufs_inode_info *ufsi = UFS_I(inode); | 87 | struct ufs_inode_info *ufsi = UFS_I(inode); |
95 | struct super_block *sb = inode->i_sb; | 88 | struct super_block *sb = inode->i_sb; |
@@ -104,8 +97,8 @@ u64 ufs_frag_map(struct inode *inode, sector_t frag) | |||
104 | unsigned flags = UFS_SB(sb)->s_flags; | 97 | unsigned flags = UFS_SB(sb)->s_flags; |
105 | u64 temp = 0L; | 98 | u64 temp = 0L; |
106 | 99 | ||
107 | UFSD((": frag = %llu depth = %d\n", (unsigned long long)frag, depth)); | 100 | UFSD(": frag = %llu depth = %d\n", (unsigned long long)frag, depth); |
108 | UFSD((": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask)); | 101 | UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask); |
109 | 102 | ||
110 | if (depth == 0) | 103 | if (depth == 0) |
111 | return 0; | 104 | return 0; |
@@ -161,26 +154,64 @@ out: | |||
161 | return ret; | 154 | return ret; |
162 | } | 155 | } |
163 | 156 | ||
164 | static struct buffer_head * ufs_inode_getfrag (struct inode *inode, | 157 | static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh) |
165 | unsigned int fragment, unsigned int new_fragment, | 158 | { |
166 | unsigned int required, int *err, int metadata, long *phys, int *new) | 159 | lock_buffer(bh); |
160 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | ||
161 | set_buffer_uptodate(bh); | ||
162 | mark_buffer_dirty(bh); | ||
163 | unlock_buffer(bh); | ||
164 | if (IS_SYNC(inode)) | ||
165 | sync_dirty_buffer(bh); | ||
166 | } | ||
167 | |||
168 | static struct buffer_head * | ||
169 | ufs_clear_frags(struct inode *inode, sector_t beg, | ||
170 | unsigned int n) | ||
171 | { | ||
172 | struct buffer_head *res, *bh; | ||
173 | sector_t end = beg + n; | ||
174 | |||
175 | res = sb_getblk(inode->i_sb, beg); | ||
176 | ufs_clear_frag(inode, res); | ||
177 | for (++beg; beg < end; ++beg) { | ||
178 | bh = sb_getblk(inode->i_sb, beg); | ||
179 | ufs_clear_frag(inode, bh); | ||
180 | brelse(bh); | ||
181 | } | ||
182 | return res; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * ufs_inode_getfrag() - allocate new fragment(s) | ||
187 | * @inode - pointer to inode | ||
188 | * @fragment - number of `fragment' which hold pointer | ||
189 | * to new allocated fragment(s) | ||
190 | * @new_fragment - number of new allocated fragment(s) | ||
191 | * @required - how many fragment(s) we require | ||
192 | * @err - we set it if something wrong | ||
193 | * @phys - pointer to where we save physical number of new allocated fragments, | ||
194 | * NULL if we allocate not data(indirect blocks for example). | ||
195 | * @new - we set it if we allocate new block | ||
196 | * @locked_page - for ufs_new_fragments() | ||
197 | */ | ||
198 | static struct buffer_head * | ||
199 | ufs_inode_getfrag(struct inode *inode, unsigned int fragment, | ||
200 | sector_t new_fragment, unsigned int required, int *err, | ||
201 | long *phys, int *new, struct page *locked_page) | ||
167 | { | 202 | { |
168 | struct ufs_inode_info *ufsi = UFS_I(inode); | 203 | struct ufs_inode_info *ufsi = UFS_I(inode); |
169 | struct super_block * sb; | 204 | struct super_block *sb = inode->i_sb; |
170 | struct ufs_sb_private_info * uspi; | 205 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
171 | struct buffer_head * result; | 206 | struct buffer_head * result; |
172 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; | 207 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; |
173 | unsigned tmp, goal; | 208 | unsigned tmp, goal; |
174 | __fs32 * p, * p2; | 209 | __fs32 * p, * p2; |
175 | unsigned flags = 0; | ||
176 | 210 | ||
177 | UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u, required %u\n", | 211 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, required %u, " |
178 | inode->i_ino, fragment, new_fragment, required)) | 212 | "metadata %d\n", inode->i_ino, fragment, |
213 | (unsigned long long)new_fragment, required, !phys); | ||
179 | 214 | ||
180 | sb = inode->i_sb; | ||
181 | uspi = UFS_SB(sb)->s_uspi; | ||
182 | |||
183 | flags = UFS_SB(sb)->s_flags; | ||
184 | /* TODO : to be done for write support | 215 | /* TODO : to be done for write support |
185 | if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 216 | if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) |
186 | goto ufs2; | 217 | goto ufs2; |
@@ -195,16 +226,16 @@ repeat: | |||
195 | tmp = fs32_to_cpu(sb, *p); | 226 | tmp = fs32_to_cpu(sb, *p); |
196 | lastfrag = ufsi->i_lastfrag; | 227 | lastfrag = ufsi->i_lastfrag; |
197 | if (tmp && fragment < lastfrag) { | 228 | if (tmp && fragment < lastfrag) { |
198 | if (metadata) { | 229 | if (!phys) { |
199 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 230 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
200 | if (tmp == fs32_to_cpu(sb, *p)) { | 231 | if (tmp == fs32_to_cpu(sb, *p)) { |
201 | UFSD(("EXIT, result %u\n", tmp + blockoff)) | 232 | UFSD("EXIT, result %u\n", tmp + blockoff); |
202 | return result; | 233 | return result; |
203 | } | 234 | } |
204 | brelse (result); | 235 | brelse (result); |
205 | goto repeat; | 236 | goto repeat; |
206 | } else { | 237 | } else { |
207 | *phys = tmp; | 238 | *phys = tmp + blockoff; |
208 | return NULL; | 239 | return NULL; |
209 | } | 240 | } |
210 | } | 241 | } |
@@ -221,7 +252,8 @@ repeat: | |||
221 | if (lastblockoff) { | 252 | if (lastblockoff) { |
222 | p2 = ufsi->i_u1.i_data + lastblock; | 253 | p2 = ufsi->i_u1.i_data + lastblock; |
223 | tmp = ufs_new_fragments (inode, p2, lastfrag, | 254 | tmp = ufs_new_fragments (inode, p2, lastfrag, |
224 | fs32_to_cpu(sb, *p2), uspi->s_fpb - lastblockoff, err); | 255 | fs32_to_cpu(sb, *p2), uspi->s_fpb - lastblockoff, |
256 | err, locked_page); | ||
225 | if (!tmp) { | 257 | if (!tmp) { |
226 | if (lastfrag != ufsi->i_lastfrag) | 258 | if (lastfrag != ufsi->i_lastfrag) |
227 | goto repeat; | 259 | goto repeat; |
@@ -233,14 +265,16 @@ repeat: | |||
233 | } | 265 | } |
234 | goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb; | 266 | goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb; |
235 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, | 267 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, |
236 | goal, required + blockoff, err); | 268 | goal, required + blockoff, |
269 | err, locked_page); | ||
237 | } | 270 | } |
238 | /* | 271 | /* |
239 | * We will extend last allocated block | 272 | * We will extend last allocated block |
240 | */ | 273 | */ |
241 | else if (lastblock == block) { | 274 | else if (lastblock == block) { |
242 | tmp = ufs_new_fragments (inode, p, fragment - (blockoff - lastblockoff), | 275 | tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), |
243 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), err); | 276 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), |
277 | err, locked_page); | ||
244 | } | 278 | } |
245 | /* | 279 | /* |
246 | * We will allocate new block before last allocated block | 280 | * We will allocate new block before last allocated block |
@@ -248,8 +282,8 @@ repeat: | |||
248 | else /* (lastblock > block) */ { | 282 | else /* (lastblock > block) */ { |
249 | if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1]))) | 283 | if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1]))) |
250 | goal = tmp + uspi->s_fpb; | 284 | goal = tmp + uspi->s_fpb; |
251 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, | 285 | tmp = ufs_new_fragments(inode, p, fragment - blockoff, |
252 | goal, uspi->s_fpb, err); | 286 | goal, uspi->s_fpb, err, locked_page); |
253 | } | 287 | } |
254 | if (!tmp) { | 288 | if (!tmp) { |
255 | if ((!blockoff && *p) || | 289 | if ((!blockoff && *p) || |
@@ -259,14 +293,10 @@ repeat: | |||
259 | return NULL; | 293 | return NULL; |
260 | } | 294 | } |
261 | 295 | ||
262 | /* The nullification of framgents done in ufs/balloc.c is | 296 | if (!phys) { |
263 | * something I don't have the stomache to move into here right | 297 | result = ufs_clear_frags(inode, tmp + blockoff, required); |
264 | * now. -DaveM | ||
265 | */ | ||
266 | if (metadata) { | ||
267 | result = sb_getblk(inode->i_sb, tmp + blockoff); | ||
268 | } else { | 298 | } else { |
269 | *phys = tmp; | 299 | *phys = tmp + blockoff; |
270 | result = NULL; | 300 | result = NULL; |
271 | *err = 0; | 301 | *err = 0; |
272 | *new = 1; | 302 | *new = 1; |
@@ -276,7 +306,7 @@ repeat: | |||
276 | if (IS_SYNC(inode)) | 306 | if (IS_SYNC(inode)) |
277 | ufs_sync_inode (inode); | 307 | ufs_sync_inode (inode); |
278 | mark_inode_dirty(inode); | 308 | mark_inode_dirty(inode); |
279 | UFSD(("EXIT, result %u\n", tmp + blockoff)) | 309 | UFSD("EXIT, result %u\n", tmp + blockoff); |
280 | return result; | 310 | return result; |
281 | 311 | ||
282 | /* This part : To be implemented .... | 312 | /* This part : To be implemented .... |
@@ -295,22 +325,35 @@ repeat2: | |||
295 | */ | 325 | */ |
296 | } | 326 | } |
297 | 327 | ||
298 | static struct buffer_head * ufs_block_getfrag (struct inode *inode, | 328 | /** |
299 | struct buffer_head *bh, unsigned int fragment, unsigned int new_fragment, | 329 | * ufs_inode_getblock() - allocate new block |
300 | unsigned int blocksize, int * err, int metadata, long *phys, int *new) | 330 | * @inode - pointer to inode |
331 | * @bh - pointer to block which hold "pointer" to new allocated block | ||
332 | * @fragment - number of `fragment' which hold pointer | ||
333 | * to new allocated block | ||
334 | * @new_fragment - number of new allocated fragment | ||
335 | * (block will hold this fragment and also uspi->s_fpb-1) | ||
336 | * @err - see ufs_inode_getfrag() | ||
337 | * @phys - see ufs_inode_getfrag() | ||
338 | * @new - see ufs_inode_getfrag() | ||
339 | * @locked_page - see ufs_inode_getfrag() | ||
340 | */ | ||
341 | static struct buffer_head * | ||
342 | ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, | ||
343 | unsigned int fragment, sector_t new_fragment, int *err, | ||
344 | long *phys, int *new, struct page *locked_page) | ||
301 | { | 345 | { |
302 | struct super_block * sb; | 346 | struct super_block *sb = inode->i_sb; |
303 | struct ufs_sb_private_info * uspi; | 347 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
304 | struct buffer_head * result; | 348 | struct buffer_head * result; |
305 | unsigned tmp, goal, block, blockoff; | 349 | unsigned tmp, goal, block, blockoff; |
306 | __fs32 * p; | 350 | __fs32 * p; |
307 | 351 | ||
308 | sb = inode->i_sb; | ||
309 | uspi = UFS_SB(sb)->s_uspi; | ||
310 | block = ufs_fragstoblks (fragment); | 352 | block = ufs_fragstoblks (fragment); |
311 | blockoff = ufs_fragnum (fragment); | 353 | blockoff = ufs_fragnum (fragment); |
312 | 354 | ||
313 | UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u\n", inode->i_ino, fragment, new_fragment)) | 355 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, metadata %d\n", |
356 | inode->i_ino, fragment, (unsigned long long)new_fragment, !phys); | ||
314 | 357 | ||
315 | result = NULL; | 358 | result = NULL; |
316 | if (!bh) | 359 | if (!bh) |
@@ -326,14 +369,14 @@ static struct buffer_head * ufs_block_getfrag (struct inode *inode, | |||
326 | repeat: | 369 | repeat: |
327 | tmp = fs32_to_cpu(sb, *p); | 370 | tmp = fs32_to_cpu(sb, *p); |
328 | if (tmp) { | 371 | if (tmp) { |
329 | if (metadata) { | 372 | if (!phys) { |
330 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 373 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
331 | if (tmp == fs32_to_cpu(sb, *p)) | 374 | if (tmp == fs32_to_cpu(sb, *p)) |
332 | goto out; | 375 | goto out; |
333 | brelse (result); | 376 | brelse (result); |
334 | goto repeat; | 377 | goto repeat; |
335 | } else { | 378 | } else { |
336 | *phys = tmp; | 379 | *phys = tmp + blockoff; |
337 | goto out; | 380 | goto out; |
338 | } | 381 | } |
339 | } | 382 | } |
@@ -342,21 +385,19 @@ repeat: | |||
342 | goal = tmp + uspi->s_fpb; | 385 | goal = tmp + uspi->s_fpb; |
343 | else | 386 | else |
344 | goal = bh->b_blocknr + uspi->s_fpb; | 387 | goal = bh->b_blocknr + uspi->s_fpb; |
345 | tmp = ufs_new_fragments (inode, p, ufs_blknum(new_fragment), goal, uspi->s_fpb, err); | 388 | tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal, |
389 | uspi->s_fpb, err, locked_page); | ||
346 | if (!tmp) { | 390 | if (!tmp) { |
347 | if (fs32_to_cpu(sb, *p)) | 391 | if (fs32_to_cpu(sb, *p)) |
348 | goto repeat; | 392 | goto repeat; |
349 | goto out; | 393 | goto out; |
350 | } | 394 | } |
351 | 395 | ||
352 | /* The nullification of framgents done in ufs/balloc.c is | 396 | |
353 | * something I don't have the stomache to move into here right | 397 | if (!phys) { |
354 | * now. -DaveM | 398 | result = ufs_clear_frags(inode, tmp + blockoff, uspi->s_fpb); |
355 | */ | ||
356 | if (metadata) { | ||
357 | result = sb_getblk(sb, tmp + blockoff); | ||
358 | } else { | 399 | } else { |
359 | *phys = tmp; | 400 | *phys = tmp + blockoff; |
360 | *new = 1; | 401 | *new = 1; |
361 | } | 402 | } |
362 | 403 | ||
@@ -365,18 +406,19 @@ repeat: | |||
365 | sync_dirty_buffer(bh); | 406 | sync_dirty_buffer(bh); |
366 | inode->i_ctime = CURRENT_TIME_SEC; | 407 | inode->i_ctime = CURRENT_TIME_SEC; |
367 | mark_inode_dirty(inode); | 408 | mark_inode_dirty(inode); |
368 | UFSD(("result %u\n", tmp + blockoff)); | 409 | UFSD("result %u\n", tmp + blockoff); |
369 | out: | 410 | out: |
370 | brelse (bh); | 411 | brelse (bh); |
371 | UFSD(("EXIT\n")); | 412 | UFSD("EXIT\n"); |
372 | return result; | 413 | return result; |
373 | } | 414 | } |
374 | 415 | ||
375 | /* | 416 | /** |
376 | * This function gets the block which contains the fragment. | 417 | * ufs_getfrag_bloc() - `get_block_t' function, interface between UFS and |
418 | * readpage, writepage and so on | ||
377 | */ | 419 | */ |
378 | 420 | ||
379 | int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) | 421 | int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) |
380 | { | 422 | { |
381 | struct super_block * sb = inode->i_sb; | 423 | struct super_block * sb = inode->i_sb; |
382 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; | 424 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; |
@@ -387,7 +429,7 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
387 | 429 | ||
388 | if (!create) { | 430 | if (!create) { |
389 | phys64 = ufs_frag_map(inode, fragment); | 431 | phys64 = ufs_frag_map(inode, fragment); |
390 | UFSD(("phys64 = %llu \n",phys64)); | 432 | UFSD("phys64 = %llu \n",phys64); |
391 | if (phys64) | 433 | if (phys64) |
392 | map_bh(bh_result, sb, phys64); | 434 | map_bh(bh_result, sb, phys64); |
393 | return 0; | 435 | return 0; |
@@ -402,7 +444,7 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
402 | 444 | ||
403 | lock_kernel(); | 445 | lock_kernel(); |
404 | 446 | ||
405 | UFSD(("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment)) | 447 | UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); |
406 | if (fragment < 0) | 448 | if (fragment < 0) |
407 | goto abort_negative; | 449 | goto abort_negative; |
408 | if (fragment > | 450 | if (fragment > |
@@ -418,15 +460,15 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
418 | * it much more readable: | 460 | * it much more readable: |
419 | */ | 461 | */ |
420 | #define GET_INODE_DATABLOCK(x) \ | 462 | #define GET_INODE_DATABLOCK(x) \ |
421 | ufs_inode_getfrag(inode, x, fragment, 1, &err, 0, &phys, &new) | 463 | ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page) |
422 | #define GET_INODE_PTR(x) \ | 464 | #define GET_INODE_PTR(x) \ |
423 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, 1, NULL, NULL) | 465 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, bh_result->b_page) |
424 | #define GET_INDIRECT_DATABLOCK(x) \ | 466 | #define GET_INDIRECT_DATABLOCK(x) \ |
425 | ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ | 467 | ufs_inode_getblock(inode, bh, x, fragment, \ |
426 | &err, 0, &phys, &new); | 468 | &err, &phys, &new, bh_result->b_page); |
427 | #define GET_INDIRECT_PTR(x) \ | 469 | #define GET_INDIRECT_PTR(x) \ |
428 | ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ | 470 | ufs_inode_getblock(inode, bh, x, fragment, \ |
429 | &err, 1, NULL, NULL); | 471 | &err, NULL, NULL, bh_result->b_page); |
430 | 472 | ||
431 | if (ptr < UFS_NDIR_FRAGMENT) { | 473 | if (ptr < UFS_NDIR_FRAGMENT) { |
432 | bh = GET_INODE_DATABLOCK(ptr); | 474 | bh = GET_INODE_DATABLOCK(ptr); |
@@ -474,8 +516,9 @@ abort_too_big: | |||
474 | goto abort; | 516 | goto abort; |
475 | } | 517 | } |
476 | 518 | ||
477 | struct buffer_head *ufs_getfrag(struct inode *inode, unsigned int fragment, | 519 | static struct buffer_head *ufs_getfrag(struct inode *inode, |
478 | int create, int *err) | 520 | unsigned int fragment, |
521 | int create, int *err) | ||
479 | { | 522 | { |
480 | struct buffer_head dummy; | 523 | struct buffer_head dummy; |
481 | int error; | 524 | int error; |
@@ -502,7 +545,7 @@ struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment, | |||
502 | { | 545 | { |
503 | struct buffer_head * bh; | 546 | struct buffer_head * bh; |
504 | 547 | ||
505 | UFSD(("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment)) | 548 | UFSD("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment); |
506 | bh = ufs_getfrag (inode, fragment, create, err); | 549 | bh = ufs_getfrag (inode, fragment, create, err); |
507 | if (!bh || buffer_uptodate(bh)) | 550 | if (!bh || buffer_uptodate(bh)) |
508 | return bh; | 551 | return bh; |
@@ -540,6 +583,28 @@ struct address_space_operations ufs_aops = { | |||
540 | .bmap = ufs_bmap | 583 | .bmap = ufs_bmap |
541 | }; | 584 | }; |
542 | 585 | ||
586 | static void ufs_set_inode_ops(struct inode *inode) | ||
587 | { | ||
588 | if (S_ISREG(inode->i_mode)) { | ||
589 | inode->i_op = &ufs_file_inode_operations; | ||
590 | inode->i_fop = &ufs_file_operations; | ||
591 | inode->i_mapping->a_ops = &ufs_aops; | ||
592 | } else if (S_ISDIR(inode->i_mode)) { | ||
593 | inode->i_op = &ufs_dir_inode_operations; | ||
594 | inode->i_fop = &ufs_dir_operations; | ||
595 | inode->i_mapping->a_ops = &ufs_aops; | ||
596 | } else if (S_ISLNK(inode->i_mode)) { | ||
597 | if (!inode->i_blocks) | ||
598 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
599 | else { | ||
600 | inode->i_op = &page_symlink_inode_operations; | ||
601 | inode->i_mapping->a_ops = &ufs_aops; | ||
602 | } | ||
603 | } else | ||
604 | init_special_inode(inode, inode->i_mode, | ||
605 | ufs_get_inode_dev(inode->i_sb, UFS_I(inode))); | ||
606 | } | ||
607 | |||
543 | void ufs_read_inode (struct inode * inode) | 608 | void ufs_read_inode (struct inode * inode) |
544 | { | 609 | { |
545 | struct ufs_inode_info *ufsi = UFS_I(inode); | 610 | struct ufs_inode_info *ufsi = UFS_I(inode); |
@@ -552,7 +617,7 @@ void ufs_read_inode (struct inode * inode) | |||
552 | unsigned i; | 617 | unsigned i; |
553 | unsigned flags; | 618 | unsigned flags; |
554 | 619 | ||
555 | UFSD(("ENTER, ino %lu\n", inode->i_ino)) | 620 | UFSD("ENTER, ino %lu\n", inode->i_ino); |
556 | 621 | ||
557 | sb = inode->i_sb; | 622 | sb = inode->i_sb; |
558 | uspi = UFS_SB(sb)->s_uspi; | 623 | uspi = UFS_SB(sb)->s_uspi; |
@@ -603,38 +668,22 @@ void ufs_read_inode (struct inode * inode) | |||
603 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); | 668 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); |
604 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); | 669 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); |
605 | ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; | 670 | ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; |
671 | ufsi->i_dir_start_lookup = 0; | ||
606 | 672 | ||
607 | if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { | 673 | if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { |
608 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) | 674 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) |
609 | ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i]; | 675 | ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i]; |
610 | } | 676 | } else { |
611 | else { | ||
612 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) | 677 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) |
613 | ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i]; | 678 | ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i]; |
614 | } | 679 | } |
615 | ufsi->i_osync = 0; | 680 | ufsi->i_osync = 0; |
616 | 681 | ||
617 | if (S_ISREG(inode->i_mode)) { | 682 | ufs_set_inode_ops(inode); |
618 | inode->i_op = &ufs_file_inode_operations; | ||
619 | inode->i_fop = &ufs_file_operations; | ||
620 | inode->i_mapping->a_ops = &ufs_aops; | ||
621 | } else if (S_ISDIR(inode->i_mode)) { | ||
622 | inode->i_op = &ufs_dir_inode_operations; | ||
623 | inode->i_fop = &ufs_dir_operations; | ||
624 | } else if (S_ISLNK(inode->i_mode)) { | ||
625 | if (!inode->i_blocks) | ||
626 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
627 | else { | ||
628 | inode->i_op = &page_symlink_inode_operations; | ||
629 | inode->i_mapping->a_ops = &ufs_aops; | ||
630 | } | ||
631 | } else | ||
632 | init_special_inode(inode, inode->i_mode, | ||
633 | ufs_get_inode_dev(sb, ufsi)); | ||
634 | 683 | ||
635 | brelse (bh); | 684 | brelse (bh); |
636 | 685 | ||
637 | UFSD(("EXIT\n")) | 686 | UFSD("EXIT\n"); |
638 | return; | 687 | return; |
639 | 688 | ||
640 | bad_inode: | 689 | bad_inode: |
@@ -642,7 +691,7 @@ bad_inode: | |||
642 | return; | 691 | return; |
643 | 692 | ||
644 | ufs2_inode : | 693 | ufs2_inode : |
645 | UFSD(("Reading ufs2 inode, ino %lu\n", inode->i_ino)) | 694 | UFSD("Reading ufs2 inode, ino %lu\n", inode->i_ino); |
646 | 695 | ||
647 | ufs2_inode = (struct ufs2_inode *)(bh->b_data + sizeof(struct ufs2_inode) * ufs_inotofsbo(inode->i_ino)); | 696 | ufs2_inode = (struct ufs2_inode *)(bh->b_data + sizeof(struct ufs2_inode) * ufs_inotofsbo(inode->i_ino)); |
648 | 697 | ||
@@ -690,27 +739,11 @@ ufs2_inode : | |||
690 | } | 739 | } |
691 | ufsi->i_osync = 0; | 740 | ufsi->i_osync = 0; |
692 | 741 | ||
693 | if (S_ISREG(inode->i_mode)) { | 742 | ufs_set_inode_ops(inode); |
694 | inode->i_op = &ufs_file_inode_operations; | ||
695 | inode->i_fop = &ufs_file_operations; | ||
696 | inode->i_mapping->a_ops = &ufs_aops; | ||
697 | } else if (S_ISDIR(inode->i_mode)) { | ||
698 | inode->i_op = &ufs_dir_inode_operations; | ||
699 | inode->i_fop = &ufs_dir_operations; | ||
700 | } else if (S_ISLNK(inode->i_mode)) { | ||
701 | if (!inode->i_blocks) | ||
702 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
703 | else { | ||
704 | inode->i_op = &page_symlink_inode_operations; | ||
705 | inode->i_mapping->a_ops = &ufs_aops; | ||
706 | } | ||
707 | } else /* TODO : here ...*/ | ||
708 | init_special_inode(inode, inode->i_mode, | ||
709 | ufs_get_inode_dev(sb, ufsi)); | ||
710 | 743 | ||
711 | brelse(bh); | 744 | brelse(bh); |
712 | 745 | ||
713 | UFSD(("EXIT\n")) | 746 | UFSD("EXIT\n"); |
714 | return; | 747 | return; |
715 | } | 748 | } |
716 | 749 | ||
@@ -724,7 +757,7 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
724 | unsigned i; | 757 | unsigned i; |
725 | unsigned flags; | 758 | unsigned flags; |
726 | 759 | ||
727 | UFSD(("ENTER, ino %lu\n", inode->i_ino)) | 760 | UFSD("ENTER, ino %lu\n", inode->i_ino); |
728 | 761 | ||
729 | sb = inode->i_sb; | 762 | sb = inode->i_sb; |
730 | uspi = UFS_SB(sb)->s_uspi; | 763 | uspi = UFS_SB(sb)->s_uspi; |
@@ -785,7 +818,7 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
785 | sync_dirty_buffer(bh); | 818 | sync_dirty_buffer(bh); |
786 | brelse (bh); | 819 | brelse (bh); |
787 | 820 | ||
788 | UFSD(("EXIT\n")) | 821 | UFSD("EXIT\n"); |
789 | return 0; | 822 | return 0; |
790 | } | 823 | } |
791 | 824 | ||