Page MenuHomeFreeBSD

D33921.id101571.diff
No OneTemporary

D33921.id101571.diff

diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1702,7 +1702,7 @@
if (freebufs == bd->bd_lofreebuffers)
bufspace_daemon_wakeup(bd);
- error = BUF_LOCK(bp, LK_EXCLUSIVE, NULL);
+ error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL);
KASSERT(error == 0, ("%s: BUF_LOCK on free buf %p: %d.", __func__, bp,
error));
(void)error;
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -179,7 +179,7 @@
pause("ffsupd", 1);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
vrele(vp);
- if (VN_IS_DOOMED(vp))
+ if (!IS_UFS(vp))
return (ENOENT);
/*
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -646,7 +646,7 @@
off_t bytesinfile;
long size, xfersize, blkoffset;
ssize_t orig_resid;
- int bflag, error, ioflag, seqcount;
+ int bflag, error, ioflag, locked, seqcount;
vp = ap->a_vp;
uio = ap->a_uio;
@@ -690,7 +690,9 @@
uio->uio_offset >= fs->fs_maxfilesize)
return (EOVERFLOW);
- bflag = GB_UNMAPPED | (uio->uio_segflg == UIO_NOCOPY ? 0 : GB_NOSPARSE);
+ bflag = GB_UNMAPPED |
+ (uio->uio_segflg == UIO_NOCOPY ? 0 : GB_NOSPARSE) |
+ (IS_SNAPSHOT(ip) ? GB_LOCK_NOWAIT : 0);
for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
break;
@@ -759,6 +761,18 @@
*/
error = bread_gb(vp, lbn, size, NOCRED, bflag, &bp);
}
+ if (error == EBUSY && IS_SNAPSHOT(ip)) {
+ /* Read of a snapshot, block is busy. */
+ locked = VOP_ISLOCKED(vp);
+ VOP_UNLOCK(vp);
+ pause("slkrd", 1);
+ vn_lock(vp, locked | LK_RETRY);
+ if (!IS_UFS(vp)) {
+ error = EBADF;
+ break;
+ }
+ continue;
+ }
if (error == EJUSTRETURN) {
error = ffs_read_hole(uio, xfersize, &size);
if (error == 0)
@@ -2066,7 +2080,7 @@
* and respond to dead vnodes by returning ESTALE.
*/
VOP_LOCK(vp, vp_locked | LK_RETRY);
- if (!VN_IS_DOOMED(vp))
+ if (IS_UFS(vp))
return (0);
/*
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -247,6 +247,7 @@
} while (0)
#define IS_SNAPSHOT(ip) ((ip)->i_flags & SF_SNAPSHOT)
+#define IS_UFS(vp) ((vp)->v_data != NULL)
/*
* Structure used to pass around logical block paths generated by

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 12, 12:34 PM (8 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29582473
Default Alt Text
D33921.id101571.diff (2 KB)

Event Timeline