Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ffs Refine the scope of WAPBL transactions so we sho...
details: https://anonhg.NetBSD.org/src/rev/cfa0de4895ec
branches: trunk
changeset: 762158:cfa0de4895ec
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Feb 16 19:43:50 2011 +0000
description:
Refine the scope of WAPBL transactions so we should no longer get
a "wapbl_flush: current transaction too big to flush" panic when
creating or removing snapshots on larger logging disks.
Adresses PR #44568 (WAPBL doens't play nice with snapshots).
diffstat:
sys/ufs/ffs/ffs_snapshot.c | 155 +++++++++++++++++++++++++++++++++-----------
1 files changed, 116 insertions(+), 39 deletions(-)
diffs (truncated from 408 to 300 lines):
diff -r 1e35eedfad09 -r cfa0de4895ec sys/ufs/ffs/ffs_snapshot.c
--- a/sys/ufs/ffs/ffs_snapshot.c Wed Feb 16 19:43:05 2011 +0000
+++ b/sys/ufs/ffs/ffs_snapshot.c Wed Feb 16 19:43:50 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_snapshot.c,v 1.102 2010/12/20 00:25:47 matt Exp $ */
+/* $NetBSD: ffs_snapshot.c,v 1.103 2011/02/16 19:43:50 hannken Exp $ */
/*
* Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102 2010/12/20 00:25:47 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.103 2011/02/16 19:43:50 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -114,6 +114,7 @@
static int rwfsblk(struct vnode *, int, void *, daddr_t);
static int syncsnap(struct vnode *);
static int wrsnapblk(struct vnode *, void *, daddr_t);
+static int blocks_in_journal(struct fs *);
static inline bool is_active_snapshot(struct snap_info *, struct inode *);
static inline daddr_t db_get(struct inode *, int);
@@ -403,11 +404,12 @@
static int
snapshot_setup(struct mount *mp, struct vnode *vp)
{
- int error, i, len, loc;
+ int error, n, len, loc;
daddr_t blkno, numblks;
struct buf *ibp, *nbp;
struct fs *fs = VFSTOUFS(mp)->um_fs;
struct lwp *l = curlwp;
+ const int wbreak = blocks_in_journal(fs)/8;
/*
* Check mount, exclusive reference and owner.
@@ -452,13 +454,13 @@
error = UFS_WAPBL_BEGIN(mp);
if (error)
return error;
- for (blkno = NDADDR, i = 0; blkno < numblks; blkno += NINDIR(fs)) {
+ for (blkno = NDADDR, n = 0; blkno < numblks; blkno += NINDIR(fs)) {
error = ffs_balloc(vp, lblktosize(fs, (off_t)blkno),
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp);
if (error)
goto out;
brelse(ibp, 0);
- if ((++i % 16) == 0) {
+ if (wbreak > 0 && (++n % wbreak) == 0) {
UFS_WAPBL_END(mp);
error = UFS_WAPBL_BEGIN(mp);
if (error)
@@ -561,7 +563,6 @@
snapshot_expunge(struct mount *mp, struct vnode *vp, struct fs *copy_fs,
daddr_t *snaplistsize, daddr_t **snaplist)
{
- bool has_wapbl = false;
int cg, error, len, loc;
daddr_t blkno, *blkp;
struct fs *fs = VFSTOUFS(mp)->um_fs;
@@ -593,10 +594,6 @@
*/
*snaplistsize = fs->fs_ncg + howmany(fs->fs_cssize, fs->fs_bsize) +
FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */;
- error = UFS_WAPBL_BEGIN(mp);
- if (error)
- goto out;
- has_wapbl = true;
mutex_enter(&mntvnode_lock);
/*
* NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
@@ -648,19 +645,30 @@
if (loc < NDADDR) {
len = fragroundup(fs, blkoff(fs, xp->i_size));
if (len > 0 && len < fs->fs_bsize) {
+ error = UFS_WAPBL_BEGIN(mp);
+ if (error) {
+ (void)vunmark(mvp);
+ goto out;
+ }
ffs_blkfree_snap(copy_fs, vp, db_get(xp, loc),
len, xp->i_number);
blkno = db_get(xp, loc);
db_assign(xp, loc, 0);
+ UFS_WAPBL_END(mp);
}
}
*snaplistsize += 1;
error = expunge(vp, xp, copy_fs, fullacct, BLK_NOCOPY);
if (blkno)
db_assign(xp, loc, blkno);
- if (!error)
- error = ffs_freefile_snap(copy_fs, vp, xp->i_number,
- xp->i_mode);
+ if (!error) {
+ error = UFS_WAPBL_BEGIN(mp);
+ if (!error) {
+ error = ffs_freefile_snap(copy_fs, vp,
+ xp->i_number, xp->i_mode);
+ UFS_WAPBL_END(mp);
+ }
+ }
if (error) {
(void)vunmark(mvp);
goto out;
@@ -688,8 +696,6 @@
(*snaplist)[0] = blkp - &(*snaplist)[0];
out:
- if (has_wapbl)
- UFS_WAPBL_END(mp);
if (mvp != NULL)
vnfree(mvp);
if (logvp != NULL)
@@ -711,16 +717,13 @@
snapshot_expunge_snap(struct mount *mp, struct vnode *vp,
struct fs *copy_fs, daddr_t snaplistsize)
{
- int error, i;
+ int error = 0, i;
daddr_t numblks, *snaplist = NULL;
struct fs *fs = VFSTOUFS(mp)->um_fs;
struct inode *ip = VTOI(vp), *xp;
struct lwp *l = curlwp;
struct snap_info *si = VFSTOUFS(mp)->um_snapinfo;
- error = UFS_WAPBL_BEGIN(mp);
- if (error)
- return error;
TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap) {
if (xp == ip)
break;
@@ -729,7 +732,11 @@
break;
if (xp->i_nlink != 0)
continue;
+ error = UFS_WAPBL_BEGIN(mp);
+ if (error)
+ break;
error = ffs_freefile_snap(copy_fs, vp, xp->i_number, xp->i_mode);
+ UFS_WAPBL_END(mp);
if (error)
break;
}
@@ -761,12 +768,10 @@
snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs));
error = vn_rdwr(UIO_WRITE, vp, (void *)snaplist,
snaplistsize * sizeof(daddr_t), lblktosize(fs, (off_t)numblks),
- UIO_SYSSPACE, IO_NODELOCKED | IO_JOURNALLOCKED | IO_UNIT,
- l->l_cred, NULL, NULL);
+ UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, l->l_cred, NULL, NULL);
for (i = 0; i < snaplistsize; i++)
snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs));
out:
- UFS_WAPBL_END(mp);
if (error && snaplist != NULL) {
free(snaplist, M_UFSMNT);
ip->i_snapblklist = NULL;
@@ -859,13 +864,10 @@
static int
cgaccount(struct vnode *vp, int passno, int *redo)
{
- int cg, error;
+ int cg, error = 0;
struct buf *nbp;
struct fs *fs = VTOI(vp)->i_fs;
- error = UFS_WAPBL_BEGIN(vp->v_mount);
- if (error)
- return error;
if (redo != NULL)
*redo = 0;
if (passno == 1)
@@ -874,18 +876,24 @@
for (cg = 0; cg < fs->fs_ncg; cg++) {
if (passno == 2 && ACTIVECG_ISSET(fs, cg))
continue;
+
if (redo != NULL)
*redo += 1;
+ error = UFS_WAPBL_BEGIN(vp->v_mount);
+ if (error)
+ return error;
error = ffs_balloc(vp, lfragtosize(fs, cgtod(fs, cg)),
fs->fs_bsize, curlwp->l_cred, 0, &nbp);
- if (error)
+ if (error) {
+ UFS_WAPBL_END(vp->v_mount);
break;
+ }
error = cgaccount1(cg, vp, nbp->b_data, passno);
bawrite(nbp);
+ UFS_WAPBL_END(vp->v_mount);
if (error)
break;
}
- UFS_WAPBL_END(vp->v_mount);
return error;
}
@@ -992,8 +1000,14 @@
struct lwp *l = curlwp;
void *bap;
struct buf *bp;
+ struct mount *mp;
ns = UFS_FSNEEDSWAP(fs);
+ mp = snapvp->v_mount;
+
+ error = UFS_WAPBL_BEGIN(mp);
+ if (error)
+ return error;
/*
* Prepare to expunge the inode. If its inode block has not
* yet been copied, then allocate and fill the copy.
@@ -1011,8 +1025,10 @@
if (! error)
error = rwfsblk(snapvp, B_READ, bp->b_data, lbn);
}
- if (error)
+ if (error) {
+ UFS_WAPBL_END(mp);
return error;
+ }
/*
* Set a snapshot inode to be a zero length file, regular files
* or unlinked snapshots to be completely unallocated.
@@ -1039,6 +1055,7 @@
memset(&dip2->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int64_t));
}
bdwrite(bp);
+ UFS_WAPBL_END(mp);
/*
* Now go through and expunge all the blocks in the file
* using the function requested.
@@ -1048,13 +1065,15 @@
bap = &cancelip->i_ffs1_db[0];
else
bap = &cancelip->i_ffs2_db[0];
- if ((error = (*acctfunc)(snapvp, bap, 0, NDADDR, fs, 0, expungetype)))
+ error = (*acctfunc)(snapvp, bap, 0, NDADDR, fs, 0, expungetype);
+ if (error)
return (error);
if (fs->fs_magic == FS_UFS1_MAGIC)
bap = &cancelip->i_ffs1_ib[0];
else
bap = &cancelip->i_ffs2_ib[0];
- if ((error = (*acctfunc)(snapvp, bap, 0, NIADDR, fs, -1, expungetype)))
+ error = (*acctfunc)(snapvp, bap, 0, NIADDR, fs, -1, expungetype);
+ if (error)
return (error);
blksperindir = 1;
lbn = -NDADDR;
@@ -1170,12 +1189,17 @@
{
struct inode *ip = VTOI(vp);
struct lwp *l = curlwp;
+ struct mount *mp = vp->v_mount;
daddr_t blkno;
daddr_t lbn;
struct buf *ibp;
- int error;
+ int error, n;
+ const int wbreak = blocks_in_journal(VFSTOUFS(mp)->um_fs)/8;
- for ( ; oldblkp < lastblkp; oldblkp++) {
+ error = UFS_WAPBL_BEGIN(mp);
+ if (error)
+ return error;
+ for ( n = 0; oldblkp < lastblkp; oldblkp++) {
blkno = idb_get(ip, bap, oldblkp);
if (blkno == 0 || blkno == BLK_NOCOPY || blkno == BLK_SNAP)
continue;
@@ -1187,7 +1211,7 @@
error = ffs_balloc(vp, lblktosize(fs, (off_t)lbn),
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp);
if (error)
- return (error);
+ break;
blkno = idb_get(ip, ibp->b_data,
(lbn - NDADDR) % NINDIR(fs));
}
@@ -1211,8 +1235,15 @@
bdwrite(ibp);
}
}
+ if (wbreak > 0 && (++n % wbreak) == 0) {
+ UFS_WAPBL_END(mp);
+ error = UFS_WAPBL_BEGIN(mp);
+ if (error)
+ return error;
+ }
}
- return (0);
+ UFS_WAPBL_END(mp);
+ return error;
Home |
Main Index |
Thread Index |
Old Index