Commit 82079c70 authored by Nathan Scott's avatar Nathan Scott Committed by Christoph Hellwig

[XFS] Fix up setting up of sector size for the superblock buffer after the

very first read on mount.  Make some of the surrounding code dealing
with buffers consistent.

SGI Modid: 2.5.x-xfs:slinx:135452a
parent 073f32e7
......@@ -507,8 +507,15 @@ xfs_relse_buftarg(
truncate_inode_pages(btp->pbr_mapping, 0LL);
}
unsigned int
xfs_getsize_buftarg(
xfs_buftarg_t *btp)
{
return block_size(btp->pbr_bdev);
}
void
xfs_size_buftarg(
xfs_setsize_buftarg(
xfs_buftarg_t *btp,
unsigned int blocksize,
unsigned int sectorsize)
......@@ -535,7 +542,7 @@ xfs_alloc_buftarg(
btp->pbr_dev = bdev->bd_dev;
btp->pbr_bdev = bdev;
btp->pbr_mapping = bdev->bd_inode->i_mapping;
xfs_size_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev));
xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev));
return btp;
}
......
......@@ -82,15 +82,17 @@ struct xfs_mount;
struct pb_target;
struct block_device;
extern void xfs_initialize_vnode (bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern int xfs_blkdev_get (struct xfs_mount *, const char *,
extern int xfs_blkdev_get(struct xfs_mount *, const char *,
struct block_device **);
extern void xfs_blkdev_put (struct block_device *);
extern void xfs_blkdev_put(struct block_device *);
extern struct pb_target *xfs_alloc_buftarg (struct block_device *);
extern void xfs_size_buftarg (struct pb_target *, unsigned int, unsigned int);
extern void xfs_relse_buftarg (struct pb_target *);
extern void xfs_free_buftarg (struct pb_target *);
extern struct pb_target *xfs_alloc_buftarg(struct block_device *);
extern void xfs_relse_buftarg(struct pb_target *);
extern void xfs_free_buftarg(struct pb_target *);
extern void xfs_setsize_buftarg(struct pb_target *, unsigned int, unsigned int);
extern unsigned int xfs_getsize_buftarg(struct pb_target *);
#endif /* __XFS_SUPER_H__ */
......@@ -35,28 +35,34 @@
/* These are just for xfs_syncsub... it sets an internal variable
* then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t
*/
#define XFS_B_ASYNC PBF_ASYNC
#define XFS_B_DELWRI PBF_DELWRI
#define XFS_B_READ PBF_READ
#define XFS_B_WRITE PBF_WRITE
#define XFS_B_STALE PBF_STALE
#define XFS_B_ASYNC PBF_ASYNC
#define XFS_B_DELWRI PBF_DELWRI
#define XFS_B_READ PBF_READ
#define XFS_B_WRITE PBF_WRITE
#define XFS_B_STALE PBF_STALE
#define XFS_BUF_TRYLOCK PBF_TRYLOCK
#define XFS_INCORE_TRYLOCK PBF_TRYLOCK
#define XFS_BUF_LOCK PBF_LOCK
#define XFS_BUF_MAPPED PBF_MAPPED
#define BUF_BUSY PBF_DONT_BLOCK
#define BUF_BUSY PBF_DONT_BLOCK
#define XFS_BUF_BFLAGS(x) ((x)->pb_flags) /* debugging routines might need this */
#define XFS_BUF_BFLAGS(x) ((x)->pb_flags)
#define XFS_BUF_ZEROFLAGS(x) \
((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_DELWRI))
#define XFS_BUF_STALE(x) ((x)->pb_flags |= XFS_B_STALE)
#define XFS_BUF_UNSTALE(x) ((x)->pb_flags &= ~XFS_B_STALE)
#define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE)
#define XFS_BUF_SUPER_STALE(x) (x)->pb_flags |= XFS_B_STALE;\
xfs_buf_undelay(x);\
(x)->pb_flags &= ~(PBF_PARTIAL|PBF_NONE)
#define XFS_BUF_STALE(x) ((x)->pb_flags |= XFS_B_STALE)
#define XFS_BUF_UNSTALE(x) ((x)->pb_flags &= ~XFS_B_STALE)
#define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE)
#define XFS_BUF_SUPER_STALE(x) do { \
XFS_BUF_STALE(x); \
xfs_buf_undelay(x); \
XFS_BUF_DONE(x); \
} while (0)
#define XFS_BUF_MANAGE PBF_FS_MANAGED
#define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_FS_MANAGED)
static inline void xfs_buf_undelay(page_buf_t *pb)
{
......
......@@ -419,42 +419,64 @@ xfs_xlatesb(
int
xfs_readsb(xfs_mount_t *mp)
{
unsigned int sector_size;
unsigned int extra_flags;
xfs_buf_t *bp;
xfs_sb_t *sbp;
int error = 0;
int error;
ASSERT(mp->m_sb_bp == 0);
ASSERT(mp->m_sb_bp == NULL);
ASSERT(mp->m_ddev_targp != NULL);
/*
* Allocate a (locked) buffer to hold the superblock.
* This will be kept around at all time to optimize
* This will be kept around at all times to optimize
* access to the superblock.
*/
bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, 1,
PBF_LOCK|PBF_READ|PBF_MAPPED|PBF_MAPPABLE|PBF_FS_MANAGED);
ASSERT(bp != NULL);
ASSERT(XFS_BUF_ISBUSY(bp) && XFS_BUF_VALUSEMA(bp) <= 0);
sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED;
bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
BTOBB(sector_size), extra_flags);
ASSERT(bp);
ASSERT(XFS_BUF_ISBUSY(bp));
ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
/*
* Initialize the mount structure from the superblock.
* But first do some basic consistency checking.
*/
sbp = XFS_BUF_TO_SBP(bp);
xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, ARCH_CONVERT, XFS_SB_ALL_BITS);
if ((error = xfs_mount_validate_sb(mp, &(mp->m_sb)))) {
xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1,
ARCH_CONVERT, XFS_SB_ALL_BITS);
error = xfs_mount_validate_sb(mp, &(mp->m_sb));
if (error) {
cmn_err(CE_WARN, "XFS: SB validate failed");
goto err;
XFS_BUF_UNMANAGE(bp);
xfs_buf_relse(bp);
return error;
}
/*
* Re-read the superblock so that our buffer is correctly sized.
* We only need to do this if sector size on-disk is different.
*/
if (sector_size != mp->m_sb.sb_sectsize) {
XFS_BUF_UNMANAGE(bp);
xfs_buf_relse(bp);
sector_size = mp->m_sb.sb_sectsize;
bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
BTOBB(sector_size), extra_flags);
ASSERT(bp);
ASSERT(XFS_BUF_ISBUSY(bp));
ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
}
mp->m_sb_bp = bp;
xfs_buf_relse(bp);
ASSERT(XFS_BUF_VALUSEMA(bp) > 0);
return 0;
err:
bp->pb_flags &= ~PBF_FS_MANAGED;
xfs_buf_relse(bp);
return error;
}
......@@ -1531,10 +1553,10 @@ xfs_freesb(
/*
* Use xfs_getsb() so that the buffer will be locked
* when we call nfreerbuf().
* when we call xfs_buf_relse().
*/
bp = xfs_getsb(mp, 0);
bp->pb_flags &= ~PBF_FS_MANAGED;
XFS_BUF_UNMANAGE(bp);
xfs_buf_relse(bp);
mp->m_sb_bp = NULL;
}
......
......@@ -451,18 +451,19 @@ xfs_mount(
goto error;
}
xfs_size_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (logdev && logdev != ddev) {
unsigned int ss = BBSIZE;
unsigned int log_sector_size = BBSIZE;
if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
ss = mp->m_sb.sb_logsectsize;
xfs_size_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, ss);
log_sector_size = mp->m_sb.sb_logsectsize;
xfs_setsize_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize,
log_sector_size);
}
if (rtdev)
xfs_size_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_blocksize);
xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_blocksize);
error = xfs_mountfs(vfsp, mp, ddev->bd_dev, flags);
if (error)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment