mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 00:52:01 +00:00
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
This commit is contained in:
commit
0789d8fccb
@ -34,6 +34,12 @@
|
||||
#include <linux/backing-dev.h>
|
||||
#include <linux/freezer.h>
|
||||
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_inum.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
||||
static kmem_zone_t *xfs_buf_zone;
|
||||
STATIC int xfsbufd(void *);
|
||||
STATIC int xfsbufd_wakeup(int, gfp_t);
|
||||
@ -1435,10 +1441,12 @@ xfs_unregister_buftarg(
|
||||
|
||||
void
|
||||
xfs_free_buftarg(
|
||||
xfs_buftarg_t *btp)
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_buftarg *btp)
|
||||
{
|
||||
xfs_flush_buftarg(btp, 1);
|
||||
xfs_blkdev_issue_flush(btp);
|
||||
if (mp->m_flags & XFS_MOUNT_BARRIER)
|
||||
xfs_blkdev_issue_flush(btp);
|
||||
xfs_free_bufhash(btp);
|
||||
iput(btp->bt_mapping->host);
|
||||
|
||||
|
@ -413,7 +413,7 @@ static inline int XFS_bwrite(xfs_buf_t *bp)
|
||||
* Handling of buftargs.
|
||||
*/
|
||||
extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
|
||||
extern void xfs_free_buftarg(xfs_buftarg_t *);
|
||||
extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
|
||||
extern void xfs_wait_buftarg(xfs_buftarg_t *);
|
||||
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
|
||||
extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
|
||||
|
@ -734,15 +734,15 @@ xfs_close_devices(
|
||||
{
|
||||
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
|
||||
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
|
||||
xfs_free_buftarg(mp->m_logdev_targp);
|
||||
xfs_free_buftarg(mp, mp->m_logdev_targp);
|
||||
xfs_blkdev_put(logdev);
|
||||
}
|
||||
if (mp->m_rtdev_targp) {
|
||||
struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
|
||||
xfs_free_buftarg(mp->m_rtdev_targp);
|
||||
xfs_free_buftarg(mp, mp->m_rtdev_targp);
|
||||
xfs_blkdev_put(rtdev);
|
||||
}
|
||||
xfs_free_buftarg(mp->m_ddev_targp);
|
||||
xfs_free_buftarg(mp, mp->m_ddev_targp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -811,9 +811,9 @@ xfs_open_devices(
|
||||
|
||||
out_free_rtdev_targ:
|
||||
if (mp->m_rtdev_targp)
|
||||
xfs_free_buftarg(mp->m_rtdev_targp);
|
||||
xfs_free_buftarg(mp, mp->m_rtdev_targp);
|
||||
out_free_ddev_targ:
|
||||
xfs_free_buftarg(mp->m_ddev_targp);
|
||||
xfs_free_buftarg(mp, mp->m_ddev_targp);
|
||||
out_close_rtdev:
|
||||
if (rtdev)
|
||||
xfs_blkdev_put(rtdev);
|
||||
|
@ -246,9 +246,6 @@ xfs_iget_cache_miss(
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
if (lock_flags)
|
||||
xfs_ilock(ip, lock_flags);
|
||||
|
||||
/*
|
||||
* Preload the radix tree so we can insert safely under the
|
||||
* write spinlock. Note that we cannot sleep inside the preload
|
||||
@ -256,7 +253,16 @@ xfs_iget_cache_miss(
|
||||
*/
|
||||
if (radix_tree_preload(GFP_KERNEL)) {
|
||||
error = EAGAIN;
|
||||
goto out_unlock;
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Because the inode hasn't been added to the radix-tree yet it can't
|
||||
* be found by another thread, so we can do the non-sleeping lock here.
|
||||
*/
|
||||
if (lock_flags) {
|
||||
if (!xfs_ilock_nowait(ip, lock_flags))
|
||||
BUG();
|
||||
}
|
||||
|
||||
mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
|
||||
@ -284,7 +290,6 @@ xfs_iget_cache_miss(
|
||||
out_preload_end:
|
||||
write_unlock(&pag->pag_ici_lock);
|
||||
radix_tree_preload_end();
|
||||
out_unlock:
|
||||
if (lock_flags)
|
||||
xfs_iunlock(ip, lock_flags);
|
||||
out_destroy:
|
||||
|
@ -1455,10 +1455,19 @@ xlog_recover_add_to_trans(
|
||||
item = item->ri_prev;
|
||||
|
||||
if (item->ri_total == 0) { /* first region to be added */
|
||||
item->ri_total = in_f->ilf_size;
|
||||
ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM);
|
||||
item->ri_buf = kmem_zalloc((item->ri_total *
|
||||
sizeof(xfs_log_iovec_t)), KM_SLEEP);
|
||||
if (in_f->ilf_size == 0 ||
|
||||
in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) {
|
||||
xlog_warn(
|
||||
"XFS: bad number of regions (%d) in inode log format",
|
||||
in_f->ilf_size);
|
||||
ASSERT(0);
|
||||
return XFS_ERROR(EIO);
|
||||
}
|
||||
|
||||
item->ri_total = in_f->ilf_size;
|
||||
item->ri_buf =
|
||||
kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t),
|
||||
KM_SLEEP);
|
||||
}
|
||||
ASSERT(item->ri_total > item->ri_cnt);
|
||||
/* Description region is ri_buf[0] */
|
||||
|
Loading…
Reference in New Issue
Block a user