Commit 5f7af273 authored by Eric Sandeen's avatar Eric Sandeen Committed by Christoph Hellwig

XFS: Rearrange how xfs deals with read-only mounts vs. read-only devices.

Modid: 2.5.x-xfs:slinx:129120a
parent f93d3d7d
...@@ -1836,45 +1836,21 @@ XFS_log_write_unmount_ro(bhv_desc_t *bdp) ...@@ -1836,45 +1836,21 @@ XFS_log_write_unmount_ro(bhv_desc_t *bdp)
} }
/* /*
* In these two situations we disregard the readonly mount flag and * If the underlying (log or data) device is readonly, there are some
* temporarily enable writes (we must, to ensure metadata integrity). * operations that cannot proceed.
*/ */
STATIC int int
xfs_is_read_only(xfs_mount_t *mp) xfs_dev_is_read_only(xfs_mount_t *mp, char *message)
{ {
if (bdev_read_only(mp->m_ddev_targp->pbr_bdev) || if (bdev_read_only(mp->m_ddev_targp->pbr_bdev) ||
bdev_read_only(mp->m_logdev_targp->pbr_bdev)) { bdev_read_only(mp->m_logdev_targp->pbr_bdev)) {
cmn_err(CE_NOTE,
"XFS: %s required on read-only device.", message);
cmn_err(CE_NOTE, cmn_err(CE_NOTE,
"XFS: write access unavailable, cannot proceed."); "XFS: write access unavailable, cannot proceed.");
return EROFS; return EROFS;
} }
cmn_err(CE_NOTE,
"XFS: write access will be enabled during mount.");
XFS_MTOVFS(mp)->vfs_flag &= ~VFS_RDONLY;
return 0;
}
int return 0;
xfs_recover_read_only(xlog_t *log)
{
cmn_err(CE_NOTE, "XFS: WARNING: "
"recovery required on readonly filesystem.");
return xfs_is_read_only(log->l_mp);
}
int
xfs_quotacheck_read_only(xfs_mount_t *mp)
{
cmn_err(CE_NOTE, "XFS: WARNING: "
"quotacheck required on readonly filesystem.");
return xfs_is_read_only(mp);
}
int
xfs_quotaino_create_read_only(xfs_mount_t *mp)
{
cmn_err(CE_NOTE, "XFS: WARNING: "
"Quota inode creation required on readonly filesystem.");
return xfs_is_read_only(mp);
} }
...@@ -62,9 +62,7 @@ extern ssize_t xfs_write ( ...@@ -62,9 +62,7 @@ extern ssize_t xfs_write (
loff_t *offp, loff_t *offp,
struct cred *credp); struct cred *credp);
extern int xfs_recover_read_only (xlog_t *); extern int xfs_dev_is_read_only(xfs_mount_t *, char *);
extern int xfs_quotacheck_read_only (xfs_mount_t *);
extern int xfs_quotaino_create_read_only (xfs_mount_t *);
extern void XFS_log_write_unmount_ro (bhv_desc_t *); extern void XFS_log_write_unmount_ro (bhv_desc_t *);
......
...@@ -873,9 +873,19 @@ xlog_find_tail(xlog_t *log, ...@@ -873,9 +873,19 @@ xlog_find_tail(xlog_t *log,
* overwrite the unmount record after a clean unmount. * overwrite the unmount record after a clean unmount.
* *
* Do this only if we are going to recover the filesystem * Do this only if we are going to recover the filesystem
*
* NOTE: This used to say "if (!readonly)"
* However on Linux, we can & do recover a read-only filesystem.
* We only skip recovery if NORECOVERY is specified on mount,
* in which case we would not be here.
*
* But... if the -device- itself is readonly, just skip this.
* We can't recover this device anyway, so it won't matter.
*/ */
if (!readonly)
if (!bdev_read_only(log->l_mp->m_logdev_targp->pbr_bdev)) {
error = xlog_clear_stale_blocks(log, tail_lsn); error = xlog_clear_stale_blocks(log, tail_lsn);
}
#endif #endif
bread_err: bread_err:
...@@ -3521,17 +3531,20 @@ xlog_recover(xlog_t *log, int readonly) ...@@ -3521,17 +3531,20 @@ xlog_recover(xlog_t *log, int readonly)
* error message. * error message.
* ...but this is no longer true. Now, unless you specify * ...but this is no longer true. Now, unless you specify
* NORECOVERY (in which case this function would never be * NORECOVERY (in which case this function would never be
* called), it enables read-write access long enough to do * called), we just go ahead and recover. We do this all
* recovery. * under the vfs layer, so we can get away with it unless
* the device itself is read-only, in which case we fail.
*/ */
if (readonly) {
#ifdef __KERNEL__ #ifdef __KERNEL__
if ((error = xfs_recover_read_only(log))) if ((error = xfs_dev_is_read_only(log->l_mp,
"recovery required"))) {
return error; return error;
}
#else #else
if (readonly) {
return ENOSPC; return ENOSPC;
#endif
} }
#endif
#ifdef __KERNEL__ #ifdef __KERNEL__
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
...@@ -3548,8 +3561,6 @@ xlog_recover(xlog_t *log, int readonly) ...@@ -3548,8 +3561,6 @@ xlog_recover(xlog_t *log, int readonly)
#endif #endif
error = xlog_do_recover(log, head_blk, tail_blk); error = xlog_do_recover(log, head_blk, tail_blk);
log->l_flags |= XLOG_RECOVERY_NEEDED; log->l_flags |= XLOG_RECOVERY_NEEDED;
if (readonly)
XFS_MTOVFS(log->l_mp)->vfs_flag |= VFS_RDONLY;
} }
return error; return error;
} /* xlog_recover */ } /* xlog_recover */
......
...@@ -937,8 +937,7 @@ xfs_mountfs( ...@@ -937,8 +937,7 @@ xfs_mountfs(
if (((quotaondisk && !XFS_IS_QUOTA_ON(mp)) || if (((quotaondisk && !XFS_IS_QUOTA_ON(mp)) ||
(!quotaondisk && XFS_IS_QUOTA_ON(mp))) && (!quotaondisk && XFS_IS_QUOTA_ON(mp))) &&
(bdev_read_only(mp->m_ddev_targp->pbr_bdev) || xfs_dev_is_read_only(mp, "changing quota state")) {
bdev_read_only(mp->m_logdev_targp->pbr_bdev))) {
cmn_err(CE_WARN, cmn_err(CE_WARN,
"XFS: device %s is read-only, cannot change " "XFS: device %s is read-only, cannot change "
"quota state. Please mount with%s quota option.", "quota state. Please mount with%s quota option.",
...@@ -1030,14 +1029,12 @@ xfs_mountfs( ...@@ -1030,14 +1029,12 @@ xfs_mountfs(
if (needquotamount) { if (needquotamount) {
ASSERT(mp->m_qflags == 0); ASSERT(mp->m_qflags == 0);
mp->m_qflags = quotaflags; mp->m_qflags = quotaflags;
rootqcheck = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) && rootqcheck = (mp->m_dev == rootdev && needquotacheck);
mp->m_dev == rootdev && needquotacheck); if (rootqcheck && (error = xfs_dev_is_read_only(mp,
if (rootqcheck && (error = xfs_quotacheck_read_only(mp))) "quotacheck")))
goto error2; goto error2;
if (xfs_qm_mount_quotas(mp)) if (xfs_qm_mount_quotas(mp))
xfs_mount_reset_sbqflags(mp); xfs_mount_reset_sbqflags(mp);
if (rootqcheck)
XFS_MTOVFS(mp)->vfs_flag |= VFS_RDONLY;
} }
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
......
...@@ -2039,17 +2039,9 @@ xfs_qm_init_quotainos( ...@@ -2039,17 +2039,9 @@ xfs_qm_init_quotainos(
/* /*
* Create the two inodes, if they don't exist already. The changes * Create the two inodes, if they don't exist already. The changes
* made above will get added to a transaction and logged in one of * made above will get added to a transaction and logged in one of
* the qino_alloc calls below. If the device is readonly, * the qino_alloc calls below.
* temporarily switch to read-write to do this.
*/ */
if (readonly &&
((XFS_IS_UQUOTA_ON(mp) && uip == NULL) ||
(XFS_IS_GQUOTA_ON(mp) && gip == NULL))) {
if ((error = xfs_quotaino_create_read_only(mp)))
goto error;
}
if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) { if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
if ((error = xfs_qm_qino_alloc(mp, &uip, if ((error = xfs_qm_qino_alloc(mp, &uip,
sbflags | XFS_SB_UQUOTINO, sbflags | XFS_SB_UQUOTINO,
......
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