diff options
Diffstat (limited to 'fs/ocfs2/inode.c')
-rw-r--r-- | fs/ocfs2/inode.c | 175 |
1 files changed, 128 insertions, 47 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 7aa00d511874..229e707bc050 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
31 | #include <linux/quotaops.h> | ||
31 | 32 | ||
32 | #include <asm/byteorder.h> | 33 | #include <asm/byteorder.h> |
33 | 34 | ||
@@ -37,6 +38,7 @@ | |||
37 | #include "ocfs2.h" | 38 | #include "ocfs2.h" |
38 | 39 | ||
39 | #include "alloc.h" | 40 | #include "alloc.h" |
41 | #include "blockcheck.h" | ||
40 | #include "dlmglue.h" | 42 | #include "dlmglue.h" |
41 | #include "extent_map.h" | 43 | #include "extent_map.h" |
42 | #include "file.h" | 44 | #include "file.h" |
@@ -214,12 +216,11 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque) | |||
214 | return 0; | 216 | return 0; |
215 | } | 217 | } |
216 | 218 | ||
217 | int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | 219 | void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, |
218 | int create_ino) | 220 | int create_ino) |
219 | { | 221 | { |
220 | struct super_block *sb; | 222 | struct super_block *sb; |
221 | struct ocfs2_super *osb; | 223 | struct ocfs2_super *osb; |
222 | int status = -EINVAL; | ||
223 | int use_plocks = 1; | 224 | int use_plocks = 1; |
224 | 225 | ||
225 | mlog_entry("(0x%p, size:%llu)\n", inode, | 226 | mlog_entry("(0x%p, size:%llu)\n", inode, |
@@ -232,25 +233,17 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
232 | ocfs2_mount_local(osb) || !ocfs2_stack_supports_plocks()) | 233 | ocfs2_mount_local(osb) || !ocfs2_stack_supports_plocks()) |
233 | use_plocks = 0; | 234 | use_plocks = 0; |
234 | 235 | ||
235 | /* this means that read_inode cannot create a superblock inode | 236 | /* |
236 | * today. change if needed. */ | 237 | * These have all been checked by ocfs2_read_inode_block() or set |
237 | if (!OCFS2_IS_VALID_DINODE(fe) || | 238 | * by ocfs2_mknod_locked(), so a failure is a code bug. |
238 | !(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) { | 239 | */ |
239 | mlog(0, "Invalid dinode: i_ino=%lu, i_blkno=%llu, " | 240 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); /* This means that read_inode |
240 | "signature = %.*s, flags = 0x%x\n", | 241 | cannot create a superblock |
241 | inode->i_ino, | 242 | inode today. change if |
242 | (unsigned long long)le64_to_cpu(fe->i_blkno), 7, | 243 | that is needed. */ |
243 | fe->i_signature, le32_to_cpu(fe->i_flags)); | 244 | BUG_ON(!(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))); |
244 | goto bail; | 245 | BUG_ON(le32_to_cpu(fe->i_fs_generation) != osb->fs_generation); |
245 | } | ||
246 | 246 | ||
247 | if (le32_to_cpu(fe->i_fs_generation) != osb->fs_generation) { | ||
248 | mlog(ML_ERROR, "file entry generation does not match " | ||
249 | "superblock! osb->fs_generation=%x, " | ||
250 | "fe->i_fs_generation=%x\n", | ||
251 | osb->fs_generation, le32_to_cpu(fe->i_fs_generation)); | ||
252 | goto bail; | ||
253 | } | ||
254 | 247 | ||
255 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); | 248 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); |
256 | OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); | 249 | OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); |
@@ -284,14 +277,18 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
284 | 277 | ||
285 | inode->i_nlink = le16_to_cpu(fe->i_links_count); | 278 | inode->i_nlink = le16_to_cpu(fe->i_links_count); |
286 | 279 | ||
287 | if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) | 280 | if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) { |
288 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE; | 281 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE; |
282 | inode->i_flags |= S_NOQUOTA; | ||
283 | } | ||
289 | 284 | ||
290 | if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) { | 285 | if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) { |
291 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; | 286 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; |
292 | mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino); | 287 | mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino); |
293 | } else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) { | 288 | } else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) { |
294 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; | 289 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; |
290 | } else if (fe->i_flags & cpu_to_le32(OCFS2_QUOTA_FL)) { | ||
291 | inode->i_flags |= S_NOQUOTA; | ||
295 | } else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) { | 292 | } else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) { |
296 | mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino); | 293 | mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino); |
297 | /* we can't actually hit this as read_inode can't | 294 | /* we can't actually hit this as read_inode can't |
@@ -354,10 +351,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
354 | 351 | ||
355 | ocfs2_set_inode_flags(inode); | 352 | ocfs2_set_inode_flags(inode); |
356 | 353 | ||
357 | status = 0; | 354 | mlog_exit_void(); |
358 | bail: | ||
359 | mlog_exit(status); | ||
360 | return status; | ||
361 | } | 355 | } |
362 | 356 | ||
363 | static int ocfs2_read_locked_inode(struct inode *inode, | 357 | static int ocfs2_read_locked_inode(struct inode *inode, |
@@ -460,11 +454,14 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
460 | } | 454 | } |
461 | } | 455 | } |
462 | 456 | ||
463 | if (can_lock) | 457 | if (can_lock) { |
464 | status = ocfs2_read_blocks(inode, args->fi_blkno, 1, &bh, | 458 | status = ocfs2_read_inode_block_full(inode, &bh, |
465 | OCFS2_BH_IGNORE_CACHE); | 459 | OCFS2_BH_IGNORE_CACHE); |
466 | else | 460 | } else { |
467 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); | 461 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); |
462 | if (!status) | ||
463 | status = ocfs2_validate_inode_block(osb->sb, bh); | ||
464 | } | ||
468 | if (status < 0) { | 465 | if (status < 0) { |
469 | mlog_errno(status); | 466 | mlog_errno(status); |
470 | goto bail; | 467 | goto bail; |
@@ -472,12 +469,6 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
472 | 469 | ||
473 | status = -EINVAL; | 470 | status = -EINVAL; |
474 | fe = (struct ocfs2_dinode *) bh->b_data; | 471 | fe = (struct ocfs2_dinode *) bh->b_data; |
475 | if (!OCFS2_IS_VALID_DINODE(fe)) { | ||
476 | mlog(0, "Invalid dinode #%llu: signature = %.*s\n", | ||
477 | (unsigned long long)args->fi_blkno, 7, | ||
478 | fe->i_signature); | ||
479 | goto bail; | ||
480 | } | ||
481 | 472 | ||
482 | /* | 473 | /* |
483 | * This is a code bug. Right now the caller needs to | 474 | * This is a code bug. Right now the caller needs to |
@@ -491,10 +482,9 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
491 | 482 | ||
492 | if (S_ISCHR(le16_to_cpu(fe->i_mode)) || | 483 | if (S_ISCHR(le16_to_cpu(fe->i_mode)) || |
493 | S_ISBLK(le16_to_cpu(fe->i_mode))) | 484 | S_ISBLK(le16_to_cpu(fe->i_mode))) |
494 | inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); | 485 | inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); |
495 | 486 | ||
496 | if (ocfs2_populate_inode(inode, fe, 0) < 0) | 487 | ocfs2_populate_inode(inode, fe, 0); |
497 | goto bail; | ||
498 | 488 | ||
499 | BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno)); | 489 | BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno)); |
500 | 490 | ||
@@ -547,8 +537,8 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
547 | goto out; | 537 | goto out; |
548 | } | 538 | } |
549 | 539 | ||
550 | status = ocfs2_journal_access(handle, inode, fe_bh, | 540 | status = ocfs2_journal_access_di(handle, inode, fe_bh, |
551 | OCFS2_JOURNAL_ACCESS_WRITE); | 541 | OCFS2_JOURNAL_ACCESS_WRITE); |
552 | if (status < 0) { | 542 | if (status < 0) { |
553 | mlog_errno(status); | 543 | mlog_errno(status); |
554 | goto out; | 544 | goto out; |
@@ -615,7 +605,8 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
615 | goto bail; | 605 | goto bail; |
616 | } | 606 | } |
617 | 607 | ||
618 | handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS); | 608 | handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS + |
609 | ocfs2_quota_trans_credits(inode->i_sb)); | ||
619 | if (IS_ERR(handle)) { | 610 | if (IS_ERR(handle)) { |
620 | status = PTR_ERR(handle); | 611 | status = PTR_ERR(handle); |
621 | mlog_errno(status); | 612 | mlog_errno(status); |
@@ -630,8 +621,8 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
630 | } | 621 | } |
631 | 622 | ||
632 | /* set the inodes dtime */ | 623 | /* set the inodes dtime */ |
633 | status = ocfs2_journal_access(handle, inode, di_bh, | 624 | status = ocfs2_journal_access_di(handle, inode, di_bh, |
634 | OCFS2_JOURNAL_ACCESS_WRITE); | 625 | OCFS2_JOURNAL_ACCESS_WRITE); |
635 | if (status < 0) { | 626 | if (status < 0) { |
636 | mlog_errno(status); | 627 | mlog_errno(status); |
637 | goto bail_commit; | 628 | goto bail_commit; |
@@ -647,6 +638,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
647 | } | 638 | } |
648 | 639 | ||
649 | ocfs2_remove_from_cache(inode, di_bh); | 640 | ocfs2_remove_from_cache(inode, di_bh); |
641 | vfs_dq_free_inode(inode); | ||
650 | 642 | ||
651 | status = ocfs2_free_dinode(handle, inode_alloc_inode, | 643 | status = ocfs2_free_dinode(handle, inode_alloc_inode, |
652 | inode_alloc_bh, di); | 644 | inode_alloc_bh, di); |
@@ -929,7 +921,10 @@ void ocfs2_delete_inode(struct inode *inode) | |||
929 | 921 | ||
930 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 922 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
931 | 923 | ||
932 | if (is_bad_inode(inode)) { | 924 | /* When we fail in read_inode() we mark inode as bad. The second test |
925 | * catches the case when inode allocation fails before allocating | ||
926 | * a block for inode. */ | ||
927 | if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) { | ||
933 | mlog(0, "Skipping delete of bad inode\n"); | 928 | mlog(0, "Skipping delete of bad inode\n"); |
934 | goto bail; | 929 | goto bail; |
935 | } | 930 | } |
@@ -1195,8 +1190,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle, | |||
1195 | mlog_entry("(inode %llu)\n", | 1190 | mlog_entry("(inode %llu)\n", |
1196 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 1191 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
1197 | 1192 | ||
1198 | status = ocfs2_journal_access(handle, inode, bh, | 1193 | status = ocfs2_journal_access_di(handle, inode, bh, |
1199 | OCFS2_JOURNAL_ACCESS_WRITE); | 1194 | OCFS2_JOURNAL_ACCESS_WRITE); |
1200 | if (status < 0) { | 1195 | if (status < 0) { |
1201 | mlog_errno(status); | 1196 | mlog_errno(status); |
1202 | goto leave; | 1197 | goto leave; |
@@ -1264,3 +1259,89 @@ void ocfs2_refresh_inode(struct inode *inode, | |||
1264 | 1259 | ||
1265 | spin_unlock(&OCFS2_I(inode)->ip_lock); | 1260 | spin_unlock(&OCFS2_I(inode)->ip_lock); |
1266 | } | 1261 | } |
1262 | |||
1263 | int ocfs2_validate_inode_block(struct super_block *sb, | ||
1264 | struct buffer_head *bh) | ||
1265 | { | ||
1266 | int rc; | ||
1267 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; | ||
1268 | |||
1269 | mlog(0, "Validating dinode %llu\n", | ||
1270 | (unsigned long long)bh->b_blocknr); | ||
1271 | |||
1272 | BUG_ON(!buffer_uptodate(bh)); | ||
1273 | |||
1274 | /* | ||
1275 | * If the ecc fails, we return the error but otherwise | ||
1276 | * leave the filesystem running. We know any error is | ||
1277 | * local to this block. | ||
1278 | */ | ||
1279 | rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check); | ||
1280 | if (rc) { | ||
1281 | mlog(ML_ERROR, "Checksum failed for dinode %llu\n", | ||
1282 | (unsigned long long)bh->b_blocknr); | ||
1283 | goto bail; | ||
1284 | } | ||
1285 | |||
1286 | /* | ||
1287 | * Errors after here are fatal. | ||
1288 | */ | ||
1289 | |||
1290 | rc = -EINVAL; | ||
1291 | |||
1292 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
1293 | ocfs2_error(sb, "Invalid dinode #%llu: signature = %.*s\n", | ||
1294 | (unsigned long long)bh->b_blocknr, 7, | ||
1295 | di->i_signature); | ||
1296 | goto bail; | ||
1297 | } | ||
1298 | |||
1299 | if (le64_to_cpu(di->i_blkno) != bh->b_blocknr) { | ||
1300 | ocfs2_error(sb, "Invalid dinode #%llu: i_blkno is %llu\n", | ||
1301 | (unsigned long long)bh->b_blocknr, | ||
1302 | (unsigned long long)le64_to_cpu(di->i_blkno)); | ||
1303 | goto bail; | ||
1304 | } | ||
1305 | |||
1306 | if (!(di->i_flags & cpu_to_le32(OCFS2_VALID_FL))) { | ||
1307 | ocfs2_error(sb, | ||
1308 | "Invalid dinode #%llu: OCFS2_VALID_FL not set\n", | ||
1309 | (unsigned long long)bh->b_blocknr); | ||
1310 | goto bail; | ||
1311 | } | ||
1312 | |||
1313 | if (le32_to_cpu(di->i_fs_generation) != | ||
1314 | OCFS2_SB(sb)->fs_generation) { | ||
1315 | ocfs2_error(sb, | ||
1316 | "Invalid dinode #%llu: fs_generation is %u\n", | ||
1317 | (unsigned long long)bh->b_blocknr, | ||
1318 | le32_to_cpu(di->i_fs_generation)); | ||
1319 | goto bail; | ||
1320 | } | ||
1321 | |||
1322 | rc = 0; | ||
1323 | |||
1324 | bail: | ||
1325 | return rc; | ||
1326 | } | ||
1327 | |||
1328 | int ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh, | ||
1329 | int flags) | ||
1330 | { | ||
1331 | int rc; | ||
1332 | struct buffer_head *tmp = *bh; | ||
1333 | |||
1334 | rc = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, &tmp, | ||
1335 | flags, ocfs2_validate_inode_block); | ||
1336 | |||
1337 | /* If ocfs2_read_blocks() got us a new bh, pass it up. */ | ||
1338 | if (!rc && !*bh) | ||
1339 | *bh = tmp; | ||
1340 | |||
1341 | return rc; | ||
1342 | } | ||
1343 | |||
1344 | int ocfs2_read_inode_block(struct inode *inode, struct buffer_head **bh) | ||
1345 | { | ||
1346 | return ocfs2_read_inode_block_full(inode, bh, 0); | ||
1347 | } | ||