diff options
author | tegge <tegge@FreeBSD.org> | 2006-05-03 00:29:22 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2006-05-03 00:29:22 +0000 |
commit | 581c3c81537dc544744b18bab247968aa7b6d5f6 (patch) | |
tree | f9fa84ac18135f5288d000ff693d100f7894a453 /sys/ufs | |
parent | e2c33fcc897dcf0c3c6d88080a723627e4ba4860 (diff) | |
download | FreeBSD-src-581c3c81537dc544744b18bab247968aa7b6d5f6.zip FreeBSD-src-581c3c81537dc544744b18bab247968aa7b6d5f6.tar.gz |
Detect the snapshot file being prematurely unlinked.
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_snapshot.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index eff466d..a00d5e9 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -406,6 +406,11 @@ restart: vn_start_write(NULL, &wrtmp, V_WAIT); } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); + if (ip->i_effnlink == 0) { + error = ENOENT; /* Snapshot file unlinked */ + sn = NULL; + goto out1; + } if (collectsnapstats) nanotime(&starttime); /* @@ -764,12 +769,17 @@ out1: * the inode for this snapshot then a deadlock can occur. Drop * the snapshot lock until the buffer has been written. */ + VREF(vp); /* Protect against ffs_snapgone() */ VOP_UNLOCK(vp, 0, td); (void) bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), (int) fs->fs_bsize, NOCRED, &nbp); brelse(nbp); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); + if (ip->i_effnlink == 0) + error = ENOENT; /* Snapshot file unlinked */ + else + vrele(vp); /* Drop extra reference */ done: FREE(copy_fs->fs_csp, M_UFSMNT); bawrite(sbp); |