* vm_object_shadow: * * Create a new object which is backed by the * specified existing object range. The source * object reference is deallocated. * * The new object and offset into that object * are returned in the source parameters. */
| 1415 | * are returned in the source parameters. |
| 1416 | */ |
| 1417 | void |
| 1418 | vm_object_shadow(vm_object_t *object, vm_ooffset_t *offset, vm_size_t length, |
| 1419 | struct ucred *cred, bool shared) |
| 1420 | { |
| 1421 | vm_object_t source; |
| 1422 | vm_object_t result; |
| 1423 | |
| 1424 | source = *object; |
| 1425 | |
| 1426 | /* |
| 1427 | * Don't create the new object if the old object isn't shared. |
| 1428 | * |
| 1429 | * If we hold the only reference we can guarantee that it won't |
| 1430 | * increase while we have the map locked. Otherwise the race is |
| 1431 | * harmless and we will end up with an extra shadow object that |
| 1432 | * will be collapsed later. |
| 1433 | */ |
| 1434 | if (source != NULL && source->ref_count == 1 && |
| 1435 | (source->flags & OBJ_ANON) != 0) |
| 1436 | return; |
| 1437 | |
| 1438 | /* |
| 1439 | * Allocate a new object with the given length. |
| 1440 | */ |
| 1441 | result = vm_object_allocate_anon(atop(length), source, cred, length); |
| 1442 | |
| 1443 | /* |
| 1444 | * Store the offset into the source object, and fix up the offset into |
| 1445 | * the new object. |
| 1446 | */ |
| 1447 | result->backing_object_offset = *offset; |
| 1448 | |
| 1449 | if (shared || source != NULL) { |
| 1450 | VM_OBJECT_WLOCK(result); |
| 1451 | |
| 1452 | /* |
| 1453 | * The new object shadows the source object, adding a |
| 1454 | * reference to it. Our caller changes his reference |
| 1455 | * to point to the new object, removing a reference to |
| 1456 | * the source object. Net result: no change of |
| 1457 | * reference count, unless the caller needs to add one |
| 1458 | * more reference due to forking a shared map entry. |
| 1459 | */ |
| 1460 | if (shared) { |
| 1461 | vm_object_reference_locked(result); |
| 1462 | vm_object_clear_flag(result, OBJ_ONEMAPPING); |
| 1463 | } |
| 1464 | |
| 1465 | /* |
| 1466 | * Try to optimize the result object's page color when |
| 1467 | * shadowing in order to maintain page coloring |
| 1468 | * consistency in the combined shadowed object. |
| 1469 | */ |
| 1470 | if (source != NULL) { |
| 1471 | vm_object_backing_insert(result, source); |
| 1472 | result->domain = source->domain; |
| 1473 | #if VM_NRESERVLEVEL > 0 |
| 1474 | result->flags |= source->flags & OBJ_COLORED; |
no test coverage detected