Module Name: src
Committed By: snj
Date: Sun Mar 28 17:28:34 UTC 2010
Modified Files:
src/sys/ufs/ffs [netbsd-5]: ffs_snapshot.c
Log Message:
Pull up following revision(s) (requested by hannken in ticket #1345):
sys/ufs/ffs/ffs_snapshot.c: revision 1.97
No longer abuse TAILQ internal data.
To generate a diff of this commit:
cvs rdiff -u -r1.82.4.2 -r1.82.4.3 src/sys/ufs/ffs/ffs_snapshot.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/ufs/ffs/ffs_snapshot.c
diff -u src/sys/ufs/ffs/ffs_snapshot.c:1.82.4.2 src/sys/ufs/ffs/ffs_snapshot.c:1.82.4.3
--- src/sys/ufs/ffs/ffs_snapshot.c:1.82.4.2 Sun Mar 28 17:27:29 2010
+++ src/sys/ufs/ffs/ffs_snapshot.c Sun Mar 28 17:28:33 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_snapshot.c,v 1.82.4.2 2010/03/28 17:27:29 snj Exp $ */
+/* $NetBSD: ffs_snapshot.c,v 1.82.4.3 2010/03/28 17:28:33 snj 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.82.4.2 2010/03/28 17:27:29 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.82.4.3 2010/03/28 17:28:33 snj Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -76,6 +76,14 @@
#include <uvm/uvm.h>
+struct snap_info {
+ kmutex_t si_lock; /* Lock this snapinfo */
+ kmutex_t si_snaplock; /* Snapshot vnode common lock */
+ TAILQ_HEAD(inodelst, inode) si_snapshots; /* List of active snapshots */
+ daddr_t *si_snapblklist; /* Snapshot block hints list */
+ uint32_t si_gen; /* Incremented on change */
+};
+
#if !defined(FFS_NO_SNAPSHOT)
typedef int (*acctfunc_t)
(struct vnode *, void *, int, int, struct fs *, daddr_t, int);
@@ -107,6 +115,7 @@
static int syncsnap(struct vnode *);
static int wrsnapblk(struct vnode *, void *, daddr_t);
+static inline bool is_active_snapshot(struct snap_info *, struct inode *);
static inline daddr_t db_get(struct inode *, int);
static inline void db_assign(struct inode *, int, daddr_t);
static inline daddr_t ib_get(struct inode *, int);
@@ -114,14 +123,6 @@
static inline daddr_t idb_get(struct inode *, void *, int);
static inline void idb_assign(struct inode *, void *, int, daddr_t);
-struct snap_info {
- kmutex_t si_lock; /* Lock this snapinfo */
- kmutex_t si_snaplock; /* Snapshot vnode common lock */
- TAILQ_HEAD(inodelst, inode) si_snapshots; /* List of active snapshots */
- daddr_t *si_snapblklist; /* Snapshot block hints list */
- uint32_t si_gen; /* Incremented on change */
-};
-
#ifdef DEBUG
static int snapdebug = 0;
#endif
@@ -277,7 +278,7 @@
fs->fs_snapinum[snaploc] = ip->i_number;
mutex_enter(&si->si_lock);
- if (ip->i_nextsnap.tqe_prev != 0)
+ if (is_active_snapshot(si, ip))
panic("ffs_snapshot: %"PRIu64" already on list", ip->i_number);
TAILQ_INSERT_TAIL(&si->si_snapshots, ip, i_nextsnap);
if (TAILQ_FIRST(&si->si_snapshots) == ip) {
@@ -1321,10 +1322,9 @@
*
* Clear copy-on-write flag if last snapshot.
*/
- if (ip->i_nextsnap.tqe_prev != 0) {
- mutex_enter(&si->si_lock);
+ mutex_enter(&si->si_lock);
+ if (is_active_snapshot(si, ip)) {
TAILQ_REMOVE(&si->si_snapshots, ip, i_nextsnap);
- ip->i_nextsnap.tqe_prev = 0;
if (TAILQ_FIRST(&si->si_snapshots) != 0) {
/* Roll back the list of preallocated blocks. */
xp = TAILQ_LAST(&si->si_snapshots, inodelst);
@@ -1341,7 +1341,8 @@
free(ip->i_snapblklist, M_UFSMNT);
ip->i_snapblklist = NULL;
}
- }
+ } else
+ mutex_exit(&si->si_lock);
/*
* Clear all BLK_NOCOPY fields. Pass any block claims to other
* snapshots that want them (see ffs_snapblkfree below).
@@ -1681,9 +1682,9 @@
/*
* Link it onto the active snapshot list.
*/
- if (ip->i_nextsnap.tqe_prev != 0)
- panic("ffs_snapshot_mount: %llu already on list",
- (unsigned long long)ip->i_number);
+ if (is_active_snapshot(si, ip))
+ panic("ffs_snapshot_mount: %"PRIu64" already on list",
+ ip->i_number);
else
TAILQ_INSERT_TAIL(&si->si_snapshots, ip, i_nextsnap);
vp->v_vflag |= VV_SYSTEM;
@@ -1724,7 +1725,6 @@
vp = ITOV(xp);
vp->v_vnlock = &vp->v_lock;
TAILQ_REMOVE(&si->si_snapshots, xp, i_nextsnap);
- xp->i_nextsnap.tqe_prev = 0;
if (xp->i_snapblklist == si->si_snapblklist)
si->si_snapblklist = NULL;
FREE(xp->i_snapblklist, M_UFSMNT);
@@ -2125,6 +2125,23 @@
}
/*
+ * Check if this inode is present on the active snapshot list.
+ * Must be called with snapinfo locked.
+ */
+static inline bool
+is_active_snapshot(struct snap_info *si, struct inode *ip)
+{
+ struct inode *xp;
+
+ KASSERT(mutex_owned(&si->si_lock));
+
+ TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap)
+ if (xp == ip)
+ return true;
+ return false;
+}
+
+/*
* Get/Put direct block from inode or buffer containing disk addresses. Take
* care for fs type (UFS1/UFS2) and byte swapping. These functions should go
* into a global include.