- znode_t *zp = VTOZ(vp);
- zfsvfs_t *zfsvfs = zp->z_zfsvfs;
- int error;
-
- ZFS_ENTER(zfsvfs);
- ZFS_VERIFY_ZP(zp);
-
- /*
- * We are following the UFS semantics with respect to mapcnt
- * here: If we see that the file is mapped already, then we will
- * return an error, but we don't worry about races between this
- * function and zfs_map().
- */
- if (zp->z_mapcnt > 0 && MANDMODE((mode_t)zp->z_phys->zp_mode)) {
- ZFS_EXIT(zfsvfs);
- return (EAGAIN);
- }
- error = fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ct);
- ZFS_EXIT(zfsvfs);
- return (error);
-}
-
-/*
- * If we can't find a page in the cache, we will create a new page
- * and fill it with file data. For efficiency, we may try to fill
- * multiple pages at once (klustering).
- */
-static int
-zfs_fillpage(vnode_t *vp, u_offset_t off, struct seg *seg,
- caddr_t addr, page_t *pl[], size_t plsz, enum seg_rw rw)
-{
- znode_t *zp = VTOZ(vp);
- page_t *pp, *cur_pp;
- objset_t *os = zp->z_zfsvfs->z_os;
- caddr_t va;
- u_offset_t io_off, total;
- uint64_t oid = zp->z_id;
- size_t io_len;
- uint64_t filesz;
- int err;
-
- /*
- * If we are only asking for a single page don't bother klustering.
- */
- filesz = zp->z_phys->zp_size; /* get consistent copy of zp_size */
- if (off >= filesz)
- return (EFAULT);
- if (plsz == PAGESIZE || zp->z_blksz <= PAGESIZE) {
- io_off = off;
- io_len = PAGESIZE;
- pp = page_create_va(vp, io_off, io_len, PG_WAIT, seg, addr);
- } else {
- /*
- * Try to fill a kluster of pages (a blocks worth).
- */
- size_t klen;
- u_offset_t koff;
-
- if (!ISP2(zp->z_blksz)) {
- /* Only one block in the file. */
- klen = P2ROUNDUP((ulong_t)zp->z_blksz, PAGESIZE);
- koff = 0;
- } else {
- /*
- * It would be ideal to align our offset to the
- * blocksize but doing so has resulted in some
- * strange application crashes. For now, we
- * leave the offset as is and only adjust the
- * length if we are off the end of the file.
- */
- koff = off;
- klen = plsz;
- }
- ASSERT(koff <= filesz);
- if (koff + klen > filesz)
- klen = P2ROUNDUP(filesz, (uint64_t)PAGESIZE) - koff;
- ASSERT3U(off, >=, koff);
- ASSERT3U(off, <, koff + klen);
- pp = pvn_read_kluster(vp, off, seg, addr, &io_off,
- &io_len, koff, klen, 0);
- }
- if (pp == NULL) {
- /*
- * Some other thread entered the page before us.
- * Return to zfs_getpage to retry the lookup.
- */
- *pl = NULL;
- return (0);
- }