361 size_t size, total = *lenp;
362 char first = 1;
363 faultcode_t res;
364
365 *lenp = 0;
366 if (cow) {
367 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
368 seg = as_findseg(as, uaddr, 0);
369 if ((seg == NULL) || ((base = seg->s_base) > uaddr) ||
370 (uaddr + total) > base + seg->s_size) {
371 AS_LOCK_EXIT(as, &as->a_lock);
372 return (EINVAL);
373 }
374 /*
375 * The COW scheme should work for all segment types.
376 * But to be safe, we check against segvn.
377 */
378 if (seg->s_ops != &segvn_ops) {
379 AS_LOCK_EXIT(as, &as->a_lock);
380 return (ENOTSUP);
381 } else if ((SEGOP_GETTYPE(seg, uaddr) & MAP_PRIVATE) == 0) {
382 AS_LOCK_EXIT(as, &as->a_lock);
383 return (ENOTSUP);
384 }
385 }
386 hat = as->a_hat;
387 size = total;
388 tryagain:
389 /*
390 * If (cow), hat_softlock will also change the usr protection to RO.
391 * This is the first step toward setting up cow. Before we
392 * bump up an_refcnt, we can't allow any cow-fault on this
393 * address. Otherwise segvn_fault will change the protection back
394 * to RW upon seeing an_refcnt == 1.
395 * The solution is to hold the writer lock on "as".
396 */
397 res = hat_softlock(hat, uaddr, &size, &ppp[0], cow ? HAT_COW : 0);
398 size = total - size;
399 *lenp += size;
400 size = size >> PAGESHIFT;
401 i = 0;
|
361 size_t size, total = *lenp;
362 char first = 1;
363 faultcode_t res;
364
365 *lenp = 0;
366 if (cow) {
367 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
368 seg = as_findseg(as, uaddr, 0);
369 if ((seg == NULL) || ((base = seg->s_base) > uaddr) ||
370 (uaddr + total) > base + seg->s_size) {
371 AS_LOCK_EXIT(as, &as->a_lock);
372 return (EINVAL);
373 }
374 /*
375 * The COW scheme should work for all segment types.
376 * But to be safe, we check against segvn.
377 */
378 if (seg->s_ops != &segvn_ops) {
379 AS_LOCK_EXIT(as, &as->a_lock);
380 return (ENOTSUP);
381 } else if ((segop_gettype(seg, uaddr) & MAP_PRIVATE) == 0) {
382 AS_LOCK_EXIT(as, &as->a_lock);
383 return (ENOTSUP);
384 }
385 }
386 hat = as->a_hat;
387 size = total;
388 tryagain:
389 /*
390 * If (cow), hat_softlock will also change the usr protection to RO.
391 * This is the first step toward setting up cow. Before we
392 * bump up an_refcnt, we can't allow any cow-fault on this
393 * address. Otherwise segvn_fault will change the protection back
394 * to RW upon seeing an_refcnt == 1.
395 * The solution is to hold the writer lock on "as".
396 */
397 res = hat_softlock(hat, uaddr, &size, &ppp[0], cow ? HAT_COW : 0);
398 size = total - size;
399 *lenp += size;
400 size = size >> PAGESHIFT;
401 i = 0;
|