···41184118 ASSERT(nextents <= XFS_LINEAR_EXTS);41194119 size = nextents * sizeof(xfs_bmbt_rec_t);4120412041214121- xfs_iext_irec_compact_full(ifp);41214121+ xfs_iext_irec_compact_pages(ifp);41224122 ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);4123412341244124 ep = ifp->if_u1.if_ext_irec->er_extbuf;···44494449 * compaction policy is as follows:44504450 *44514451 * Full Compaction: Extents fit into a single page (or inline buffer)44524452- * Full Compaction: Extents occupy less than 10% of allocated space44534453- * Partial Compaction: Extents occupy > 10% and < 50% of allocated space44524452+ * Partial Compaction: Extents occupy less than 50% of allocated space44544453 * No Compaction: Extents occupy at least 50% of allocated space44554454 */44564455void···44704471 xfs_iext_direct_to_inline(ifp, nextents);44714472 } else if (nextents <= XFS_LINEAR_EXTS) {44724473 xfs_iext_indirect_to_direct(ifp);44734473- } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) {44744474- xfs_iext_irec_compact_full(ifp);44754474 } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {44764475 xfs_iext_irec_compact_pages(ifp);44774476 }···44934496 erp_next = erp + 1;44944497 if (erp_next->er_extcount <=44954498 (XFS_LINEAR_EXTS - erp->er_extcount)) {44964496- memmove(&erp->er_extbuf[erp->er_extcount],44994499+ memcpy(&erp->er_extbuf[erp->er_extcount],44974500 erp_next->er_extbuf, erp_next->er_extcount *44984501 sizeof(xfs_bmbt_rec_t));44994502 erp->er_extcount += erp_next->er_extcount;···45094512 } else {45104513 erp_idx++;45114514 }45124512- }45134513-}45144514-45154515-/*45164516- * Fully compact the extent records managed by the indirection array.45174517- */45184518-void45194519-xfs_iext_irec_compact_full(45204520- xfs_ifork_t *ifp) /* inode fork pointer */45214521-{45224522- xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */45234523- xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */45244524- int erp_idx = 0; /* extent irec index */45254525- int ext_avail; /* empty entries in ex list */45264526- int ext_diff; /* number of exts to add */45274527- int nlists; /* number of irec's (ex lists) */45284528-45294529- ASSERT(ifp->if_flags & XFS_IFEXTIREC);45304530-45314531- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;45324532- erp = ifp->if_u1.if_ext_irec;45334533- ep = &erp->er_extbuf[erp->er_extcount];45344534- erp_next = erp + 1;45354535- ep_next = erp_next->er_extbuf;45364536-45374537- while (erp_idx < nlists - 1) {45384538- /*45394539- * Check how many extent records are available in this irec.45404540- * If there is none skip the whole exercise.45414541- */45424542- ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;45434543- if (ext_avail) {45444544-45454545- /*45464546- * Copy over as many as possible extent records into45474547- * the previous page.45484548- */45494549- ext_diff = MIN(ext_avail, erp_next->er_extcount);45504550- memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));45514551- erp->er_extcount += ext_diff;45524552- erp_next->er_extcount -= ext_diff;45534553-45544554- /*45554555- * If the next irec is empty now we can simply45564556- * remove it.45574557- */45584558- if (erp_next->er_extcount == 0) {45594559- /*45604560- * Free page before removing extent record45614561- * so er_extoffs don't get modified in45624562- * xfs_iext_irec_remove.45634563- */45644564- kmem_free(erp_next->er_extbuf);45654565- erp_next->er_extbuf = NULL;45664566- xfs_iext_irec_remove(ifp, erp_idx + 1);45674567- erp = &ifp->if_u1.if_ext_irec[erp_idx];45684568- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;45694569-45704570- /*45714571- * If the next irec is not empty move up the content45724572- * that has not been copied to the previous page to45734573- * the beggining of this one.45744574- */45754575- } else {45764576- memmove(erp_next->er_extbuf, &ep_next[ext_diff],45774577- erp_next->er_extcount *45784578- sizeof(xfs_bmbt_rec_t));45794579- ep_next = erp_next->er_extbuf;45804580- memset(&ep_next[erp_next->er_extcount], 0,45814581- (XFS_LINEAR_EXTS -45824582- erp_next->er_extcount) *45834583- sizeof(xfs_bmbt_rec_t));45844584- }45854585- }45864586-45874587- if (erp->er_extcount == XFS_LINEAR_EXTS) {45884588- erp_idx++;45894589- if (erp_idx < nlists)45904590- erp = &ifp->if_u1.if_ext_irec[erp_idx];45914591- else45924592- break;45934593- }45944594- ep = &erp->er_extbuf[erp->er_extcount];45954595- erp_next = erp + 1;45964596- ep_next = erp_next->er_extbuf;45974515 }45984516}45994517