diff options
author | delphij <delphij@FreeBSD.org> | 2007-07-08 15:56:12 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2007-07-08 15:56:12 +0000 |
commit | b4ff5952426a6e92dc21f676c1929eea72c2d9a4 (patch) | |
tree | 6ac0bd7afea293c01d39622b1f9361df605db31d /sys/fs/tmpfs/tmpfs_vnops.c | |
parent | 4df766d13509673472d8fac9e2b4fd393fa2a98f (diff) | |
download | FreeBSD-src-b4ff5952426a6e92dc21f676c1929eea72c2d9a4.zip FreeBSD-src-b4ff5952426a6e92dc21f676c1929eea72c2d9a4.tar.gz |
MFp4:
- Plug memory leak.
- Respect underlying vnode's properties rather than assuming that
the user want root:wheel + 0755. Useful for using tmpfs(5) for
/tmp.
- Use roundup2 and howmany macros instead of rolling our own version.
- Try to fix fsx -W -R foo case.
- Instead of blindly zeroing a page, determine whether we need a pagein
order to prevent data corruption.
- Fix several bugs reported by Coverity.
Submitted by: Mingyan Guo <guomingyan gmail com>, Howard Su, delphij
Coverity ID: CID 2550, 2551, 2552, 2557
Approved by: re (tmpfs blanket)
Diffstat (limited to 'sys/fs/tmpfs/tmpfs_vnops.c')
-rw-r--r-- | sys/fs/tmpfs/tmpfs_vnops.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 520fff7e..69f6e47 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -450,6 +450,7 @@ tmpfs_uio_xfer(struct tmpfs_mount *tmp, struct tmpfs_node *node, vm_page_t m; size_t len; int error = 0; + int behind = 0, ahead = 0; /* uobj - locked by caller */ @@ -468,8 +469,21 @@ tmpfs_uio_xfer(struct tmpfs_mount *tmp, struct tmpfs_node *node, len = MIN(len, (PAGE_SIZE - d)); m = vm_page_grab(uobj, idx, VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - if (uio->uio_rw == UIO_READ && m->valid != VM_PAGE_BITS_ALL) - vm_page_zero_invalid(m, TRUE); + if (m->valid != VM_PAGE_BITS_ALL){ + if (vm_pager_has_page(uobj, idx, &behind, &ahead)){ + error = vm_pager_get_pages(uobj, &m, 1, 0); + if (error == VM_PAGER_ERROR){ + printf("vm_pager_get_pages error\n"); + goto out; + } +#ifdef DIAGNOSTIC + /* XXX */ + printf("tmpfs gets page from pager\n"); +#endif + } else { + vm_page_zero_invalid(m, TRUE); + } + } VM_OBJECT_UNLOCK(uobj); sched_pin(); sf = sf_buf_alloc(m, SFB_CPUPRIVATE); @@ -488,6 +502,7 @@ tmpfs_uio_xfer(struct tmpfs_mount *tmp, struct tmpfs_node *node, vm_page_wakeup(m); vm_page_unlock_queues(); } +out: vm_object_pip_subtract(uobj, 1); VM_OBJECT_UNLOCK(uobj); return error; @@ -680,14 +695,12 @@ tmpfs_link(struct vop_link_args *v) int error; struct tmpfs_dirent *de; - struct tmpfs_node *dnode; struct tmpfs_node *node; MPASS(VOP_ISLOCKED(dvp, cnp->cn_thread)); MPASS(cnp->cn_flags & HASBUF); MPASS(dvp != vp); /* XXX When can this be false? */ - dnode = VP_TO_TMPFS_DIR(dvp); node = VP_TO_TMPFS_NODE(vp); /* XXX: Why aren't the following two tests done by the caller? */ @@ -753,7 +766,6 @@ tmpfs_rename(struct vop_rename_args *v) char *newname; int error; struct tmpfs_dirent *de; - struct tmpfs_mount *tmp; struct tmpfs_node *fdnode; struct tmpfs_node *fnode; struct tmpfs_node *tdnode; @@ -775,7 +787,6 @@ tmpfs_rename(struct vop_rename_args *v) goto out; } - tmp = VFS_TO_TMPFS(tdvp->v_mount); tdnode = VP_TO_TMPFS_DIR(tdvp); /* If source and target are the same file, there is nothing to do. */ |