diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-11-08 15:28:05 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-11-08 15:28:05 -0500 |
commit | bad97817dece759dd6c0b24f862b7d0ed588edda (patch) | |
tree | fcabaa3ae3e2f17236135e60dc875f47e852cc6d /fs/xfs | |
parent | 6fe19278ffebdd57e5c5ec10275e6d423404364e (diff) | |
parent | 61e6cfa80de5760bbe406f4e815b7739205754d2 (diff) |
Merge tag 'v3.12-rc5' into stable/for-linus-3.13
Linux 3.12-rc5
Because the Stefano branch (for SWIOTLB ARM changes) is based on that.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
* tag 'v3.12-rc5': (550 commits)
Linux 3.12-rc5
watchdog: sunxi: Fix section mismatch
watchdog: kempld_wdt: Fix bit mask definition
watchdog: ts72xx_wdt: locking bug in ioctl
ARM: exynos: dts: Update 5250 arch timer node with clock frequency
parisc: let probe_kernel_read() capture access to page zero
parisc: optimize variable initialization in do_page_fault
parisc: fix interruption handler to respect pagefault_disable()
parisc: mark parisc_terminate() noreturn and cold.
parisc: remove unused syscall_ipi() function.
parisc: kill SMP single function call interrupt
parisc: Export flush_cache_page() (needed by lustre)
vfs: allow O_PATH file descriptors for fstatfs()
ext4: fix memory leak in xattr
ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc"
ALSA: hda - Sony VAIO Pro 13 (haswell) now has a working headset jack
ALSA: hda - Add a headset mic model for ALC269 and friends
ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model)
compiler/gcc4: Add quirk for 'asm goto' miscompilation bug
Revert "i915: Update VGA arbiter support for newer devices"
...
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_block.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_format.h | 51 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_readdir.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_sf.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.c | 19 | ||||
-rw-r--r-- | fs/xfs/xfs_fs.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 74 |
10 files changed, 113 insertions, 64 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 88c5ea75ebf6..f1d85cfc0a54 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -628,6 +628,7 @@ xfs_buf_item_unlock( | |||
628 | else if (aborted) { | 628 | else if (aborted) { |
629 | ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); | 629 | ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); |
630 | if (lip->li_flags & XFS_LI_IN_AIL) { | 630 | if (lip->li_flags & XFS_LI_IN_AIL) { |
631 | spin_lock(&lip->li_ailp->xa_lock); | ||
631 | xfs_trans_ail_delete(lip->li_ailp, lip, | 632 | xfs_trans_ail_delete(lip->li_ailp, lip, |
632 | SHUTDOWN_LOG_IO_ERROR); | 633 | SHUTDOWN_LOG_IO_ERROR); |
633 | } | 634 | } |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 069537c845e5..20bf8e8002d6 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1224,6 +1224,7 @@ xfs_da3_node_toosmall( | |||
1224 | /* start with smaller blk num */ | 1224 | /* start with smaller blk num */ |
1225 | forward = nodehdr.forw < nodehdr.back; | 1225 | forward = nodehdr.forw < nodehdr.back; |
1226 | for (i = 0; i < 2; forward = !forward, i++) { | 1226 | for (i = 0; i < 2; forward = !forward, i++) { |
1227 | struct xfs_da3_icnode_hdr thdr; | ||
1227 | if (forward) | 1228 | if (forward) |
1228 | blkno = nodehdr.forw; | 1229 | blkno = nodehdr.forw; |
1229 | else | 1230 | else |
@@ -1236,10 +1237,10 @@ xfs_da3_node_toosmall( | |||
1236 | return(error); | 1237 | return(error); |
1237 | 1238 | ||
1238 | node = bp->b_addr; | 1239 | node = bp->b_addr; |
1239 | xfs_da3_node_hdr_from_disk(&nodehdr, node); | 1240 | xfs_da3_node_hdr_from_disk(&thdr, node); |
1240 | xfs_trans_brelse(state->args->trans, bp); | 1241 | xfs_trans_brelse(state->args->trans, bp); |
1241 | 1242 | ||
1242 | if (count - nodehdr.count >= 0) | 1243 | if (count - thdr.count >= 0) |
1243 | break; /* fits with at least 25% to spare */ | 1244 | break; /* fits with at least 25% to spare */ |
1244 | } | 1245 | } |
1245 | if (i >= 2) { | 1246 | if (i >= 2) { |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 0957aa98b6c0..12dad188939d 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -1158,7 +1158,7 @@ xfs_dir2_sf_to_block( | |||
1158 | /* | 1158 | /* |
1159 | * Create entry for . | 1159 | * Create entry for . |
1160 | */ | 1160 | */ |
1161 | dep = xfs_dir3_data_dot_entry_p(hdr); | 1161 | dep = xfs_dir3_data_dot_entry_p(mp, hdr); |
1162 | dep->inumber = cpu_to_be64(dp->i_ino); | 1162 | dep->inumber = cpu_to_be64(dp->i_ino); |
1163 | dep->namelen = 1; | 1163 | dep->namelen = 1; |
1164 | dep->name[0] = '.'; | 1164 | dep->name[0] = '.'; |
@@ -1172,7 +1172,7 @@ xfs_dir2_sf_to_block( | |||
1172 | /* | 1172 | /* |
1173 | * Create entry for .. | 1173 | * Create entry for .. |
1174 | */ | 1174 | */ |
1175 | dep = xfs_dir3_data_dotdot_entry_p(hdr); | 1175 | dep = xfs_dir3_data_dotdot_entry_p(mp, hdr); |
1176 | dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); | 1176 | dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); |
1177 | dep->namelen = 2; | 1177 | dep->namelen = 2; |
1178 | dep->name[0] = dep->name[1] = '.'; | 1178 | dep->name[0] = dep->name[1] = '.'; |
@@ -1183,7 +1183,7 @@ xfs_dir2_sf_to_block( | |||
1183 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); | 1183 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); |
1184 | blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, | 1184 | blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, |
1185 | (char *)dep - (char *)hdr)); | 1185 | (char *)dep - (char *)hdr)); |
1186 | offset = xfs_dir3_data_first_offset(hdr); | 1186 | offset = xfs_dir3_data_first_offset(mp); |
1187 | /* | 1187 | /* |
1188 | * Loop over existing entries, stuff them in. | 1188 | * Loop over existing entries, stuff them in. |
1189 | */ | 1189 | */ |
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h index a0961a61ac1a..9cf67381adf6 100644 --- a/fs/xfs/xfs_dir2_format.h +++ b/fs/xfs/xfs_dir2_format.h | |||
@@ -497,69 +497,58 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) | |||
497 | /* | 497 | /* |
498 | * Offsets of . and .. in data space (always block 0) | 498 | * Offsets of . and .. in data space (always block 0) |
499 | * | 499 | * |
500 | * The macros are used for shortform directories as they have no headers to read | ||
501 | * the magic number out of. Shortform directories need to know the size of the | ||
502 | * data block header because the sfe embeds the block offset of the entry into | ||
503 | * it so that it doesn't change when format conversion occurs. Bad Things Happen | ||
504 | * if we don't follow this rule. | ||
505 | * | ||
506 | * XXX: there is scope for significant optimisation of the logic here. Right | 500 | * XXX: there is scope for significant optimisation of the logic here. Right |
507 | * now we are checking for "dir3 format" over and over again. Ideally we should | 501 | * now we are checking for "dir3 format" over and over again. Ideally we should |
508 | * only do it once for each operation. | 502 | * only do it once for each operation. |
509 | */ | 503 | */ |
510 | #define XFS_DIR3_DATA_DOT_OFFSET(mp) \ | ||
511 | xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb)) | ||
512 | #define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \ | ||
513 | (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 1)) | ||
514 | #define XFS_DIR3_DATA_FIRST_OFFSET(mp) \ | ||
515 | (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 2)) | ||
516 | |||
517 | static inline xfs_dir2_data_aoff_t | 504 | static inline xfs_dir2_data_aoff_t |
518 | xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr) | 505 | xfs_dir3_data_dot_offset(struct xfs_mount *mp) |
519 | { | 506 | { |
520 | return xfs_dir3_data_entry_offset(hdr); | 507 | return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)); |
521 | } | 508 | } |
522 | 509 | ||
523 | static inline xfs_dir2_data_aoff_t | 510 | static inline xfs_dir2_data_aoff_t |
524 | xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr) | 511 | xfs_dir3_data_dotdot_offset(struct xfs_mount *mp) |
525 | { | 512 | { |
526 | bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || | 513 | return xfs_dir3_data_dot_offset(mp) + |
527 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); | 514 | xfs_dir3_data_entsize(mp, 1); |
528 | return xfs_dir3_data_dot_offset(hdr) + | ||
529 | __xfs_dir3_data_entsize(dir3, 1); | ||
530 | } | 515 | } |
531 | 516 | ||
532 | static inline xfs_dir2_data_aoff_t | 517 | static inline xfs_dir2_data_aoff_t |
533 | xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr) | 518 | xfs_dir3_data_first_offset(struct xfs_mount *mp) |
534 | { | 519 | { |
535 | bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || | 520 | return xfs_dir3_data_dotdot_offset(mp) + |
536 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); | 521 | xfs_dir3_data_entsize(mp, 2); |
537 | return xfs_dir3_data_dotdot_offset(hdr) + | ||
538 | __xfs_dir3_data_entsize(dir3, 2); | ||
539 | } | 522 | } |
540 | 523 | ||
541 | /* | 524 | /* |
542 | * location of . and .. in data space (always block 0) | 525 | * location of . and .. in data space (always block 0) |
543 | */ | 526 | */ |
544 | static inline struct xfs_dir2_data_entry * | 527 | static inline struct xfs_dir2_data_entry * |
545 | xfs_dir3_data_dot_entry_p(struct xfs_dir2_data_hdr *hdr) | 528 | xfs_dir3_data_dot_entry_p( |
529 | struct xfs_mount *mp, | ||
530 | struct xfs_dir2_data_hdr *hdr) | ||
546 | { | 531 | { |
547 | return (struct xfs_dir2_data_entry *) | 532 | return (struct xfs_dir2_data_entry *) |
548 | ((char *)hdr + xfs_dir3_data_dot_offset(hdr)); | 533 | ((char *)hdr + xfs_dir3_data_dot_offset(mp)); |
549 | } | 534 | } |
550 | 535 | ||
551 | static inline struct xfs_dir2_data_entry * | 536 | static inline struct xfs_dir2_data_entry * |
552 | xfs_dir3_data_dotdot_entry_p(struct xfs_dir2_data_hdr *hdr) | 537 | xfs_dir3_data_dotdot_entry_p( |
538 | struct xfs_mount *mp, | ||
539 | struct xfs_dir2_data_hdr *hdr) | ||
553 | { | 540 | { |
554 | return (struct xfs_dir2_data_entry *) | 541 | return (struct xfs_dir2_data_entry *) |
555 | ((char *)hdr + xfs_dir3_data_dotdot_offset(hdr)); | 542 | ((char *)hdr + xfs_dir3_data_dotdot_offset(mp)); |
556 | } | 543 | } |
557 | 544 | ||
558 | static inline struct xfs_dir2_data_entry * | 545 | static inline struct xfs_dir2_data_entry * |
559 | xfs_dir3_data_first_entry_p(struct xfs_dir2_data_hdr *hdr) | 546 | xfs_dir3_data_first_entry_p( |
547 | struct xfs_mount *mp, | ||
548 | struct xfs_dir2_data_hdr *hdr) | ||
560 | { | 549 | { |
561 | return (struct xfs_dir2_data_entry *) | 550 | return (struct xfs_dir2_data_entry *) |
562 | ((char *)hdr + xfs_dir3_data_first_offset(hdr)); | 551 | ((char *)hdr + xfs_dir3_data_first_offset(mp)); |
563 | } | 552 | } |
564 | 553 | ||
565 | /* | 554 | /* |
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 8993ec17452c..8f84153e98a8 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c | |||
@@ -119,9 +119,9 @@ xfs_dir2_sf_getdents( | |||
119 | * mp->m_dirdatablk. | 119 | * mp->m_dirdatablk. |
120 | */ | 120 | */ |
121 | dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 121 | dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
122 | XFS_DIR3_DATA_DOT_OFFSET(mp)); | 122 | xfs_dir3_data_dot_offset(mp)); |
123 | dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 123 | dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
124 | XFS_DIR3_DATA_DOTDOT_OFFSET(mp)); | 124 | xfs_dir3_data_dotdot_offset(mp)); |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Put . entry unless we're starting past it. | 127 | * Put . entry unless we're starting past it. |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index bb6e2848f473..3ef6d402084c 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
@@ -557,7 +557,7 @@ xfs_dir2_sf_addname_hard( | |||
557 | * to insert the new entry. | 557 | * to insert the new entry. |
558 | * If it's going to end up at the end then oldsfep will point there. | 558 | * If it's going to end up at the end then oldsfep will point there. |
559 | */ | 559 | */ |
560 | for (offset = XFS_DIR3_DATA_FIRST_OFFSET(mp), | 560 | for (offset = xfs_dir3_data_first_offset(mp), |
561 | oldsfep = xfs_dir2_sf_firstentry(oldsfp), | 561 | oldsfep = xfs_dir2_sf_firstentry(oldsfp), |
562 | add_datasize = xfs_dir3_data_entsize(mp, args->namelen), | 562 | add_datasize = xfs_dir3_data_entsize(mp, args->namelen), |
563 | eof = (char *)oldsfep == &buf[old_isize]; | 563 | eof = (char *)oldsfep == &buf[old_isize]; |
@@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick( | |||
640 | 640 | ||
641 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 641 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
642 | size = xfs_dir3_data_entsize(mp, args->namelen); | 642 | size = xfs_dir3_data_entsize(mp, args->namelen); |
643 | offset = XFS_DIR3_DATA_FIRST_OFFSET(mp); | 643 | offset = xfs_dir3_data_first_offset(mp); |
644 | sfep = xfs_dir2_sf_firstentry(sfp); | 644 | sfep = xfs_dir2_sf_firstentry(sfp); |
645 | holefit = 0; | 645 | holefit = 0; |
646 | /* | 646 | /* |
@@ -713,7 +713,7 @@ xfs_dir2_sf_check( | |||
713 | mp = dp->i_mount; | 713 | mp = dp->i_mount; |
714 | 714 | ||
715 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 715 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
716 | offset = XFS_DIR3_DATA_FIRST_OFFSET(mp); | 716 | offset = xfs_dir3_data_first_offset(mp); |
717 | ino = xfs_dir2_sf_get_parent_ino(sfp); | 717 | ino = xfs_dir2_sf_get_parent_ino(sfp); |
718 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; | 718 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; |
719 | 719 | ||
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 71520e6e5d65..1ee776d477c3 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -64,7 +64,8 @@ int xfs_dqerror_mod = 33; | |||
64 | struct kmem_zone *xfs_qm_dqtrxzone; | 64 | struct kmem_zone *xfs_qm_dqtrxzone; |
65 | static struct kmem_zone *xfs_qm_dqzone; | 65 | static struct kmem_zone *xfs_qm_dqzone; |
66 | 66 | ||
67 | static struct lock_class_key xfs_dquot_other_class; | 67 | static struct lock_class_key xfs_dquot_group_class; |
68 | static struct lock_class_key xfs_dquot_project_class; | ||
68 | 69 | ||
69 | /* | 70 | /* |
70 | * This is called to free all the memory associated with a dquot | 71 | * This is called to free all the memory associated with a dquot |
@@ -703,8 +704,20 @@ xfs_qm_dqread( | |||
703 | * Make sure group quotas have a different lock class than user | 704 | * Make sure group quotas have a different lock class than user |
704 | * quotas. | 705 | * quotas. |
705 | */ | 706 | */ |
706 | if (!(type & XFS_DQ_USER)) | 707 | switch (type) { |
707 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); | 708 | case XFS_DQ_USER: |
709 | /* uses the default lock class */ | ||
710 | break; | ||
711 | case XFS_DQ_GROUP: | ||
712 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class); | ||
713 | break; | ||
714 | case XFS_DQ_PROJ: | ||
715 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class); | ||
716 | break; | ||
717 | default: | ||
718 | ASSERT(0); | ||
719 | break; | ||
720 | } | ||
708 | 721 | ||
709 | XFS_STATS_INC(xs_qm_dquot); | 722 | XFS_STATS_INC(xs_qm_dquot); |
710 | 723 | ||
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 1edb5cc3e5f4..18272c766a50 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -515,7 +515,7 @@ typedef struct xfs_swapext | |||
515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ | 515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ |
516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) | 516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) |
517 | #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) | 517 | #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) |
518 | #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks) | 518 | #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) |
519 | 519 | ||
520 | /* | 520 | /* |
521 | * ioctl commands that replace IRIX syssgi()'s | 521 | * ioctl commands that replace IRIX syssgi()'s |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 193206ba4358..474807a401c8 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -119,11 +119,6 @@ xfs_inode_free( | |||
119 | ip->i_itemp = NULL; | 119 | ip->i_itemp = NULL; |
120 | } | 120 | } |
121 | 121 | ||
122 | /* asserts to verify all state is correct here */ | ||
123 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
124 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | ||
125 | ASSERT(!xfs_isiflocked(ip)); | ||
126 | |||
127 | /* | 122 | /* |
128 | * Because we use RCU freeing we need to ensure the inode always | 123 | * Because we use RCU freeing we need to ensure the inode always |
129 | * appears to be reclaimed with an invalid inode number when in the | 124 | * appears to be reclaimed with an invalid inode number when in the |
@@ -135,6 +130,10 @@ xfs_inode_free( | |||
135 | ip->i_ino = 0; | 130 | ip->i_ino = 0; |
136 | spin_unlock(&ip->i_flags_lock); | 131 | spin_unlock(&ip->i_flags_lock); |
137 | 132 | ||
133 | /* asserts to verify all state is correct here */ | ||
134 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
135 | ASSERT(!xfs_isiflocked(ip)); | ||
136 | |||
138 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); | 137 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); |
139 | } | 138 | } |
140 | 139 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index dabda9521b4b..39797490a1f1 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1585,6 +1585,7 @@ xlog_recover_add_to_trans( | |||
1585 | "bad number of regions (%d) in inode log format", | 1585 | "bad number of regions (%d) in inode log format", |
1586 | in_f->ilf_size); | 1586 | in_f->ilf_size); |
1587 | ASSERT(0); | 1587 | ASSERT(0); |
1588 | kmem_free(ptr); | ||
1588 | return XFS_ERROR(EIO); | 1589 | return XFS_ERROR(EIO); |
1589 | } | 1590 | } |
1590 | 1591 | ||
@@ -1970,6 +1971,13 @@ xlog_recover_do_inode_buffer( | |||
1970 | * magic number. If we don't recognise the magic number in the buffer, then | 1971 | * magic number. If we don't recognise the magic number in the buffer, then |
1971 | * return a LSN of -1 so that the caller knows it was an unrecognised block and | 1972 | * return a LSN of -1 so that the caller knows it was an unrecognised block and |
1972 | * so can recover the buffer. | 1973 | * so can recover the buffer. |
1974 | * | ||
1975 | * Note: we cannot rely solely on magic number matches to determine that the | ||
1976 | * buffer has a valid LSN - we also need to verify that it belongs to this | ||
1977 | * filesystem, so we need to extract the object's LSN and compare it to that | ||
1978 | * which we read from the superblock. If the UUIDs don't match, then we've got a | ||
1979 | * stale metadata block from an old filesystem instance that we need to recover | ||
1980 | * over the top of. | ||
1973 | */ | 1981 | */ |
1974 | static xfs_lsn_t | 1982 | static xfs_lsn_t |
1975 | xlog_recover_get_buf_lsn( | 1983 | xlog_recover_get_buf_lsn( |
@@ -1980,6 +1988,8 @@ xlog_recover_get_buf_lsn( | |||
1980 | __uint16_t magic16; | 1988 | __uint16_t magic16; |
1981 | __uint16_t magicda; | 1989 | __uint16_t magicda; |
1982 | void *blk = bp->b_addr; | 1990 | void *blk = bp->b_addr; |
1991 | uuid_t *uuid; | ||
1992 | xfs_lsn_t lsn = -1; | ||
1983 | 1993 | ||
1984 | /* v4 filesystems always recover immediately */ | 1994 | /* v4 filesystems always recover immediately */ |
1985 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | 1995 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
@@ -1992,43 +2002,79 @@ xlog_recover_get_buf_lsn( | |||
1992 | case XFS_ABTB_MAGIC: | 2002 | case XFS_ABTB_MAGIC: |
1993 | case XFS_ABTC_MAGIC: | 2003 | case XFS_ABTC_MAGIC: |
1994 | case XFS_IBT_CRC_MAGIC: | 2004 | case XFS_IBT_CRC_MAGIC: |
1995 | case XFS_IBT_MAGIC: | 2005 | case XFS_IBT_MAGIC: { |
1996 | return be64_to_cpu( | 2006 | struct xfs_btree_block *btb = blk; |
1997 | ((struct xfs_btree_block *)blk)->bb_u.s.bb_lsn); | 2007 | |
2008 | lsn = be64_to_cpu(btb->bb_u.s.bb_lsn); | ||
2009 | uuid = &btb->bb_u.s.bb_uuid; | ||
2010 | break; | ||
2011 | } | ||
1998 | case XFS_BMAP_CRC_MAGIC: | 2012 | case XFS_BMAP_CRC_MAGIC: |
1999 | case XFS_BMAP_MAGIC: | 2013 | case XFS_BMAP_MAGIC: { |
2000 | return be64_to_cpu( | 2014 | struct xfs_btree_block *btb = blk; |
2001 | ((struct xfs_btree_block *)blk)->bb_u.l.bb_lsn); | 2015 | |
2016 | lsn = be64_to_cpu(btb->bb_u.l.bb_lsn); | ||
2017 | uuid = &btb->bb_u.l.bb_uuid; | ||
2018 | break; | ||
2019 | } | ||
2002 | case XFS_AGF_MAGIC: | 2020 | case XFS_AGF_MAGIC: |
2003 | return be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn); | 2021 | lsn = be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn); |
2022 | uuid = &((struct xfs_agf *)blk)->agf_uuid; | ||
2023 | break; | ||
2004 | case XFS_AGFL_MAGIC: | 2024 | case XFS_AGFL_MAGIC: |
2005 | return be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn); | 2025 | lsn = be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn); |
2026 | uuid = &((struct xfs_agfl *)blk)->agfl_uuid; | ||
2027 | break; | ||
2006 | case XFS_AGI_MAGIC: | 2028 | case XFS_AGI_MAGIC: |
2007 | return be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn); | 2029 | lsn = be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn); |
2030 | uuid = &((struct xfs_agi *)blk)->agi_uuid; | ||
2031 | break; | ||
2008 | case XFS_SYMLINK_MAGIC: | 2032 | case XFS_SYMLINK_MAGIC: |
2009 | return be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn); | 2033 | lsn = be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn); |
2034 | uuid = &((struct xfs_dsymlink_hdr *)blk)->sl_uuid; | ||
2035 | break; | ||
2010 | case XFS_DIR3_BLOCK_MAGIC: | 2036 | case XFS_DIR3_BLOCK_MAGIC: |
2011 | case XFS_DIR3_DATA_MAGIC: | 2037 | case XFS_DIR3_DATA_MAGIC: |
2012 | case XFS_DIR3_FREE_MAGIC: | 2038 | case XFS_DIR3_FREE_MAGIC: |
2013 | return be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn); | 2039 | lsn = be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn); |
2040 | uuid = &((struct xfs_dir3_blk_hdr *)blk)->uuid; | ||
2041 | break; | ||
2014 | case XFS_ATTR3_RMT_MAGIC: | 2042 | case XFS_ATTR3_RMT_MAGIC: |
2015 | return be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn); | 2043 | lsn = be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn); |
2044 | uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid; | ||
2045 | break; | ||
2016 | case XFS_SB_MAGIC: | 2046 | case XFS_SB_MAGIC: |
2017 | return be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); | 2047 | lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); |
2048 | uuid = &((struct xfs_dsb *)blk)->sb_uuid; | ||
2049 | break; | ||
2018 | default: | 2050 | default: |
2019 | break; | 2051 | break; |
2020 | } | 2052 | } |
2021 | 2053 | ||
2054 | if (lsn != (xfs_lsn_t)-1) { | ||
2055 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | ||
2056 | goto recover_immediately; | ||
2057 | return lsn; | ||
2058 | } | ||
2059 | |||
2022 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); | 2060 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); |
2023 | switch (magicda) { | 2061 | switch (magicda) { |
2024 | case XFS_DIR3_LEAF1_MAGIC: | 2062 | case XFS_DIR3_LEAF1_MAGIC: |
2025 | case XFS_DIR3_LEAFN_MAGIC: | 2063 | case XFS_DIR3_LEAFN_MAGIC: |
2026 | case XFS_DA3_NODE_MAGIC: | 2064 | case XFS_DA3_NODE_MAGIC: |
2027 | return be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); | 2065 | lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); |
2066 | uuid = &((struct xfs_da3_blkinfo *)blk)->uuid; | ||
2067 | break; | ||
2028 | default: | 2068 | default: |
2029 | break; | 2069 | break; |
2030 | } | 2070 | } |
2031 | 2071 | ||
2072 | if (lsn != (xfs_lsn_t)-1) { | ||
2073 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | ||
2074 | goto recover_immediately; | ||
2075 | return lsn; | ||
2076 | } | ||
2077 | |||
2032 | /* | 2078 | /* |
2033 | * We do individual object checks on dquot and inode buffers as they | 2079 | * We do individual object checks on dquot and inode buffers as they |
2034 | * have their own individual LSN records. Also, we could have a stale | 2080 | * have their own individual LSN records. Also, we could have a stale |