Author: mm
Date: Thu Aug 25 08:17:39 2011
New Revision: 225166
URL: http://svn.freebsd.org/changeset/base/225166

Log:
  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

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
  head/sys/kern/vfs_vnops.c
  head/sys/sys/vnode.h
  head/sys/ufs/ffs/ffs_extern.h
  head/sys/ufs/ffs/ffs_inode.c
  head/sys/ufs/ffs/ffs_softdep.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c     Thu Aug 
25 07:28:07 2011        (r225165)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c     Thu Aug 
25 08:17:39 2011        (r225166)
@@ -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);
 

Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c   Thu Aug 25 07:28:07 2011        (r225165)
+++ head/sys/kern/vfs_vnops.c   Thu Aug 25 08:17:39 2011        (r225166)
@@ -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
        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);
+}

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Thu Aug 25 07:28:07 2011        (r225165)
+++ head/sys/sys/vnode.h        Thu Aug 25 08:17:39 2011        (r225166)
@@ -640,6 +640,7 @@ int _vn_lock(struct vnode *vp, int flags
 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,

Modified: head/sys/ufs/ffs/ffs_extern.h
==============================================================================
--- head/sys/ufs/ffs/ffs_extern.h       Thu Aug 25 07:28:07 2011        
(r225165)
+++ head/sys/ufs/ffs/ffs_extern.h       Thu Aug 25 08:17:39 2011        
(r225166)
@@ -79,7 +79,6 @@ int   ffs_isfreeblock(struct fs *, u_char 
 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 **);

Modified: head/sys/ufs/ffs/ffs_inode.c
==============================================================================
--- head/sys/ufs/ffs/ffs_inode.c        Thu Aug 25 07:28:07 2011        
(r225165)
+++ head/sys/ufs/ffs/ffs_inode.c        Thu Aug 25 08:17:39 2011        
(r225166)
@@ -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;

Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c      Thu Aug 25 07:28:07 2011        
(r225165)
+++ head/sys/ufs/ffs/ffs_softdep.c      Thu Aug 25 08:17:39 2011        
(r225166)
@@ -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);
 }
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to