+ break;
+ case VLNK:
+ nfsstats.biocache_readlinks++;
+ on = 0;
+ error = bread(vp, (daddr_t)0, NFS_MAXPATHLEN, cred, &bp);
+ n = MIN(uio->uio_resid, NFS_MAXPATHLEN - bp->b_resid);
+ break;
+ case VDIR:
+ nfsstats.biocache_readdirs++;
+ on = 0;
+ error = bread(vp, uio->uio_offset, NFS_DIRBLKSIZ, cred, &bp);
+ n = MIN(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid);
+ break;
+ };
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+
+ /*
+ * For nqnfs:
+ * Must check for valid lease, since it may have expired while in
+ * bread(). If expired, get a lease.
+ * If data is stale, flush and try again.
+ * nb: If a read rpc is done by bread() or breada() and there is
+ * no valid lease, a get_lease request will be piggy backed.
+ */
+ if (nmp->nm_flag & NFSMNT_NQNFS) {
+ if (NQNFS_CKINVALID(vp, np, NQL_READ)) {
+ do {
+ error = nqnfs_getlease(vp, NQL_READ, cred, uio->uio_procp);
+ } while (error == NQNFS_EXPIRED);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+ if ((np->n_flag & NQNFSNONCACHE) ||
+ np->n_lrev != np->n_brev ||
+ ((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) {
+ if (vp->v_type == VDIR) {
+ np->n_direofoffset = 0;
+ cache_purge(vp);
+ }
+ brelse(bp);
+ np->n_flag &= ~NMODIFIED;
+ vinvalbuf(vp, TRUE, cred, uio->uio_procp);
+ np->n_brev = np->n_lrev;
+ continue;
+ }
+ } else if ((np->n_flag & NQNFSNONCACHE) ||
+ ((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) {
+ np->n_direofoffset = 0;