7291 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7292 return (EAGAIN);
7293 }
7294 } else if (svd->type == MAP_SHARED && svd->amp != NULL &&
7295 svd->amp->a_softlockcnt > 0) {
7296 /*
7297 * Try to purge this amp's entries from pcache. It will
7298 * succeed only if other segments that share the amp have no
7299 * outstanding softlock's.
7300 */
7301 segvn_purge(seg);
7302 if (svd->amp->a_softlockcnt > 0 || svd->softlockcnt > 0) {
7303 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7304 return (EAGAIN);
7305 }
7306 }
7307
7308 vpp = svd->vpage;
7309 offset = svd->offset + (uintptr_t)(addr - seg->s_base);
7310 bflags = ((flags & MS_ASYNC) ? B_ASYNC : 0) |
7311 ((flags & MS_INVALIDATE) ? B_INVAL : 0);
7312
7313 if (attr) {
7314 pageprot = attr & ~(SHARED|PRIVATE);
7315 segtype = (attr & SHARED) ? MAP_SHARED : MAP_PRIVATE;
7316
7317 /*
7318 * We are done if the segment types don't match
7319 * or if we have segment level protections and
7320 * they don't match.
7321 */
7322 if (svd->type != segtype) {
7323 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7324 return (0);
7325 }
7326 if (vpp == NULL) {
7327 if (svd->prot != pageprot) {
7328 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7329 return (0);
7330 }
7331 prot = svd->prot;
7332 } else
7333 vpp = &svd->vpage[seg_page(seg, addr)];
7334
7335 } else if (svd->vp && svd->amp == NULL &&
7336 (flags & MS_INVALIDATE) == 0) {
7337
7338 /*
7339 * No attributes, no anonymous pages and MS_INVALIDATE flag
7340 * is not on, just use one big request.
7341 */
7342 err = VOP_PUTPAGE(svd->vp, (offset_t)offset, len,
7343 bflags, svd->cred, NULL);
7344 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7345 return (err);
7346 }
7347
7348 if ((amp = svd->amp) != NULL)
7349 anon_index = svd->anon_index + seg_page(seg, addr);
7350
7351 for (eaddr = addr + len; addr < eaddr; addr += PAGESIZE) {
7352 ap = NULL;
7353 if (amp != NULL) {
7354 ANON_LOCK_ENTER(&->a_rwlock, RW_READER);
7355 anon_array_enter(amp, anon_index, &cookie);
7356 ap = anon_get_ptr(amp->ahp, anon_index++);
7357 if (ap != NULL) {
7358 swap_xlate(ap, &vp, &off);
7359 } else {
7360 vp = svd->vp;
7372 continue;
7373
7374 if (attr) {
7375 if (vpp) {
7376 prot = VPP_PROT(vpp);
7377 vpp++;
7378 }
7379 if (prot != pageprot) {
7380 continue;
7381 }
7382 }
7383
7384 /*
7385 * See if any of these pages are locked -- if so, then we
7386 * will have to truncate an invalidate request at the first
7387 * locked one. We don't need the page_struct_lock to test
7388 * as this is only advisory; even if we acquire it someone
7389 * might race in and lock the page after we unlock and before
7390 * we do the PUTPAGE, then PUTPAGE simply does nothing.
7391 */
7392 if (flags & MS_INVALIDATE) {
7393 if ((pp = page_lookup(vp, off, SE_SHARED)) != NULL) {
7394 if (pp->p_lckcnt != 0 || pp->p_cowcnt != 0) {
7395 page_unlock(pp);
7396 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7397 return (EBUSY);
7398 }
7399 if (ap != NULL && pp->p_szc != 0 &&
7400 page_tryupgrade(pp)) {
7401 if (pp->p_lckcnt == 0 &&
7402 pp->p_cowcnt == 0) {
7403 /*
7404 * swapfs VN_DISPOSE() won't
7405 * invalidate large pages.
7406 * Attempt to demote.
7407 * XXX can't help it if it
7408 * fails. But for swapfs
7409 * pages it is no big deal.
7410 */
7411 (void) page_try_demote_pages(
7412 pp);
|
7291 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7292 return (EAGAIN);
7293 }
7294 } else if (svd->type == MAP_SHARED && svd->amp != NULL &&
7295 svd->amp->a_softlockcnt > 0) {
7296 /*
7297 * Try to purge this amp's entries from pcache. It will
7298 * succeed only if other segments that share the amp have no
7299 * outstanding softlock's.
7300 */
7301 segvn_purge(seg);
7302 if (svd->amp->a_softlockcnt > 0 || svd->softlockcnt > 0) {
7303 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7304 return (EAGAIN);
7305 }
7306 }
7307
7308 vpp = svd->vpage;
7309 offset = svd->offset + (uintptr_t)(addr - seg->s_base);
7310 bflags = ((flags & MS_ASYNC) ? B_ASYNC : 0) |
7311 ((flags & MS_INVALIDATE) ? B_INVAL : 0) |
7312 ((flags & MS_INVALCURPROC) ? (B_INVALCURONLY | B_INVAL) : 0);
7313
7314 if (attr) {
7315 pageprot = attr & ~(SHARED|PRIVATE);
7316 segtype = (attr & SHARED) ? MAP_SHARED : MAP_PRIVATE;
7317
7318 /*
7319 * We are done if the segment types don't match
7320 * or if we have segment level protections and
7321 * they don't match.
7322 */
7323 if (svd->type != segtype) {
7324 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7325 return (0);
7326 }
7327 if (vpp == NULL) {
7328 if (svd->prot != pageprot) {
7329 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7330 return (0);
7331 }
7332 prot = svd->prot;
7333 } else
7334 vpp = &svd->vpage[seg_page(seg, addr)];
7335
7336 } else if (svd->vp && svd->amp == NULL &&
7337 (flags & (MS_INVALIDATE | MS_INVALCURPROC)) == 0) {
7338
7339 /*
7340 * No attributes, no anonymous pages and MS_INVAL* flags
7341 * are not on, just use one big request.
7342 */
7343 err = VOP_PUTPAGE(svd->vp, (offset_t)offset, len,
7344 bflags, svd->cred, NULL);
7345 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7346 return (err);
7347 }
7348
7349 if ((amp = svd->amp) != NULL)
7350 anon_index = svd->anon_index + seg_page(seg, addr);
7351
7352 for (eaddr = addr + len; addr < eaddr; addr += PAGESIZE) {
7353 ap = NULL;
7354 if (amp != NULL) {
7355 ANON_LOCK_ENTER(&->a_rwlock, RW_READER);
7356 anon_array_enter(amp, anon_index, &cookie);
7357 ap = anon_get_ptr(amp->ahp, anon_index++);
7358 if (ap != NULL) {
7359 swap_xlate(ap, &vp, &off);
7360 } else {
7361 vp = svd->vp;
7373 continue;
7374
7375 if (attr) {
7376 if (vpp) {
7377 prot = VPP_PROT(vpp);
7378 vpp++;
7379 }
7380 if (prot != pageprot) {
7381 continue;
7382 }
7383 }
7384
7385 /*
7386 * See if any of these pages are locked -- if so, then we
7387 * will have to truncate an invalidate request at the first
7388 * locked one. We don't need the page_struct_lock to test
7389 * as this is only advisory; even if we acquire it someone
7390 * might race in and lock the page after we unlock and before
7391 * we do the PUTPAGE, then PUTPAGE simply does nothing.
7392 */
7393 if (flags & (MS_INVALIDATE | MS_INVALCURPROC)) {
7394 if ((pp = page_lookup(vp, off, SE_SHARED)) != NULL) {
7395 if (pp->p_lckcnt != 0 || pp->p_cowcnt != 0) {
7396 page_unlock(pp);
7397 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7398 return (EBUSY);
7399 }
7400 if (ap != NULL && pp->p_szc != 0 &&
7401 page_tryupgrade(pp)) {
7402 if (pp->p_lckcnt == 0 &&
7403 pp->p_cowcnt == 0) {
7404 /*
7405 * swapfs VN_DISPOSE() won't
7406 * invalidate large pages.
7407 * Attempt to demote.
7408 * XXX can't help it if it
7409 * fails. But for swapfs
7410 * pages it is no big deal.
7411 */
7412 (void) page_try_demote_pages(
7413 pp);
|