diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-09-19 19:21:59 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-09-19 19:21:59 -0400 |
| commit | ab048fb1aafff7883a6bbe62b5354fbc2fa5597c (patch) | |
| tree | 020842de956b7f5ce881dbcb37ce8c1a91d6654d | |
| parent | 5a0cd4eb661fea095ff9962060c21c161a9ed43f (diff) | |
| parent | 2fd6f6ec64ff347447d26646ac6188f3658b383c (diff) | |
Merge git://oss.sgi.com:8090/xfs/linux-2.6
* git://oss.sgi.com:8090/xfs/linux-2.6:
[XFS] Don't do I/O beyond eof when unreserving space
[XFS] Fix use-after-free with buffers
[XFS] Prevent lockdep false positives when locking two inodes.
[XFS] Fix barrier status change detection.
[XFS] Prevent direct I/O from mapping extents beyond eof
[XFS] Fix regression introduced by remount fixup
[XFS] Move memory allocations for log tracing out of the critical path
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 20 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf_item.c | 44 | ||||
| -rw-r--r-- | fs/xfs/xfs_dfrag.c | 9 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.c | 62 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_priv.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 26 |
7 files changed, 119 insertions, 47 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index f42f80a3b1fa..a44d68eb50b5 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -1338,6 +1338,10 @@ __xfs_get_blocks( | |||
| 1338 | offset = (xfs_off_t)iblock << inode->i_blkbits; | 1338 | offset = (xfs_off_t)iblock << inode->i_blkbits; |
| 1339 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); | 1339 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); |
| 1340 | size = bh_result->b_size; | 1340 | size = bh_result->b_size; |
| 1341 | |||
| 1342 | if (!create && direct && offset >= i_size_read(inode)) | ||
| 1343 | return 0; | ||
| 1344 | |||
| 1341 | error = xfs_iomap(XFS_I(inode), offset, size, | 1345 | error = xfs_iomap(XFS_I(inode), offset, size, |
| 1342 | create ? flags : BMAPI_READ, &iomap, &niomap); | 1346 | create ? flags : BMAPI_READ, &iomap, &niomap); |
| 1343 | if (error) | 1347 | if (error) |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 73c65f19e549..18d3c8487835 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -1302,9 +1302,29 @@ xfs_fs_remount( | |||
| 1302 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1302 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
| 1303 | break; | 1303 | break; |
| 1304 | default: | 1304 | default: |
| 1305 | /* | ||
| 1306 | * Logically we would return an error here to prevent | ||
| 1307 | * users from believing they might have changed | ||
| 1308 | * mount options using remount which can't be changed. | ||
| 1309 | * | ||
| 1310 | * But unfortunately mount(8) adds all options from | ||
| 1311 | * mtab and fstab to the mount arguments in some cases | ||
| 1312 | * so we can't blindly reject options, but have to | ||
| 1313 | * check for each specified option if it actually | ||
| 1314 | * differs from the currently set option and only | ||
| 1315 | * reject it if that's the case. | ||
| 1316 | * | ||
| 1317 | * Until that is implemented we return success for | ||
| 1318 | * every remount request, and silently ignore all | ||
| 1319 | * options that we can't actually change. | ||
| 1320 | */ | ||
| 1321 | #if 0 | ||
| 1305 | printk(KERN_INFO | 1322 | printk(KERN_INFO |
| 1306 | "XFS: mount option \"%s\" not supported for remount\n", p); | 1323 | "XFS: mount option \"%s\" not supported for remount\n", p); |
| 1307 | return -EINVAL; | 1324 | return -EINVAL; |
| 1325 | #else | ||
| 1326 | return 0; | ||
| 1327 | #endif | ||
| 1308 | } | 1328 | } |
| 1309 | } | 1329 | } |
| 1310 | 1330 | ||
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 608c30c3f76b..002fc2617c8e 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -732,6 +732,7 @@ xfs_buf_item_init( | |||
| 732 | bip->bli_item.li_ops = &xfs_buf_item_ops; | 732 | bip->bli_item.li_ops = &xfs_buf_item_ops; |
| 733 | bip->bli_item.li_mountp = mp; | 733 | bip->bli_item.li_mountp = mp; |
| 734 | bip->bli_buf = bp; | 734 | bip->bli_buf = bp; |
| 735 | xfs_buf_hold(bp); | ||
| 735 | bip->bli_format.blf_type = XFS_LI_BUF; | 736 | bip->bli_format.blf_type = XFS_LI_BUF; |
| 736 | bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); | 737 | bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); |
| 737 | bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); | 738 | bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); |
| @@ -867,6 +868,21 @@ xfs_buf_item_dirty( | |||
| 867 | return (bip->bli_flags & XFS_BLI_DIRTY); | 868 | return (bip->bli_flags & XFS_BLI_DIRTY); |
| 868 | } | 869 | } |
| 869 | 870 | ||
| 871 | STATIC void | ||
| 872 | xfs_buf_item_free( | ||
| 873 | xfs_buf_log_item_t *bip) | ||
| 874 | { | ||
| 875 | #ifdef XFS_TRANS_DEBUG | ||
| 876 | kmem_free(bip->bli_orig); | ||
| 877 | kmem_free(bip->bli_logged); | ||
| 878 | #endif /* XFS_TRANS_DEBUG */ | ||
| 879 | |||
| 880 | #ifdef XFS_BLI_TRACE | ||
| 881 | ktrace_free(bip->bli_trace); | ||
| 882 | #endif | ||
| 883 | kmem_zone_free(xfs_buf_item_zone, bip); | ||
| 884 | } | ||
| 885 | |||
| 870 | /* | 886 | /* |
| 871 | * This is called when the buf log item is no longer needed. It should | 887 | * This is called when the buf log item is no longer needed. It should |
| 872 | * free the buf log item associated with the given buffer and clear | 888 | * free the buf log item associated with the given buffer and clear |
| @@ -887,18 +903,8 @@ xfs_buf_item_relse( | |||
| 887 | (XFS_BUF_IODONE_FUNC(bp) != NULL)) { | 903 | (XFS_BUF_IODONE_FUNC(bp) != NULL)) { |
| 888 | XFS_BUF_CLR_IODONE_FUNC(bp); | 904 | XFS_BUF_CLR_IODONE_FUNC(bp); |
| 889 | } | 905 | } |
| 890 | 906 | xfs_buf_rele(bp); | |
| 891 | #ifdef XFS_TRANS_DEBUG | 907 | xfs_buf_item_free(bip); |
| 892 | kmem_free(bip->bli_orig); | ||
| 893 | bip->bli_orig = NULL; | ||
| 894 | kmem_free(bip->bli_logged); | ||
| 895 | bip->bli_logged = NULL; | ||
| 896 | #endif /* XFS_TRANS_DEBUG */ | ||
| 897 | |||
| 898 | #ifdef XFS_BLI_TRACE | ||
| 899 | ktrace_free(bip->bli_trace); | ||
| 900 | #endif | ||
| 901 | kmem_zone_free(xfs_buf_item_zone, bip); | ||
| 902 | } | 908 | } |
| 903 | 909 | ||
| 904 | 910 | ||
| @@ -1120,6 +1126,7 @@ xfs_buf_iodone( | |||
| 1120 | 1126 | ||
| 1121 | ASSERT(bip->bli_buf == bp); | 1127 | ASSERT(bip->bli_buf == bp); |
| 1122 | 1128 | ||
| 1129 | xfs_buf_rele(bp); | ||
| 1123 | mp = bip->bli_item.li_mountp; | 1130 | mp = bip->bli_item.li_mountp; |
| 1124 | 1131 | ||
| 1125 | /* | 1132 | /* |
| @@ -1136,18 +1143,7 @@ xfs_buf_iodone( | |||
| 1136 | * xfs_trans_delete_ail() drops the AIL lock. | 1143 | * xfs_trans_delete_ail() drops the AIL lock. |
| 1137 | */ | 1144 | */ |
| 1138 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); | 1145 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); |
| 1139 | 1146 | xfs_buf_item_free(bip); | |
| 1140 | #ifdef XFS_TRANS_DEBUG | ||
| 1141 | kmem_free(bip->bli_orig); | ||
| 1142 | bip->bli_orig = NULL; | ||
| 1143 | kmem_free(bip->bli_logged); | ||
| 1144 | bip->bli_logged = NULL; | ||
| 1145 | #endif /* XFS_TRANS_DEBUG */ | ||
| 1146 | |||
| 1147 | #ifdef XFS_BLI_TRACE | ||
| 1148 | ktrace_free(bip->bli_trace); | ||
| 1149 | #endif | ||
| 1150 | kmem_zone_free(xfs_buf_item_zone, bip); | ||
| 1151 | } | 1147 | } |
| 1152 | 1148 | ||
| 1153 | #if defined(XFS_BLI_TRACE) | 1149 | #if defined(XFS_BLI_TRACE) |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 760f4c5b5160..75b0cd4da0ea 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
| @@ -149,7 +149,14 @@ xfs_swap_extents( | |||
| 149 | 149 | ||
| 150 | sbp = &sxp->sx_stat; | 150 | sbp = &sxp->sx_stat; |
| 151 | 151 | ||
| 152 | xfs_lock_two_inodes(ip, tip, lock_flags); | 152 | /* |
| 153 | * we have to do two separate lock calls here to keep lockdep | ||
| 154 | * happy. If we try to get all the locks in one call, lock will | ||
| 155 | * report false positives when we drop the ILOCK and regain them | ||
| 156 | * below. | ||
| 157 | */ | ||
| 158 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); | ||
| 159 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | ||
| 153 | locked = 1; | 160 | locked = 1; |
| 154 | 161 | ||
| 155 | /* Verify that both files have the same format */ | 162 | /* Verify that both files have the same format */ |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index ccba14eb9dbe..503ea89e8b9a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -124,16 +124,27 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, | |||
| 124 | STATIC int xlog_iclogs_empty(xlog_t *log); | 124 | STATIC int xlog_iclogs_empty(xlog_t *log); |
| 125 | 125 | ||
| 126 | #if defined(XFS_LOG_TRACE) | 126 | #if defined(XFS_LOG_TRACE) |
| 127 | |||
| 128 | #define XLOG_TRACE_LOGGRANT_SIZE 2048 | ||
| 129 | #define XLOG_TRACE_ICLOG_SIZE 256 | ||
| 130 | |||
| 131 | void | ||
| 132 | xlog_trace_loggrant_alloc(xlog_t *log) | ||
| 133 | { | ||
| 134 | log->l_grant_trace = ktrace_alloc(XLOG_TRACE_LOGGRANT_SIZE, KM_NOFS); | ||
| 135 | } | ||
| 136 | |||
| 137 | void | ||
| 138 | xlog_trace_loggrant_dealloc(xlog_t *log) | ||
| 139 | { | ||
| 140 | ktrace_free(log->l_grant_trace); | ||
| 141 | } | ||
