dect
/
linux-2.6
Archived
13
0
Fork 0

xfs: fix bad_features2 fixups for the root filesystem

Currently the bad_features2 fixup and the alignment updates in the superblock
are skipped if we mount a filesystem read-only.  But for the root filesystem
the typical case is to mount read-only first and only later remount writeable
so we'll never perform this update at all.  It's not a big problem but means
the logs of people needing the fixup get spammed at every boot because they
never happen on disk.

Reported-by: Arkadiusz Miskiewicz <arekm@maven.pl>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Christoph Hellwig 2009-01-19 02:04:07 +01:00 committed by Lachlan McIlroy
parent 5aa2dc0a06
commit 49739140e5
3 changed files with 32 additions and 14 deletions

View File

@ -1197,6 +1197,7 @@ xfs_fs_remount(
struct xfs_mount *mp = XFS_M(sb); struct xfs_mount *mp = XFS_M(sb);
substring_t args[MAX_OPT_ARGS]; substring_t args[MAX_OPT_ARGS];
char *p; char *p;
int error;
while ((p = strsep(&options, ",")) != NULL) { while ((p = strsep(&options, ",")) != NULL) {
int token; int token;
@ -1247,11 +1248,25 @@ xfs_fs_remount(
} }
} }
/* rw/ro -> rw */ /* ro -> rw */
if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
mp->m_flags &= ~XFS_MOUNT_RDONLY; mp->m_flags &= ~XFS_MOUNT_RDONLY;
if (mp->m_flags & XFS_MOUNT_BARRIER) if (mp->m_flags & XFS_MOUNT_BARRIER)
xfs_mountfs_check_barriers(mp); xfs_mountfs_check_barriers(mp);
/*
* If this is the first remount to writeable state we
* might have some superblock changes to update.
*/
if (mp->m_update_flags) {
error = xfs_mount_log_sb(mp, mp->m_update_flags);
if (error) {
cmn_err(CE_WARN,
"XFS: failed to write sb changes");
return error;
}
mp->m_update_flags = 0;
}
} }
/* rw -> ro */ /* rw -> ro */

View File

