* Note that there is absolutely no sense in writing out * anonymous objects, so we track down the vnode object * to write out. * We invalidate (remove) all pages from the address space * for semantic correctness. * * If the backing object is a device object with unmanaged pages, then any * mappings to the specified range of pages must be removed before this * function is called. * * Note
| 1166 | * may start out with a NULL object. |
| 1167 | */ |
| 1168 | boolean_t |
| 1169 | vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size, |
| 1170 | boolean_t syncio, boolean_t invalidate) |
| 1171 | { |
| 1172 | vm_object_t backing_object; |
| 1173 | struct vnode *vp; |
| 1174 | struct mount *mp; |
| 1175 | int error, flags, fsync_after; |
| 1176 | boolean_t res; |
| 1177 | |
| 1178 | if (object == NULL) |
| 1179 | return (TRUE); |
| 1180 | res = TRUE; |
| 1181 | error = 0; |
| 1182 | VM_OBJECT_WLOCK(object); |
| 1183 | while ((backing_object = object->backing_object) != NULL) { |
| 1184 | VM_OBJECT_WLOCK(backing_object); |
| 1185 | offset += object->backing_object_offset; |
| 1186 | VM_OBJECT_WUNLOCK(object); |
| 1187 | object = backing_object; |
| 1188 | if (object->size < OFF_TO_IDX(offset + size)) |
| 1189 | size = IDX_TO_OFF(object->size) - offset; |
| 1190 | } |
| 1191 | /* |
| 1192 | * Flush pages if writing is allowed, invalidate them |
| 1193 | * if invalidation requested. Pages undergoing I/O |
| 1194 | * will be ignored by vm_object_page_remove(). |
| 1195 | * |
| 1196 | * We cannot lock the vnode and then wait for paging |
| 1197 | * to complete without deadlocking against vm_fault. |
| 1198 | * Instead we simply call vm_object_page_remove() and |
| 1199 | * allow it to block internally on a page-by-page |
| 1200 | * basis when it encounters pages undergoing async |
| 1201 | * I/O. |
| 1202 | */ |
| 1203 | if (object->type == OBJT_VNODE && |
| 1204 | vm_object_mightbedirty(object) != 0 && |
| 1205 | ((vp = object->handle)->v_vflag & VV_NOSYNC) == 0) { |
| 1206 | VM_OBJECT_WUNLOCK(object); |
| 1207 | (void) vn_start_write(vp, &mp, V_WAIT); |
| 1208 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
| 1209 | if (syncio && !invalidate && offset == 0 && |
| 1210 | atop(size) == object->size) { |
| 1211 | /* |
| 1212 | * If syncing the whole mapping of the file, |
| 1213 | * it is faster to schedule all the writes in |
| 1214 | * async mode, also allowing the clustering, |
| 1215 | * and then wait for i/o to complete. |
| 1216 | */ |
| 1217 | flags = 0; |
| 1218 | fsync_after = TRUE; |
| 1219 | } else { |
| 1220 | flags = (syncio || invalidate) ? OBJPC_SYNC : 0; |
| 1221 | flags |= invalidate ? (OBJPC_SYNC | OBJPC_INVAL) : 0; |
| 1222 | fsync_after = FALSE; |
| 1223 | } |
| 1224 | VM_OBJECT_WLOCK(object); |
| 1225 | res = vm_object_page_clean(object, offset, offset + size, |
no test coverage detected