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)
}
/*
* In these two situations we disregard the readonly mount flag and
* temporarily enable writes (we must, to ensure metadata integrity).
* If the underlying (log or data) device is readonly, there are some
* operations that cannot proceed.
*/
STATIC int
xfs_is_read_only(xfs_mount_t *mp)
int
xfs_dev_is_read_only(xfs_mount_t *mp, char *message)
{
if (bdev_read_only(mp->m_ddev_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,
"XFS: write access unavailable, cannot proceed.");
return EROFS;
}
cmn_err(CE_NOTE,
"XFS: write access will be enabled during mount.");
XFS_MTOVFS(mp)->vfs_flag &= ~VFS_RDONLY;
return 0;
}
int
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);
return 0;
}
......@@ -62,9 +62,7 @@ extern ssize_t xfs_write (
loff_t *offp,
struct cred *credp);
extern int xfs_recover_read_only (xlog_t *);
extern int xfs_quotacheck_read_only (xfs_mount_t *);
extern int xfs_quotaino_create_read_only (xfs_mount_t *);
extern int xfs_dev_is_read_only(xfs_mount_t *, char *);
extern void XFS_log_write_unmount_ro (bhv_desc_t *);
......
......@@ -873,9 +873,19 @@ xlog_find_tail(xlog_t *log,
* overwrite the unmount record after a clean unmount.
*
* 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);
}
#endif
bread_err:
......@@ -3521,17 +3531,20 @@ xlog_recover(xlog_t *log, int readonly)
* error message.
* ...but this is no longer true. Now, unless you specify
* NORECOVERY (in which case this function would never be
* called), it enables read-write access long enough to do
* recovery.
* called), we just go ahead and recover. We do this all
* 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__
if ((error = xfs_recover_read_only(log)))
return error;
if ((error = xfs_dev_is_read_only(log->l_mp,
"recovery required"))) {
return error;
}
#else
if (readonly) {
return ENOSPC;
#endif
}
#endif
#ifdef __KERNEL__
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
......@@ -3548,8 +3561,6 @@ xlog_recover(xlog_t *log, int readonly)
#endif
error = xlog_do_recover(log, head_blk, tail_blk);
log->l_flags |= XLOG_RECOVERY_NEEDED;
if (readonly)
XFS_MTOVFS(log->l_mp)->vfs_flag |= VFS_RDONLY;
}
return error;
} /* xlog_recover */
......
......@@ -937,8 +937,7 @@ xfs_mountfs(
if (((quotaondisk && !XFS_IS_QUOTA_ON(mp)) ||
(!quotaondisk && XFS_IS_QUOTA_ON(mp))) &&
(bdev_read_only(mp->m_ddev_targp->pbr_bdev) ||
bdev_read_only(mp->m_logdev_targp->pbr_bdev))) {
xfs_dev_is_read_only(mp, "changing quota state")) {
cmn_err(CE_WARN,
"XFS: device %s is read-only, cannot change "
"quota state. Please mount with%s quota option.",
......@@ -1030,14 +1029,12 @@ xfs_mountfs(
if (needquotamount) {
ASSERT(mp->m_qflags == 0);
mp->m_qflags = quotaflags;
rootqcheck = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) &&
mp->m_dev == rootdev && needquotacheck);
if (rootqcheck && (error = xfs_quotacheck_read_only(mp)))
rootqcheck = (mp->m_dev == rootdev && needquotacheck);
if (rootqcheck && (error = xfs_dev_is_read_only(mp,
"quotacheck")))
goto error2;
if (xfs_qm_mount_quotas(mp))
xfs_mount_reset_sbqflags(mp);
if (rootqcheck)
XFS_MTOVFS(mp)->vfs_flag |= VFS_RDONLY;
}
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
......
......@@ -2039,17 +2039,9 @@ xfs_qm_init_quotainos(
/*
* 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
* the qino_alloc calls below. If the device is readonly,
* temporarily switch to read-write to do this.
* the qino_alloc calls below.
*/
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 ((error = xfs_qm_qino_alloc(mp, &uip,
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