@ -45,7 +45,6 @@
#include "xfs_fsops.h" #include "xfs_fsops.h"
#include "xfs_utils.h" #include "xfs_utils.h"
STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
STATIC int xfs_uuid_mount(xfs_mount_t *); STATIC int xfs_uuid_mount(xfs_mount_t *);
STATIC void xfs_unmountfs_wait(xfs_mount_t *); STATIC void xfs_unmountfs_wait(xfs_mount_t *);
@ -682,7 +681,7 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
* Update alignment values based on mount options and sb values * Update alignment values based on mount options and sb values
*/ */
STATIC int STATIC int
xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags) xfs_update_alignment(xfs_mount_t *mp)
{ {
xfs_sb_t *sbp = &(mp->m_sb); xfs_sb_t *sbp = &(mp->m_sb);
@ -736,11 +735,11 @@ xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags)
if (xfs_sb_version_hasdalign(sbp)) { if (xfs_sb_version_hasdalign(sbp)) {
if (sbp->sb_unit != mp->m_dalign) { if (sbp->sb_unit != mp->m_dalign) {
sbp->sb_unit = mp->m_dalign; sbp->sb_unit = mp->m_dalign;
*update_flags |= XFS_SB_UNIT; mp->m_update_flags |= XFS_SB_UNIT;
} }
if (sbp->sb_width != mp->m_swidth) { if (sbp->sb_width != mp->m_swidth) {
sbp->sb_width = mp->m_swidth; sbp->sb_width = mp->m_swidth;
*update_flags |= XFS_SB_WIDTH; mp->m_update_flags |= XFS_SB_WIDTH;
} }
} }
} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
@ -905,7 +904,6 @@ xfs_mountfs(
xfs_sb_t *sbp = &(mp->m_sb); xfs_sb_t *sbp = &(mp->m_sb);
xfs_inode_t *rip; xfs_inode_t *rip;
__uint64_t resblks; __uint64_t resblks;
__int64_t update_flags = 0LL;
uint quotamount, quotaflags; uint quotamount, quotaflags;
int uuid_mounted = 0; int uuid_mounted = 0;
int error = 0; int error = 0;
@ -933,7 +931,7 @@ xfs_mountfs(
"XFS: correcting sb_features alignment problem"); "XFS: correcting sb_features alignment problem");
sbp->sb_features2 |= sbp->sb_bad_features2; sbp->sb_features2 |= sbp->sb_bad_features2;
sbp->sb_bad_features2 = sbp->sb_features2; sbp->sb_bad_features2 = sbp->sb_features2;
update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
/* /*
* Re-check for ATTR2 in case it was found in bad_features2 * Re-check for ATTR2 in case it was found in bad_features2
@ -947,11 +945,11 @@ xfs_mountfs(
if (xfs_sb_version_hasattr2(&mp->m_sb) && if (xfs_sb_version_hasattr2(&mp->m_sb) &&
(mp->m_flags & XFS_MOUNT_NOATTR2)) { (mp->m_flags & XFS_MOUNT_NOATTR2)) {
xfs_sb_version_removeattr2(&mp->m_sb); xfs_sb_version_removeattr2(&mp->m_sb);
update_flags |= XFS_SB_FEATURES2; mp->m_update_flags |= XFS_SB_FEATURES2;
/* update sb_versionnum for the clearing of the morebits */ /* update sb_versionnum for the clearing of the morebits */
if (!sbp->sb_features2) if (!sbp->sb_features2)
update_flags |= XFS_SB_VERSIONNUM; mp->m_update_flags |= XFS_SB_VERSIONNUM;
} }
/* /*
@ -960,7 +958,7 @@ xfs_mountfs(
* allocator alignment is within an ag, therefore ag has * allocator alignment is within an ag, therefore ag has
* to be aligned at stripe boundary. * to be aligned at stripe boundary.
*/ */
error = xfs_update_alignment(mp, &update_flags); error = xfs_update_alignment(mp);
if (error) if (error)
goto error1; goto error1;
@ -1137,10 +1135,12 @@ xfs_mountfs(
} }
/* /*
* If fs is not mounted readonly, then update the superblock changes. * If this is a read-only mount defer the superblock updates until
* the next remount into writeable mode. Otherwise we would never
* perform the update e.g. for the root filesystem.
*/ */
if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
error = xfs_mount_log_sb(mp, update_flags); error = xfs_mount_log_sb(mp, mp->m_update_flags);
if (error) { if (error) {
cmn_err(CE_WARN, "XFS: failed to write sb changes"); cmn_err(CE_WARN, "XFS: failed to write sb changes");
goto error4; goto error4;
@ -1820,7 +1820,7 @@ xfs_uuid_mount(
* be altered by the mount options, as well as any potential sb_features2 * be altered by the mount options, as well as any potential sb_features2
* fixup. Only the first superblock is updated. * fixup. Only the first superblock is updated.
*/ */
STATIC int int
xfs_mount_log_sb( xfs_mount_log_sb(
xfs_mount_t *mp, xfs_mount_t *mp,
__int64_t fields) __int64_t fields)

View File

@ -327,6 +327,8 @@ typedef struct xfs_mount {
spinlock_t m_sync_lock; /* work item list lock */ spinlock_t m_sync_lock; /* work item list lock */
int m_sync_seq; /* sync thread generation no. */ int m_sync_seq; /* sync thread generation no. */
wait_queue_head_t m_wait_single_sync_task; wait_queue_head_t m_wait_single_sync_task;
__int64_t m_update_flags; /* sb flags we need to update
on the next remount,rw */
} xfs_mount_t; } xfs_mount_t;
/* /*
@ -514,6 +516,7 @@ extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
int64_t, int); int64_t, int);
extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
uint, int); uint, int);
extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
extern int xfs_readsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int);
extern void xfs_freesb(xfs_mount_t *); extern void xfs_freesb(xfs_mount_t *);