diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-11 17:29:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-11 17:29:03 -0400 |
commit | 0789d8fccb5673001b54536d8f2f87f5db0d646f (patch) | |
tree | 8f4482c2b26f5f8b226433973bdf9b337dde9378 /fs | |
parent | ebdcc81c71937b30e09110c02a1e8a21fa770b6f (diff) | |
parent | c141b2928fe20396a9ecdec85526e4b66ae96c90 (diff) |
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs:
xfs: only issues a cache flush on unmount if barriers are enabled
xfs: prevent lockdep false positive in xfs_iget_cache_miss
xfs: prevent kernel crash due to corrupted inode log format
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 12 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 2 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_iget.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 17 |
5 files changed, 39 insertions, 17 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index cb329edc925b..aa1016bb9134 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -34,6 +34,12 @@ | |||
34 | #include <linux/backing-dev.h> | 34 | #include <linux/backing-dev.h> |
35 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
36 | 36 | ||
37 | #include "xfs_sb.h" | ||
38 | #include "xfs_inum.h" | ||
39 | #include "xfs_ag.h" | ||
40 | #include "xfs_dmapi.h" | ||
41 | #include "xfs_mount.h" | ||
42 | |||
37 | static kmem_zone_t *xfs_buf_zone; | 43 | static kmem_zone_t *xfs_buf_zone; |
38 | STATIC int xfsbufd(void *); | 44 | STATIC int xfsbufd(void *); |
39 | STATIC int xfsbufd_wakeup(int, gfp_t); | 45 | STATIC int xfsbufd_wakeup(int, gfp_t); |
@@ -1435,10 +1441,12 @@ xfs_unregister_buftarg( | |||
1435 | 1441 | ||
1436 | void | 1442 | void |
1437 | xfs_free_buftarg( | 1443 | xfs_free_buftarg( |
1438 | xfs_buftarg_t *btp) | 1444 | struct xfs_mount *mp, |
1445 | struct xfs_buftarg *btp) | ||
1439 | { | 1446 | { |
1440 | xfs_flush_buftarg(btp, 1); | 1447 | xfs_flush_buftarg(btp, 1); |
1441 | xfs_blkdev_issue_flush(btp); | 1448 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
1449 | xfs_blkdev_issue_flush(btp); | ||
1442 | xfs_free_bufhash(btp); | 1450 | xfs_free_bufhash(btp); |
1443 | iput(btp->bt_mapping->host); | 1451 | iput(btp->bt_mapping->host); |
1444 | 1452 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 288ae7c4c800..9b4d666ad31f 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -413,7 +413,7 @@ static inline int XFS_bwrite(xfs_buf_t *bp) | |||
413 | * Handling of buftargs. | 413 | * Handling of buftargs. |
414 | */ | 414 | */ |
415 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); | 415 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); |
416 | extern void xfs_free_buftarg(xfs_buftarg_t *); | 416 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); |
417 | extern void xfs_wait_buftarg(xfs_buftarg_t *); | 417 | extern void xfs_wait_buftarg(xfs_buftarg_t *); |
418 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); | 418 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); |
419 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); | 419 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c71e226da7f5..32ae5028e96b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -734,15 +734,15 @@ xfs_close_devices( | |||
734 | { | 734 | { |
735 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 735 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
736 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; | 736 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; |
737 | xfs_free_buftarg(mp->m_logdev_targp); | 737 | xfs_free_buftarg(mp, mp->m_logdev_targp); |
738 | xfs_blkdev_put(logdev); | 738 | xfs_blkdev_put(logdev); |
739 | } | 739 | } |
740 | if (mp->m_rtdev_targp) { | 740 | if (mp->m_rtdev_targp) { |
741 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; | 741 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; |
742 | xfs_free_buftarg(mp->m_rtdev_targp); | 742 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
743 | xfs_blkdev_put(rtdev); | 743 | xfs_blkdev_put(rtdev); |
744 | } | 744 | } |
745 | xfs_free_buftarg(mp->m_ddev_targp); | 745 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
746 | } | 746 | } |
747 | 747 | ||
748 | /* | 748 | /* |
@@ -811,9 +811,9 @@ xfs_open_devices( | |||
811 | 811 | ||
812 | out_free_rtdev_targ: | 812 | out_free_rtdev_targ: |
813 | if (mp->m_rtdev_targp) | 813 | if (mp->m_rtdev_targp) |
814 | xfs_free_buftarg(mp->m_rtdev_targp); | 814 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
815 | out_free_ddev_targ: | 815 | out_free_ddev_targ: |
816 | xfs_free_buftarg(mp->m_ddev_targp); | 816 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
817 | out_close_rtdev: | 817 | out_close_rtdev: |
818 | if (rtdev) | 818 | if (rtdev) |
819 | xfs_blkdev_put(rtdev); | 819 | xfs_blkdev_put(rtdev); |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e2fb6210d4c5..478e587087fe 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -246,9 +246,6 @@ xfs_iget_cache_miss( | |||
246 | goto out_destroy; | 246 | goto out_destroy; |
247 | } | 247 | } |
248 | 248 | ||
249 | if (lock_flags) | ||
250 | xfs_ilock(ip, lock_flags); | ||
251 | |||
252 | /* | 249 | /* |
253 | * Preload the radix tree so we can insert safely under the | 250 | * Preload the radix tree so we can insert safely under the |
254 | * write spinlock. Note that we cannot sleep inside the preload | 251 | * write spinlock. Note that we cannot sleep inside the preload |
@@ -256,7 +253,16 @@ xfs_iget_cache_miss( | |||
256 | */ | 253 | */ |
257 | if (radix_tree_preload(GFP_KERNEL)) { | 254 | if (radix_tree_preload(GFP_KERNEL)) { |
258 | error = EAGAIN; | 255 | error = EAGAIN; |
259 | goto out_unlock; | 256 | goto out_destroy; |
257 | } | ||
258 | |||
259 | /* | ||
260 | * Because the inode hasn't been added to the radix-tree yet it can't | ||
261 | * be found by another thread, so we can do the non-sleeping lock here. | ||
262 | */ | ||
263 | if (lock_flags) { | ||
264 | if (!xfs_ilock_nowait(ip, lock_flags)) | ||
265 | BUG(); | ||
260 | } | 266 | } |
261 | 267 | ||
262 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | 268 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); |
@@ -284,7 +290,6 @@ xfs_iget_cache_miss( | |||
284 | out_preload_end: | 290 | out_preload_end: |
285 | write_unlock(&pag->pag_ici_lock); | 291 | write_unlock(&pag->pag_ici_lock); |
286 | radix_tree_preload_end(); | 292 | radix_tree_preload_end(); |
287 | out_unlock: | ||
288 | if (lock_flags) | 293 | if (lock_flags) |
289 | xfs_iunlock(ip, lock_flags); | 294 | xfs_iunlock(ip, lock_flags); |
290 | out_destroy: | 295 | out_destroy: |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b1047de2fffd..61af610d79b3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1455,10 +1455,19 @@ xlog_recover_add_to_trans( | |||
1455 | item = item->ri_prev; | 1455 | item = item->ri_prev; |
1456 | 1456 | ||
1457 | if (item->ri_total == 0) { /* first region to be added */ | 1457 | if (item->ri_total == 0) { /* first region to be added */ |
1458 | item->ri_total = in_f->ilf_size; | 1458 | if (in_f->ilf_size == 0 || |
1459 | ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM); | 1459 | in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { |
1460 | item->ri_buf = kmem_zalloc((item->ri_total * | 1460 | xlog_warn( |
1461 | sizeof(xfs_log_iovec_t)), KM_SLEEP); | 1461 | "XFS: bad number of regions (%d) in inode log format", |
1462 | in_f->ilf_size); | ||
1463 | ASSERT(0); | ||
1464 | return XFS_ERROR(EIO); | ||
1465 | } | ||
1466 | |||
1467 | item->ri_total = in_f->ilf_size; | ||
1468 | item->ri_buf = | ||
1469 | kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), | ||
1470 | KM_SLEEP); | ||
1462 | } | 1471 | } |
1463 | ASSERT(item->ri_total > item->ri_cnt); | 1472 | ASSERT(item->ri_total > item->ri_cnt); |
1464 | /* Description region is ri_buf[0] */ | 1473 | /* Description region is ri_buf[0] */ |