Page MenuHomeFreeBSD

D38379.diff
No OneTemporary

D38379.diff

diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -2556,6 +2556,7 @@
vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
struct ucred *cred)
{
+ vm_object_t obj;
off_t size;
daddr_t bn, bnp;
uint64_t bsize;
@@ -2564,7 +2565,7 @@
KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
("%s: Wrong command %lu", __func__, cmd));
- ASSERT_VOP_LOCKED(vp, "vn_bmap_seekhole_locked");
+ ASSERT_VOP_ELOCKED(vp, "vn_bmap_seekhole_locked");
if (vp->v_type != VREG) {
error = ENOTTY;
@@ -2578,6 +2579,15 @@
error = ENXIO;
goto out;
}
+
+ /* See the comment in ufs_bmap_seekdata(). */
+ obj = vp->v_object;
+ if (obj != NULL) {
+ VM_OBJECT_WLOCK(obj);
+ vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_WUNLOCK(obj);
+ }
+
bsize = vp->v_mount->mnt_stat.f_iosize;
for (bn = noff / bsize; noff < size; bn++, noff += bsize -
noff % bsize) {
@@ -2613,7 +2623,7 @@
KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
("%s: Wrong command %lu", __func__, cmd));
- if (vn_lock(vp, LK_SHARED) != 0)
+ if (vn_lock(vp, LK_EXCLUSIVE) != 0)
return (EBADF);
error = vn_bmap_seekhole_locked(vp, cmd, off, cred);
VOP_UNLOCK(vp);
diff --git a/sys/ufs/ufs/ufs_bmap.c b/sys/ufs/ufs/ufs_bmap.c
--- a/sys/ufs/ufs/ufs_bmap.c
+++ b/sys/ufs/ufs/ufs_bmap.c
@@ -44,12 +44,16 @@
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/proc.h>
+#include <sys/rwlock.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+
#include <ufs/ufs/extattr.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
@@ -348,6 +352,7 @@
struct inode *ip;
struct mount *mp;
struct ufsmount *ump;
+ vm_object_t obj;
ufs2_daddr_t bn, daddr, nextbn;
uint64_t bsize;
off_t numblks;
@@ -364,6 +369,19 @@
if (*offp < 0 || *offp >= ip->i_size)
return (ENXIO);
+ /*
+ * We could have pages on the vnode' object queue which still
+ * do not have the data blocks allocated. Convert all dirty
+ * pages into buffer writes to ensure that we see all
+ * allocated data.
+ */
+ obj = vp->v_object;
+ if (obj != NULL) {
+ VM_OBJECT_WLOCK(obj);
+ vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_WUNLOCK(obj);
+ }
+
bsize = mp->mnt_stat.f_iosize;
for (bn = *offp / bsize, numblks = howmany(ip->i_size, bsize);
bn < numblks; bn = nextbn) {
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -2944,7 +2944,7 @@
vp = ap->a_vp;
switch (ap->a_command) {
case FIOSEEKDATA:
- error = vn_lock(vp, LK_SHARED);
+ error = vn_lock(vp, LK_EXCLUSIVE);
if (error == 0) {
error = ufs_bmap_seekdata(vp, (off_t *)ap->a_data);
VOP_UNLOCK(vp);

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 21, 10:43 AM (22 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14759717
Default Alt Text
D38379.diff (2 KB)

Event Timeline