Generalize ffs_pages_remove() into vn_pages_remove().
Remove mapped pages for all dataset vnodes in zfs_rezget() using new vn_pages_remove() to fix mmapped files changed by zfs rollback or zfs receive -F. PR: kern/160035, kern/156933 Reviewed by: kib, pjd Approved by: re (kib) MFC after: 1 week
This commit is contained in:
parent
631a8abdff
commit
e104c96f01
@ -1273,6 +1273,7 @@ zfs_rezget(znode_t *zp)
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
dmu_object_info_t doi;
|
||||
dmu_buf_t *db;
|
||||
vnode_t *vp;
|
||||
uint64_t obj_num = zp->z_id;
|
||||
uint64_t mode, size;
|
||||
sa_bulk_attr_t bulk[8];
|
||||
@ -1348,8 +1349,9 @@ zfs_rezget(znode_t *zp)
|
||||
* that for example regular file was replaced with directory
|
||||
* which has the same object number.
|
||||
*/
|
||||
if (ZTOV(zp) != NULL &&
|
||||
ZTOV(zp)->v_type != IFTOVT((mode_t)zp->z_mode)) {
|
||||
vp = ZTOV(zp);
|
||||
if (vp != NULL &&
|
||||
vp->v_type != IFTOVT((mode_t)zp->z_mode)) {
|
||||
zfs_znode_dmu_fini(zp);
|
||||
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
|
||||
return (EIO);
|
||||
@ -1357,8 +1359,11 @@ zfs_rezget(znode_t *zp)
|
||||
|
||||
zp->z_unlinked = (zp->z_links == 0);
|
||||
zp->z_blksz = doi.doi_data_block_size;
|
||||
if (zp->z_size != size && ZTOV(zp) != NULL)
|
||||
vnode_pager_setsize(ZTOV(zp), zp->z_size);
|
||||
if (vp != NULL) {
|
||||
vn_pages_remove(vp, 0, 0);
|
||||
if (zp->z_size != size)
|
||||
vnode_pager_setsize(vp, zp->z_size);
|
||||
}
|
||||
|
||||
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
|
||||
|
||||
|
@ -64,6 +64,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <security/audit/audit.h>
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_object.h>
|
||||
|
||||
static fo_rdwr_t vn_read;
|
||||
static fo_rdwr_t vn_write;
|
||||
static fo_truncate_t vn_truncate;
|
||||
@ -1398,3 +1401,15 @@ vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
vn_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end)
|
||||
{
|
||||
vm_object_t object;
|
||||
|
||||
if ((object = vp->v_object) == NULL)
|
||||
return;
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_object_page_remove(object, start, end, 0);
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
}
|
||||
|
@ -640,6 +640,7 @@ int _vn_lock(struct vnode *vp, int flags, char *file, int line);
|
||||
int vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp);
|
||||
int vn_open_cred(struct nameidata *ndp, int *flagp, int cmode,
|
||||
u_int vn_open_flags, struct ucred *cred, struct file *fp);
|
||||
void vn_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end);
|
||||
int vn_pollrecord(struct vnode *vp, struct thread *p, int events);
|
||||
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base,
|
||||
int len, off_t offset, enum uio_seg segflg, int ioflg,
|
||||
|
@ -79,7 +79,6 @@ int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
|
||||
void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
|
||||
int ffs_mountroot(void);
|
||||
void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
|
||||
void ffs_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end);
|
||||
int ffs_reallocblks(struct vop_reallocblks_args *);
|
||||
int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t,
|
||||
ufs2_daddr_t, int, int, int, struct ucred *, struct buf **);
|
||||
|
@ -120,18 +120,6 @@ ffs_update(vp, waitfor)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ffs_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end)
|
||||
{
|
||||
vm_object_t object;
|
||||
|
||||
if ((object = vp->v_object) == NULL)
|
||||
return;
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_object_page_remove(object, start, end, 0);
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
}
|
||||
|
||||
#define SINGLE 0 /* index of single indirect block */
|
||||
#define DOUBLE 1 /* index of double indirect block */
|
||||
#define TRIPLE 2 /* index of triple indirect block */
|
||||
@ -219,7 +207,7 @@ ffs_truncate(vp, length, flags, cred, td)
|
||||
(void) chkdq(ip, -extblocks, NOCRED, 0);
|
||||
#endif
|
||||
vinvalbuf(vp, V_ALT, 0, 0);
|
||||
ffs_pages_remove(vp,
|
||||
vn_pages_remove(vp,
|
||||
OFF_TO_IDX(lblktosize(fs, -extblocks)), 0);
|
||||
osize = ip->i_din2->di_extsize;
|
||||
ip->i_din2->di_blocks -= extblocks;
|
||||
|
@ -6541,7 +6541,7 @@ trunc_pages(ip, length, extblocks, flags)
|
||||
fs = ip->i_fs;
|
||||
extend = OFF_TO_IDX(lblktosize(fs, -extblocks));
|
||||
if ((flags & IO_EXT) != 0)
|
||||
ffs_pages_remove(vp, extend, 0);
|
||||
vn_pages_remove(vp, extend, 0);
|
||||
if ((flags & IO_NORMAL) == 0)
|
||||
return;
|
||||
BO_LOCK(&vp->v_bufobj);
|
||||
@ -6567,7 +6567,7 @@ trunc_pages(ip, length, extblocks, flags)
|
||||
end = OFF_TO_IDX(lblktosize(fs, lbn));
|
||||
} else
|
||||
end = extend;
|
||||
ffs_pages_remove(vp, OFF_TO_IDX(OFF_MAX), end);
|
||||
vn_pages_remove(vp, OFF_TO_IDX(OFF_MAX), end);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user