Page MenuHomeFreeBSD

D20814.id59236.diff
No OneTemporary

D20814.id59236.diff

Index: security/mac/mac_process.c
===================================================================
--- security/mac/mac_process.c
+++ security/mac/mac_process.c
@@ -252,7 +252,7 @@
mac_proc_vm_revoke_recurse(struct thread *td, struct ucred *cred,
struct vm_map *map)
{
- vm_map_entry_t vme;
+ vm_map_entry_t prev, vme;
int result;
vm_prot_t revokeperms;
vm_object_t backing_object, object;
@@ -264,7 +264,8 @@
return;
vm_map_lock(map);
- for (vme = map->header.next; vme != &map->header; vme = vme->next) {
+ for (prev = &map->header;
+ (vme = prev->next) != &map->header; prev = vme) {
if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
mac_proc_vm_revoke_recurse(td, cred,
vme->object.sub_map);
@@ -363,7 +364,7 @@
}
pmap_protect(map->pmap, vme->start, vme->end,
vme->protection & ~revokeperms);
- vm_map_simplify_entry(map, vme);
+ vm_map_merge_entries(map, prev, vme);
}
}
vm_map_unlock(map);
Index: vm/vm_map.h
===================================================================
--- vm/vm_map.h
+++ vm/vm_map.h
@@ -418,7 +418,8 @@
boolean_t vm_map_lookup_entry (vm_map_t, vm_offset_t, vm_map_entry_t *);
int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
int vm_map_remove (vm_map_t, vm_offset_t, vm_offset_t);
-void vm_map_simplify_entry(vm_map_t map, vm_map_entry_t entry);
+void vm_map_merge_entries(vm_map_t map, vm_map_entry_t prev,
+ vm_map_entry_t entry);
void vm_map_startup (void);
int vm_map_submap (vm_map_t, vm_offset_t, vm_offset_t, vm_map_t);
int vm_map_sync(vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t);
Index: vm/vm_map.c
===================================================================
--- vm/vm_map.c
+++ vm/vm_map.c
@@ -1422,7 +1422,7 @@
vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
vm_offset_t start, vm_offset_t end, vm_prot_t prot, vm_prot_t max, int cow)
{
- vm_map_entry_t new_entry, prev_entry, temp_entry;
+ vm_map_entry_t new_entry, prev_entry;
struct ucred *cred;
vm_eflags_t protoeflags;
vm_inherit_t inheritance;
@@ -1447,11 +1447,9 @@
* Find the entry prior to the proposed starting address; if it's part
* of an existing entry, this range is bogus.
*/
- if (vm_map_lookup_entry(map, start, &temp_entry))
+ if (vm_map_lookup_entry(map, start, &prev_entry))
return (KERN_NO_SPACE);
- prev_entry = temp_entry;
-
/*
* Assert that the next entry doesn't overlap the end point.
*/
@@ -1548,7 +1546,7 @@
map->size += end - prev_entry->end;
vm_map_entry_resize(map, prev_entry,
end - prev_entry->end);
- vm_map_simplify_entry(map, prev_entry);
+ vm_map_merge_entries(map, prev_entry, prev_entry->next);
return (KERN_SUCCESS);
}
@@ -1608,7 +1606,8 @@
* with the previous entry when object is NULL. Here, we handle the
* other cases, which are less common.
*/
- vm_map_simplify_entry(map, new_entry);
+ vm_map_merge_entries(map, prev_entry, new_entry);
+ vm_map_merge_entries(map, new_entry, new_entry->next);
if ((cow & (MAP_PREFAULT | MAP_PREFAULT_PARTIAL)) != 0) {
vm_map_pmap_enter(map, start, prot, object, OFF_TO_IDX(offset),
@@ -2077,34 +2076,21 @@
}
/*
- * vm_map_simplify_entry:
+ * vm_map_merge_entries:
*
- * Simplify the given map entry by merging with either neighbor. This
- * routine also has the ability to merge with both neighbors.
- *
- * The map must be locked.
- *
- * This routine guarantees that the passed entry remains valid (though
- * possibly extended). When merging, this routine may delete one or
- * both neighbors.
+ * Compare the given map entry to its successor, and merge it into its
+ * successor if possible. Return the successor.
*/
void
-vm_map_simplify_entry(vm_map_t map, vm_map_entry_t entry)
+vm_map_merge_entries(vm_map_t map, vm_map_entry_t prev, vm_map_entry_t entry)
{
- vm_map_entry_t next, prev;
if ((entry->eflags & MAP_ENTRY_NOMERGE_MASK) != 0)
return;
- prev = entry->prev;
if (vm_map_mergeable_neighbors(prev, entry)) {
vm_map_entry_unlink(map, prev, UNLINK_MERGE_NEXT);
vm_map_merged_neighbor_dispose(map, prev);
}
- next = entry->next;
- if (vm_map_mergeable_neighbors(entry, next)) {
- vm_map_entry_unlink(map, next, UNLINK_MERGE_PREV);
- vm_map_merged_neighbor_dispose(map, next);
- }
}
/*
@@ -2178,7 +2164,7 @@
* This routine is called only when it is known that
* the entry must be split.
*/
-static void
+static vm_map_entry_t
_vm_map_clip_start(vm_map_t map, vm_map_entry_t entry, vm_offset_t start)
{
vm_map_entry_t new_entry;
@@ -2220,6 +2206,7 @@
* left the same.
*/
}
+ return (new_entry);
}
/*
@@ -2449,7 +2436,7 @@
vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
vm_prot_t new_prot, boolean_t set_max)
{
- vm_map_entry_t current, entry, in_tran;
+ vm_map_entry_t current, entry, in_tran, prev;
vm_object_t obj;
struct ucred *cred;
vm_prot_t old_prot;
@@ -2472,8 +2459,8 @@
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &entry))
- entry = entry->next;
+ vm_map_lookup_entry(map, start-1, &prev);
+ entry = (prev->end > start) ? prev : prev->next;
/*
* Make a first pass to check for protection violations.
@@ -2515,7 +2502,8 @@
* some may now be mergeable.
*/
rv = KERN_SUCCESS;
- vm_map_clip_start(map, entry, start);
+ if (prev == entry)
+ prev = _vm_map_clip_start(map, entry, start);
for (current = entry; current->start < end; current = current->next) {
vm_map_clip_end(map, current, end);
@@ -2574,7 +2562,8 @@
* [Note that clipping is not necessary the second time.]
*/
for (current = entry; current->start < end;
- vm_map_simplify_entry(map, current), current = current->next) {
+ vm_map_merge_entries(map, prev, current),
+ prev = current, current = prev->next) {
if (rv != KERN_SUCCESS ||
(current->eflags & MAP_ENTRY_GUARD) != 0)
continue;
@@ -2612,6 +2601,7 @@
#undef MASK
}
}
+ vm_map_merge_entries(map, prev, current);
vm_map_unlock(map);
return (rv);
}
@@ -2631,7 +2621,7 @@
vm_offset_t end,
int behav)
{
- vm_map_entry_t current, entry;
+ vm_map_entry_t current, entry, prev;
bool modify_map;
/*
@@ -2670,12 +2660,8 @@
*/
VM_MAP_RANGE_CHECK(map, start, end);
- if (vm_map_lookup_entry(map, start, &entry)) {
- if (modify_map)
- vm_map_clip_start(map, entry, start);
- } else {
- entry = entry->next;
- }
+ vm_map_lookup_entry(map, start-1, &prev);
+ entry = (prev->end > start) ? prev : prev->next;
if (modify_map) {
/*
@@ -2684,8 +2670,10 @@
* We clip the vm_map_entry so that behavioral changes are
* limited to the specified address range.
*/
+ if (prev == entry)
+ prev = _vm_map_clip_start(map, entry, start);
for (current = entry; current->start < end;
- current = current->next) {
+ prev = current, current = prev->next) {
if (current->eflags & MAP_ENTRY_IS_SUB_MAP)
continue;
@@ -2716,8 +2704,9 @@
default:
break;
}
- vm_map_simplify_entry(map, current);
+ vm_map_merge_entries(map, prev, current);
}
+ vm_map_merge_entries(map, prev, current);
vm_map_unlock(map);
} else {
vm_pindex_t pstart, pend;
@@ -2805,8 +2794,7 @@
vm_map_inherit(vm_map_t map, vm_offset_t start, vm_offset_t end,
vm_inherit_t new_inheritance)
{
- vm_map_entry_t entry;
- vm_map_entry_t temp_entry;
+ vm_map_entry_t entry, prev;
switch (new_inheritance) {
case VM_INHERIT_NONE:
@@ -2821,19 +2809,20 @@
return (KERN_SUCCESS);
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
- if (vm_map_lookup_entry(map, start, &temp_entry)) {
- entry = temp_entry;
- vm_map_clip_start(map, entry, start);
- } else
- entry = temp_entry->next;
+ vm_map_lookup_entry(map, start-1, &prev);
+ if (start < prev->end)
+ prev = _vm_map_clip_start(map, prev, start);
+ entry = prev->next;
while (entry->start < end) {
vm_map_clip_end(map, entry, end);
if ((entry->eflags & MAP_ENTRY_GUARD) == 0 ||
new_inheritance != VM_INHERIT_ZERO)
entry->inheritance = new_inheritance;
- vm_map_simplify_entry(map, entry);
- entry = entry->next;
+ vm_map_merge_entries(map, prev, entry);
+ prev = entry;
+ entry = prev->next;
}
+ vm_map_merge_entries(map, prev, entry);
vm_map_unlock(map);
return (KERN_SUCCESS);
}
@@ -2847,25 +2836,26 @@
vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
int flags)
{
- vm_map_entry_t entry, first_entry, tmp_entry;
+ vm_map_entry_t entry, first_entry, prev, saved_entry;
vm_offset_t saved_start;
unsigned int last_timestamp;
int rv;
- boolean_t need_wakeup, result, user_unwire;
+ bool need_wakeup, holes_ok, user_unwire;
if (start == end)
return (KERN_SUCCESS);
- user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
+ user_unwire = (flags & VM_MAP_WIRE_USER) != 0;
+ holes_ok = (flags & VM_MAP_WIRE_HOLESOK) != 0;
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &first_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- first_entry = first_entry->next;
- else {
- vm_map_unlock(map);
- return (KERN_INVALID_ADDRESS);
- }
+ vm_map_lookup_entry(map, start-1, &prev);
+ first_entry = prev->end > start ? prev : prev->next;
+
+ if (start < first_entry->start && !holes_ok) {
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
}
+ rv = KERN_SUCCESS;
last_timestamp = map->timestamp;
entry = first_entry;
while (entry->start < end) {
@@ -2873,8 +2863,8 @@
/*
* We have not yet clipped the entry.
*/
- saved_start = (start >= entry->start) ? start :
- entry->start;
+ saved_entry = entry;
+ saved_start = ulmax(start, entry->start);
entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
if (vm_map_unlock_and_wait(map, 0)) {
/*
@@ -2882,41 +2872,41 @@
*/
}
vm_map_lock(map);
- if (last_timestamp+1 != map->timestamp) {
- /*
- * Look again for the entry because the map was
- * modified while it was unlocked.
- * Specifically, the entry may have been
- * clipped, merged, or deleted.
- */
- if (!vm_map_lookup_entry(map, saved_start,
- &tmp_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- tmp_entry = tmp_entry->next;
- else {
- if (saved_start == start) {
- /*
- * First_entry has been deleted.
- */
- vm_map_unlock(map);
- return (KERN_INVALID_ADDRESS);
- }
- end = saved_start;
- rv = KERN_INVALID_ADDRESS;
- goto done;
- }
+ if (last_timestamp + 1 == map->timestamp) {
+ last_timestamp = map->timestamp;
+ continue;
+ }
+
+ /*
+ * Look again for the entry because the map was
+ * modified while it was unlocked. Specifically, the
+ * entry may have been clipped, merged, or deleted.
+ */
+ vm_map_lookup_entry(map, saved_start-1, &prev);
+ entry = prev->end > saved_start ? prev : prev->next;
+ if (saved_start < entry->start && !holes_ok) {
+ if (saved_start == start) {
+ /*
+ * First_entry has been deleted.
+ */
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
}
- if (entry == first_entry)
- first_entry = tmp_entry;
- else
- first_entry = NULL;
- entry = tmp_entry;
+ end = saved_start;
+ rv = KERN_INVALID_ADDRESS;
+ break;
}
+ if (saved_entry == first_entry)
+ first_entry = entry;
+ else
+ first_entry = NULL;
last_timestamp = map->timestamp;
continue;
}
- vm_map_clip_start(map, entry, start);
+ if (prev == entry)
+ prev = _vm_map_clip_start(map, prev, start);
vm_map_clip_end(map, entry, end);
+
/*
* Mark the entry in case the map lock is released. (See
* above.)
@@ -2930,11 +2920,11 @@
* Check the map for holes in the specified region.
* If VM_MAP_WIRE_HOLESOK was specified, skip this check.
*/
- if (((flags & VM_MAP_WIRE_HOLESOK) == 0) &&
+ if (!holes_ok &&
(entry->end < end && entry->next->start > entry->end)) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
- goto done;
+ break;
}
/*
* If system unwiring, require that the entry is system wired.
@@ -2943,21 +2933,19 @@
vm_map_entry_system_wired_count(entry) == 0) {
end = entry->end;
rv = KERN_INVALID_ARGUMENT;
- goto done;
+ break;
}
entry = entry->next;
}
- rv = KERN_SUCCESS;
-done:
- need_wakeup = FALSE;
+ need_wakeup = false;
if (first_entry == NULL) {
- result = vm_map_lookup_entry(map, start, &first_entry);
- if (!result && (flags & VM_MAP_WIRE_HOLESOK))
- first_entry = first_entry->next;
- else
- KASSERT(result, ("vm_map_unwire: lookup failed"));
+ vm_map_lookup_entry(map, start-1, &prev);
+ first_entry = prev->end > start ? prev : prev->next;
+ KASSERT(start >= first_entry->start || holes_ok,
+ ("vm_map_unwire: lookup failed"));
}
- for (entry = first_entry; entry->start < end; entry = entry->next) {
+ for (entry = first_entry; entry->start < end;
+ prev = entry, entry = prev->next) {
/*
* If VM_MAP_WIRE_HOLESOK was specified, an empty
* space in the unwired region could have been mapped
@@ -2969,7 +2957,7 @@
*/
if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0 ||
entry->wiring_thread != curthread) {
- KASSERT((flags & VM_MAP_WIRE_HOLESOK) != 0,
+ KASSERT(holes_ok,
("vm_map_unwire: !HOLESOK and new/changed entry"));
continue;
}
@@ -2991,10 +2979,11 @@
entry->wiring_thread = NULL;
if (entry->eflags & MAP_ENTRY_NEEDS_WAKEUP) {
entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
- need_wakeup = TRUE;
+ need_wakeup = true;
}
- vm_map_simplify_entry(map, entry);
+ vm_map_merge_entries(map, prev, entry);
}
+ vm_map_merge_entries(map, prev, entry);
vm_map_unlock(map);
if (need_wakeup)
vm_map_wakeup(map);
@@ -3080,12 +3069,12 @@
int
vm_map_wire_locked(vm_map_t map, vm_offset_t start, vm_offset_t end, int flags)
{
- vm_map_entry_t entry, first_entry, tmp_entry;
+ vm_map_entry_t entry, first_entry, prev, saved_entry;
vm_offset_t faddr, saved_end, saved_start;
u_long npages;
u_int last_timestamp;
int rv;
- boolean_t need_wakeup, result, user_wire;
+ bool need_wakeup, holes_ok, user_wire;
vm_prot_t prot;
VM_MAP_ASSERT_LOCKED(map);
@@ -3095,14 +3084,14 @@
prot = 0;
if (flags & VM_MAP_WIRE_WRITE)
prot |= VM_PROT_WRITE;
- user_wire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
+ user_wire = (flags & VM_MAP_WIRE_USER) != 0;
+ holes_ok = (flags & VM_MAP_WIRE_HOLESOK) != 0;
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &first_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- first_entry = first_entry->next;
- else
- return (KERN_INVALID_ADDRESS);
- }
+ vm_map_lookup_entry(map, start-1, &prev);
+ first_entry = prev->end > start ? prev : prev->next;
+ if (start < first_entry->start && !holes_ok)
+ return (KERN_INVALID_ADDRESS);
+ rv = KERN_SUCCESS;
last_timestamp = map->timestamp;
entry = first_entry;
while (entry->start < end) {
@@ -3110,8 +3099,8 @@
/*
* We have not yet clipped the entry.
*/
- saved_start = (start >= entry->start) ? start :
- entry->start;
+ saved_entry = entry;
+ saved_start = ulmax(start, entry->start);
entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
if (vm_map_unlock_and_wait(map, 0)) {
/*
@@ -3119,40 +3108,41 @@
*/
}
vm_map_lock(map);
- if (last_timestamp + 1 != map->timestamp) {
- /*
- * Look again for the entry because the map was
- * modified while it was unlocked.
- * Specifically, the entry may have been
- * clipped, merged, or deleted.
- */
- if (!vm_map_lookup_entry(map, saved_start,
- &tmp_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- tmp_entry = tmp_entry->next;
- else {
- if (saved_start == start) {
- /*
- * first_entry has been deleted.
- */
- return (KERN_INVALID_ADDRESS);
- }
- end = saved_start;
- rv = KERN_INVALID_ADDRESS;
- goto done;
- }
+ if (last_timestamp + 1 == map->timestamp) {
+ last_timestamp = map->timestamp;
+ continue;
+ }
+
+ /*
+ * Look again for the entry because the map was
+ * modified while it was unlocked. Specifically, the
+ * entry may have been clipped, merged, or deleted.
+ */
+ vm_map_lookup_entry(map, saved_start-1, &prev);
+ entry = prev->end > saved_start ? prev : prev->next;
+ if (saved_start < entry->start && !holes_ok) {
+ if (saved_start == start) {
+ /*
+ * First_entry has been deleted.
+ */
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
}
- if (entry == first_entry)
- first_entry = tmp_entry;
- else
- first_entry = NULL;
- entry = tmp_entry;
+ end = saved_start;
+ rv = KERN_INVALID_ADDRESS;
+ break;
}
+ if (saved_entry == first_entry)
+ first_entry = entry;
+ else
+ first_entry = NULL;
last_timestamp = map->timestamp;
continue;
}
- vm_map_clip_start(map, entry, start);
+ if (prev == entry)
+ prev = _vm_map_clip_start(map, prev, start);
vm_map_clip_end(map, entry, end);
+
/*
* Mark the entry in case the map lock is released. (See
* above.)
@@ -3165,10 +3155,10 @@
if ((entry->protection & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0
|| (entry->protection & prot) != prot) {
entry->eflags |= MAP_ENTRY_WIRE_SKIPPED;
- if ((flags & VM_MAP_WIRE_HOLESOK) == 0) {
+ if (!holes_ok) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
- goto done;
+ break;
}
goto next_entry;
}
@@ -3181,7 +3171,7 @@
entry->start);
end = entry->end;
rv = KERN_RESOURCE_SHORTAGE;
- goto done;
+ break;
}
/*
@@ -3212,14 +3202,17 @@
* may have been clipped, but NOT merged or
* deleted.
*/
- result = vm_map_lookup_entry(map, saved_start,
- &tmp_entry);
- KASSERT(result, ("vm_map_wire: lookup failed"));
- if (entry == first_entry)
- first_entry = tmp_entry;
+ saved_entry = entry;
+ vm_map_lookup_entry(map, saved_start-1, &prev);
+ entry = prev->end > saved_start ? prev : prev->next;
+ vm_map_lookup_entry(map, saved_start-1, &prev);
+ first_entry = prev->end > saved_start ? prev : prev->next;
+ KASSERT(saved_start >= first_entry->start || holes_ok,
+ ("vm_map_wire: lookup failed"));
+ if (saved_entry == first_entry)
+ first_entry = entry;
else
first_entry = NULL;
- entry = tmp_entry;
while (entry->end < saved_end) {
/*
* In case of failure, handle entries
@@ -3240,7 +3233,7 @@
if (user_wire)
vm_map_wire_user_count_sub(npages);
end = entry->end;
- goto done;
+ break;
}
} else if (!user_wire ||
(entry->eflags & MAP_ENTRY_USER_WIRED) == 0) {
@@ -3251,25 +3244,23 @@
* If VM_MAP_WIRE_HOLESOK was specified, skip this check.
*/
next_entry:
- if ((flags & VM_MAP_WIRE_HOLESOK) == 0 &&
+ if (!holes_ok &&
entry->end < end && entry->next->start > entry->end) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
- goto done;
+ break;
}
entry = entry->next;
}
- rv = KERN_SUCCESS;
-done:
- need_wakeup = FALSE;
+ need_wakeup = false;
if (first_entry == NULL) {
- result = vm_map_lookup_entry(map, start, &first_entry);
- if (!result && (flags & VM_MAP_WIRE_HOLESOK))
- first_entry = first_entry->next;
- else
- KASSERT(result, ("vm_map_wire: lookup failed"));
+ vm_map_lookup_entry(map, start-1, &prev);
+ first_entry = prev->end > start ? prev : prev->next;
+ KASSERT(saved_start >= first_entry->start || holes_ok,
+ ("vm_map_wire: lookup failed"));
}
- for (entry = first_entry; entry->start < end; entry = entry->next) {
+ for (entry = first_entry; entry->start < end;
+ prev = entry, entry = prev->next) {
/*
* If VM_MAP_WIRE_HOLESOK was specified, an empty
* space in the unwired region could have been mapped
@@ -3281,7 +3272,7 @@
*/
if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0 ||
entry->wiring_thread != curthread) {
- KASSERT((flags & VM_MAP_WIRE_HOLESOK) != 0,
+ KASSERT(holes_ok,
("vm_map_wire: !HOLESOK and new/changed entry"));
continue;
}
@@ -3322,10 +3313,11 @@
entry->wiring_thread = NULL;
if (entry->eflags & MAP_ENTRY_NEEDS_WAKEUP) {
entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
- need_wakeup = TRUE;
+ need_wakeup = true;
}
- vm_map_simplify_entry(map, entry);
+ vm_map_merge_entries(map, prev, entry);
}
+ vm_map_merge_entries(map, prev, entry);
if (need_wakeup)
vm_map_wakeup(map);
return (rv);
@@ -3963,7 +3955,7 @@
old_entry->object.vm_object);
/*
- * As in vm_map_simplify_entry(), the
+ * As in vm_map_merge_entries(), the
* vnode lock will not be acquired in
* this call to vm_object_deallocate().
*/

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 6, 1:46 PM (56 m, 41 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40271566
Default Alt Text
D20814.id59236.diff (20 KB)

Event Timeline