Module Name: src
Committed By: tls
Date: Sun Feb 10 16:26:35 UTC 2013
Modified Files:
src/sys/dev/raidframe [tls-maxphys]: rf_disks.c
src/sys/kern [tls-maxphys]: subr_disk.c
src/sys/sys [tls-maxphys]: disk.h mount.h
src/sys/ufs/ffs [tls-maxphys]: ffs_vfsops.c
src/sys/ufs/ufs [tls-maxphys]: ufs_bmap.c ufs_extern.h ufs_readwrite.c
ufs_vfsops.c
Log Message:
Add an accessor -- ufs_maxphys() -- to check the maximum transfer size
for a given UFS mountpoint, and move the code from mount that finds
the underlying disk and resets the mountpoint max transfer size into a
utility function, ufs_update_maxphys().
Add a global serial number that counts disk property changes to which
filesystems are meant to accomodate themselves. Make ufs_maxphys()
check it. This is a sort of flag-polling interface that avoids callbacks
into the filesystem code, but will require freezing filesystems and
draining in-flight transactions before a decrease in size that is
mandatory (like attaching a disk with a smaller maximum transfer size
as a spare in a RAIDframe set), rather than "advisory", like finding
out set geometry from a RAID controller long after boot and deciding
a smaller transfer size would be optimal, can be signalled. Still, the
"advisory" case is the common one so this is progress.
Make a bit of an example of RAIDframe by making it bump this new
serial number when disks are added to the subsystem. I will attack
one of the hardware RAID drivers (probably arcmsr) next.
To generate a diff of this commit:
cvs rdiff -u -r1.83 -r1.83.2.1 src/sys/dev/raidframe/rf_disks.c
cvs rdiff -u -r1.100.18.2 -r1.100.18.3 src/sys/kern/subr_disk.c
cvs rdiff -u -r1.57.2.1 -r1.57.2.2 src/sys/sys/disk.h
cvs rdiff -u -r1.207.6.2 -r1.207.6.3 src/sys/sys/mount.h
cvs rdiff -u -r1.278.2.2 -r1.278.2.3 src/sys/ufs/ffs/ffs_vfsops.c
cvs rdiff -u -r1.49.14.1 -r1.49.14.2 src/sys/ufs/ufs/ufs_bmap.c
cvs rdiff -u -r1.72 -r1.72.2.1 src/sys/ufs/ufs/ufs_extern.h
cvs rdiff -u -r1.104.2.1 -r1.104.2.2 src/sys/ufs/ufs/ufs_readwrite.c
cvs rdiff -u -r1.51 -r1.51.2.1 src/sys/ufs/ufs/ufs_vfsops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/raidframe/rf_disks.c
diff -u src/sys/dev/raidframe/rf_disks.c:1.83 src/sys/dev/raidframe/rf_disks.c:1.83.2.1
--- src/sys/dev/raidframe/rf_disks.c:1.83 Thu Jul 19 22:47:52 2012
+++ src/sys/dev/raidframe/rf_disks.c Sun Feb 10 16:26:33 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_disks.c,v 1.83 2012/07/19 22:47:52 pooka Exp $ */
+/* $NetBSD: rf_disks.c,v 1.83.2.1 2013/02/10 16:26:33 tls Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -60,7 +60,7 @@
***************************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_disks.c,v 1.83 2012/07/19 22:47:52 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_disks.c,v 1.83.2.1 2013/02/10 16:26:33 tls Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -80,6 +80,8 @@ __KERNEL_RCSID(0, "$NetBSD: rf_disks.c,v
#include <sys/vnode.h>
#include <sys/namei.h> /* for pathbuf */
#include <sys/kauth.h>
+#include <sys/atomic.h>
+#include <sys/disk.h>
static int rf_AllocDiskStructures(RF_Raid_t *, RF_Config_t *);
static void rf_print_label_status( RF_Raid_t *, int, char *,
@@ -649,6 +651,15 @@ rf_ConfigureDisk(RF_Raid_t *raidPtr, cha
diskPtr->numBlocks = diskPtr->numBlocks *
rf_sizePercentage / 100;
}
+
+ /*
+ * Tell the rest of the kernel to check whether anything's
+ * maximum transfer size has changed -- like, for example,
+ * a filesystem that might be mounted on a set where we're
+ * adding a spare with a smaller maximum transfer size than
+ * the original set members.
+ */
+ atomic_inc_uint(&disk_serial);
return (0);
}
Index: src/sys/kern/subr_disk.c
diff -u src/sys/kern/subr_disk.c:1.100.18.2 src/sys/kern/subr_disk.c:1.100.18.3
--- src/sys/kern/subr_disk.c:1.100.18.2 Sun Dec 2 05:46:40 2012
+++ src/sys/kern/subr_disk.c Sun Feb 10 16:26:33 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_disk.c,v 1.100.18.2 2012/12/02 05:46:40 tls Exp $ */
+/* $NetBSD: subr_disk.c,v 1.100.18.3 2013/02/10 16:26:33 tls Exp $ */
/*-
* Copyright (c) 1996, 1997, 1999, 2000, 2009 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.100.18.2 2012/12/02 05:46:40 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.100.18.3 2013/02/10 16:26:33 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -80,6 +80,8 @@ __KERNEL_RCSID(0, "$NetBSD: subr_disk.c,
#include <sys/sysctl.h>
#include <lib/libkern/libkern.h>
+unsigned int disk_serial;
+
/*
* Compute checksum for disk label.
*/
Index: src/sys/sys/disk.h
diff -u src/sys/sys/disk.h:1.57.2.1 src/sys/sys/disk.h:1.57.2.2
--- src/sys/sys/disk.h:1.57.2.1 Wed Sep 12 06:15:35 2012
+++ src/sys/sys/disk.h Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: disk.h,v 1.57.2.1 2012/09/12 06:15:35 tls Exp $ */
+/* $NetBSD: disk.h,v 1.57.2.2 2013/02/10 16:26:34 tls Exp $ */
/*-
* Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc.
@@ -509,7 +509,7 @@ struct disk_strategy {
#ifdef _KERNEL
extern int disk_count; /* number of disks in global disklist */
-
+extern unsigned int disk_serial; /* some disk's properties changed */
struct proc;
void disk_attach(struct disk *);
Index: src/sys/sys/mount.h
diff -u src/sys/sys/mount.h:1.207.6.2 src/sys/sys/mount.h:1.207.6.3
--- src/sys/sys/mount.h:1.207.6.2 Tue Nov 20 03:02:51 2012
+++ src/sys/sys/mount.h Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mount.h,v 1.207.6.2 2012/11/20 03:02:51 tls Exp $ */
+/* $NetBSD: mount.h,v 1.207.6.3 2013/02/10 16:26:34 tls Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@@ -122,6 +122,7 @@ struct mount {
int mnt_iflag; /* internal flags */
int mnt_fs_bshift; /* offset shift for lblkno */
int mnt_dev_bshift; /* shift for device sectors */
+ unsigned int mnt_dev_serial; /* when maxphys etc. updated */
uint32_t mnt_maxphys; /* largest xfer allowed */
struct statvfs mnt_stat; /* cache of filesystem stats */
specificdata_reference
Index: src/sys/ufs/ffs/ffs_vfsops.c
diff -u src/sys/ufs/ffs/ffs_vfsops.c:1.278.2.2 src/sys/ufs/ffs/ffs_vfsops.c:1.278.2.3
--- src/sys/ufs/ffs/ffs_vfsops.c:1.278.2.2 Tue Nov 20 03:02:53 2012
+++ src/sys/ufs/ffs/ffs_vfsops.c Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_vfsops.c,v 1.278.2.2 2012/11/20 03:02:53 tls Exp $ */
+/* $NetBSD: ffs_vfsops.c,v 1.278.2.3 2013/02/10 16:26:34 tls Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.278.2.2 2012/11/20 03:02:53 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.278.2.3 2013/02/10 16:26:34 tls Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -881,7 +881,6 @@ ffs_mountfs(struct vnode *devvp, struct
struct buf *bp;
struct fs *fs;
dev_t dev;
- struct disk *diskp;
struct dkwedge_info dkw;
void *space;
daddr_t sblockloc, fsblockloc;
@@ -897,9 +896,6 @@ ffs_mountfs(struct vnode *devvp, struct
int32_t fsbsize;
dev = devvp->v_rdev;
- if ((diskp = disk_find_blk(dev)) == NULL) {
- panic("no disk for device %d %d", major(dev), DISKUNIT(dev));
- }
cred = l ? l->l_cred : NOCRED;
@@ -922,13 +918,6 @@ ffs_mountfs(struct vnode *devvp, struct
if (error)
return error;
- /*
- * Get the maximum I/O size for the underlying device.
- */
- mp->mnt_maxphys = disk_maxphys(diskp);
- aprint_debug("ffs_mount: disk %s maxphys %d\n",
- diskp->dk_name, mp->mnt_maxphys);
-
ump = kmem_zalloc(sizeof(*ump), KM_SLEEP);
mutex_init(&ump->um_lock, MUTEX_DEFAULT, IPL_NONE);
error = ffs_snapshot_init(ump);
@@ -1270,8 +1259,13 @@ ffs_mountfs(struct vnode *devvp, struct
for (i = 0; i < MAXQUOTAS; i++)
ump->um_quotas[i] = NULLVP;
devvp->v_specmountpoint = mp;
+
+ /* Before we start WAPBL or touch any snapshots, adjust maxphys */
+ ufs_update_maxphys(mp);
+
if (ronly == 0 && fs->fs_snapinum[0] != 0)
ffs_snapshot_mount(mp);
+
#ifdef WAPBL
if (!ronly) {
KDASSERT(fs->fs_ronly == 0);
Index: src/sys/ufs/ufs/ufs_bmap.c
diff -u src/sys/ufs/ufs/ufs_bmap.c:1.49.14.1 src/sys/ufs/ufs/ufs_bmap.c:1.49.14.2
--- src/sys/ufs/ufs/ufs_bmap.c:1.49.14.1 Tue Oct 9 21:53:03 2012
+++ src/sys/ufs/ufs/ufs_bmap.c Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_bmap.c,v 1.49.14.1 2012/10/09 21:53:03 bouyer Exp $ */
+/* $NetBSD: ufs_bmap.c,v 1.49.14.2 2013/02/10 16:26:34 tls Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v 1.49.14.1 2012/10/09 21:53:03 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v 1.49.14.2 2013/02/10 16:26:34 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -143,7 +143,7 @@ ufs_bmaparray(struct vnode *vp, daddr_t
* don't create a block larger than the device can handle.
*/
*runp = 0;
- maxrun = mp->mnt_maxphys / mp->mnt_stat.f_iosize - 1;
+ maxrun = ufs_maxphys(mp) / mp->mnt_stat.f_iosize - 1;
}
if (bn >= 0 && bn < NDADDR) {
Index: src/sys/ufs/ufs/ufs_extern.h
diff -u src/sys/ufs/ufs/ufs_extern.h:1.72 src/sys/ufs/ufs/ufs_extern.h:1.72.2.1
--- src/sys/ufs/ufs/ufs_extern.h:1.72 Wed May 9 00:21:18 2012
+++ src/sys/ufs/ufs/ufs_extern.h Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_extern.h,v 1.72 2012/05/09 00:21:18 riastradh Exp $ */
+/* $NetBSD: ufs_extern.h,v 1.72.2.1 2013/02/10 16:26:34 tls Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -35,6 +35,7 @@
#define _UFS_UFS_EXTERN_H_
#include <sys/mutex.h>
+#include <sys/disk.h>
struct buf;
struct componentname;
@@ -188,9 +189,20 @@ void ufs_reinit(void);
void ufs_done(void);
int ufs_start(struct mount *, int);
int ufs_root(struct mount *, struct vnode **);
+void ufs_update_maxphys(struct mount *);
int ufs_quotactl(struct mount *, struct quotactl_args *);
int ufs_fhtovp(struct mount *, struct ufid *, struct vnode **);
+static inline uint32_t
+ufs_maxphys(struct mount *mp)
+{
+ while (__predict_false(mp->mnt_dev_serial != disk_serial)) {
+ ufs_update_maxphys(mp);
+ }
+
+ return mp->mnt_maxphys;
+}
+
/* ufs_vnops.c */
void ufs_vinit(struct mount *, int (**)(void *),
int (**)(void *), struct vnode **);
Index: src/sys/ufs/ufs/ufs_readwrite.c
diff -u src/sys/ufs/ufs/ufs_readwrite.c:1.104.2.1 src/sys/ufs/ufs/ufs_readwrite.c:1.104.2.2
--- src/sys/ufs/ufs/ufs_readwrite.c:1.104.2.1 Sun Oct 14 14:33:32 2012
+++ src/sys/ufs/ufs/ufs_readwrite.c Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_readwrite.c,v 1.104.2.1 2012/10/14 14:33:32 tls Exp $ */
+/* $NetBSD: ufs_readwrite.c,v 1.104.2.2 2013/02/10 16:26:34 tls Exp $ */
/*-
* Copyright (c) 1993
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.104.2.1 2012/10/14 14:33:32 tls Exp $");
+__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.104.2.2 2013/02/10 16:26:34 tls Exp $");
#ifdef LFS_READWRITE
#define FS struct lfs
@@ -415,7 +415,7 @@ WRITE(void *v)
#ifndef LFS_READWRITE
{
- int maximum = vp->v_mount->mnt_maxphys;
+ int maximum = ufs_maxphys(vp->v_mount);
off_t oldchunk, newchunk;
oldchunk = (oldoff / maximum) * maximum;
Index: src/sys/ufs/ufs/ufs_vfsops.c
diff -u src/sys/ufs/ufs/ufs_vfsops.c:1.51 src/sys/ufs/ufs/ufs_vfsops.c:1.51.2.1
--- src/sys/ufs/ufs/ufs_vfsops.c:1.51 Wed Apr 4 19:52:48 2012
+++ src/sys/ufs/ufs/ufs_vfsops.c Sun Feb 10 16:26:34 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_vfsops.c,v 1.51 2012/04/04 19:52:48 tron Exp $ */
+/* $NetBSD: ufs_vfsops.c,v 1.51.2.1 2013/02/10 16:26:34 tls Exp $ */
/*
* Copyright (c) 1991, 1993, 1994
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.51 2012/04/04 19:52:48 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.51.2.1 2013/02/10 16:26:34 tls Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -52,6 +52,8 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c
#include <sys/vnode.h>
#include <sys/kmem.h>
#include <sys/kauth.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
#include <miscfs/specfs/specdev.h>
@@ -97,6 +99,36 @@ ufs_root(struct mount *mp, struct vnode
}
/*
+ * Get (from disk) and set (to mount structure) maximum I/O size
+ */
+
+void
+ufs_update_maxphys(struct mount *mp)
+{
+ struct ufsmount *ump;
+ dev_t dev;
+ struct disk *diskp;
+
+ ump = VFSTOUFS(mp);
+ dev = ump->um_dev;
+
+ mutex_enter(&mp->mnt_updating);
+
+ if ((diskp = disk_find_blk(dev)) == NULL) {
+ panic("no disk for device %d %d", major(dev), DISKUNIT(dev));
+ }
+
+ /*
+ * Get the maximum I/O size for the underlying device.
+ */
+ mp->mnt_dev_serial = disk_serial;
+ mp->mnt_maxphys = disk_maxphys(diskp);
+ aprint_debug("ufs_update_maxphys: disk %s maxphys %d\n",
+ diskp->dk_name, mp->mnt_maxphys);
+ mutex_exit(&mp->mnt_updating);
+}
+
+/*
* Do operations associated with quotas
*/
int