diff options
Diffstat (limited to 'mm/slub.c')
-rw-r--r-- | mm/slub.c | 167 |
1 files changed, 134 insertions, 33 deletions
@@ -17,9 +17,11 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <trace/kmemtrace.h> | 20 | #include <linux/kmemtrace.h> |
21 | #include <linux/kmemcheck.h> | ||
21 | #include <linux/cpu.h> | 22 | #include <linux/cpu.h> |
22 | #include <linux/cpuset.h> | 23 | #include <linux/cpuset.h> |
24 | #include <linux/kmemleak.h> | ||
23 | #include <linux/mempolicy.h> | 25 | #include <linux/mempolicy.h> |
24 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
25 | #include <linux/debugobjects.h> | 27 | #include <linux/debugobjects.h> |
@@ -143,10 +145,10 @@ | |||
143 | * Set of flags that will prevent slab merging | 145 | * Set of flags that will prevent slab merging |
144 | */ | 146 | */ |
145 | #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \ | 147 | #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \ |
146 | SLAB_TRACE | SLAB_DESTROY_BY_RCU) | 148 | SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE) |
147 | 149 | ||
148 | #define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \ | 150 | #define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \ |
149 | SLAB_CACHE_DMA) | 151 | SLAB_CACHE_DMA | SLAB_NOTRACK) |
150 | 152 | ||
151 | #ifndef ARCH_KMALLOC_MINALIGN | 153 | #ifndef ARCH_KMALLOC_MINALIGN |
152 | #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) | 154 | #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) |
@@ -177,6 +179,12 @@ static enum { | |||
177 | SYSFS /* Sysfs up */ | 179 | SYSFS /* Sysfs up */ |
178 | } slab_state = DOWN; | 180 | } slab_state = DOWN; |
179 | 181 | ||
182 | /* | ||
183 | * The slab allocator is initialized with interrupts disabled. Therefore, make | ||
184 | * sure early boot allocations don't accidentally enable interrupts. | ||
185 | */ | ||
186 | static gfp_t slab_gfp_mask __read_mostly = SLAB_GFP_BOOT_MASK; | ||
187 | |||
180 | /* A list of all slab caches on the system */ | 188 | /* A list of all slab caches on the system */ |
181 | static DECLARE_RWSEM(slub_lock); | 189 | static DECLARE_RWSEM(slub_lock); |
182 | static LIST_HEAD(slab_caches); | 190 | static LIST_HEAD(slab_caches); |
@@ -832,6 +840,11 @@ static inline unsigned long slabs_node(struct kmem_cache *s, int node) | |||
832 | return atomic_long_read(&n->nr_slabs); | 840 | return atomic_long_read(&n->nr_slabs); |
833 | } | 841 | } |
834 | 842 | ||
843 | static inline unsigned long node_nr_slabs(struct kmem_cache_node *n) | ||
844 | { | ||
845 | return atomic_long_read(&n->nr_slabs); | ||
846 | } | ||
847 | |||
835 | static inline void inc_slabs_node(struct kmem_cache *s, int node, int objects) | 848 | static inline void inc_slabs_node(struct kmem_cache *s, int node, int objects) |
836 | { | 849 | { |
837 | struct kmem_cache_node *n = get_node(s, node); | 850 | struct kmem_cache_node *n = get_node(s, node); |
@@ -1050,6 +1063,8 @@ static inline unsigned long kmem_cache_flags(unsigned long objsize, | |||
1050 | 1063 | ||
1051 | static inline unsigned long slabs_node(struct kmem_cache *s, int node) | 1064 | static inline unsigned long slabs_node(struct kmem_cache *s, int node) |
1052 | { return 0; } | 1065 | { return 0; } |
1066 | static inline unsigned long node_nr_slabs(struct kmem_cache_node *n) | ||
1067 | { return 0; } | ||
1053 | static inline void inc_slabs_node(struct kmem_cache *s, int node, | 1068 | static inline void inc_slabs_node(struct kmem_cache *s, int node, |
1054 | int objects) {} | 1069 | int objects) {} |
1055 | static inline void dec_slabs_node(struct kmem_cache *s, int node, | 1070 | static inline void dec_slabs_node(struct kmem_cache *s, int node, |
@@ -1064,6 +1079,8 @@ static inline struct page *alloc_slab_page(gfp_t flags, int node, | |||
1064 | { | 1079 | { |
1065 | int order = oo_order(oo); | 1080 | int order = oo_order(oo); |
1066 | 1081 | ||
1082 | flags |= __GFP_NOTRACK; | ||
1083 | |||
1067 | if (node == -1) | 1084 | if (node == -1) |
1068 | return alloc_pages(flags, order); | 1085 | return alloc_pages(flags, order); |
1069 | else | 1086 | else |
@@ -1091,6 +1108,24 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) | |||
1091 | 1108 | ||
1092 | stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK); | 1109 | stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK); |
1093 | } | 1110 | } |
1111 | |||
1112 | if (kmemcheck_enabled | ||
1113 | && !(s->flags & (SLAB_NOTRACK | DEBUG_DEFAULT_FLAGS))) | ||
1114 | { | ||
1115 | int pages = 1 << oo_order(oo); | ||
1116 | |||
1117 | kmemcheck_alloc_shadow(page, oo_order(oo), flags, node); | ||
1118 | |||
1119 | /* | ||
1120 | * Objects from caches that have a constructor don't get | ||
1121 | * cleared when they're allocated, so we need to do it here. | ||
1122 | */ | ||
1123 | if (s->ctor) | ||
1124 | kmemcheck_mark_uninitialized_pages(page, pages); | ||
1125 | else | ||
1126 | kmemcheck_mark_unallocated_pages(page, pages); | ||
1127 | } | ||
1128 | |||
1094 | page->objects = oo_objects(oo); | 1129 | page->objects = oo_objects(oo); |
1095 | mod_zone_page_state(page_zone(page), | 1130 | mod_zone_page_state(page_zone(page), |
1096 | (s->flags & SLAB_RECLAIM_ACCOUNT) ? | 1131 | (s->flags & SLAB_RECLAIM_ACCOUNT) ? |
@@ -1164,6 +1199,8 @@ static void __free_slab(struct kmem_cache *s, struct page *page) | |||
1164 | __ClearPageSlubDebug(page); | 1199 | __ClearPageSlubDebug(page); |
1165 | } | 1200 | } |
1166 | 1201 | ||
1202 | kmemcheck_free_shadow(page, compound_order(page)); | ||
1203 | |||
1167 | mod_zone_page_state(page_zone(page), | 1204 | mod_zone_page_state(page_zone(page), |
1168 | (s->flags & SLAB_RECLAIM_ACCOUNT) ? | 1205 | (s->flags & SLAB_RECLAIM_ACCOUNT) ? |
1169 | NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, | 1206 | NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, |
@@ -1484,6 +1521,65 @@ static inline int node_match(struct kmem_cache_cpu *c, int node) | |||
1484 | return 1; | 1521 | return 1; |
1485 | } | 1522 | } |
1486 | 1523 | ||
1524 | static int count_free(struct page *page) | ||
1525 | { | ||
1526 | return page->objects - page->inuse; | ||
1527 | } | ||
1528 | |||
1529 | static unsigned long count_partial(struct kmem_cache_node *n, | ||
1530 | int (*get_count)(struct page *)) | ||
1531 | { | ||
1532 | unsigned long flags; | ||
1533 | unsigned long x = 0; | ||
1534 | struct page *page; | ||
1535 | |||
1536 | spin_lock_irqsave(&n->list_lock, flags); | ||
1537 | list_for_each_entry(page, &n->partial, lru) | ||
1538 | x += get_count(page); | ||
1539 | spin_unlock_irqrestore(&n->list_lock, flags); | ||
1540 | return x; | ||
1541 | } | ||
1542 | |||
1543 | static inline unsigned long node_nr_objs(struct kmem_cache_node *n) | ||
1544 | { | ||
1545 | #ifdef CONFIG_SLUB_DEBUG | ||
1546 | return atomic_long_read(&n->total_objects); | ||
1547 | #else | ||
1548 | return 0; | ||
1549 | #endif | ||
1550 | } | ||
1551 | |||
1552 | static noinline void | ||
1553 | slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid) | ||
1554 | { | ||
1555 | int node; | ||
1556 | |||
1557 | printk(KERN_WARNING | ||
1558 | "SLUB: Unable to allocate memory on node %d (gfp=0x%x)\n", | ||
1559 | nid, gfpflags); | ||
1560 | printk(KERN_WARNING " cache: %s, object size: %d, buffer size: %d, " | ||
1561 | "default order: %d, min order: %d\n", s->name, s->objsize, | ||
1562 | s->size, oo_order(s->oo), oo_order(s->min)); | ||
1563 | |||
1564 | for_each_online_node(node) { | ||
1565 | struct kmem_cache_node *n = get_node(s, node); | ||
1566 | unsigned long nr_slabs; | ||
1567 | unsigned long nr_objs; | ||
1568 | unsigned long nr_free; | ||
1569 | |||
1570 | if (!n) | ||
1571 | continue; | ||
1572 | |||
1573 | nr_free = count_partial(n, count_free); | ||
1574 | nr_slabs = node_nr_slabs(n); | ||
1575 | nr_objs = node_nr_objs(n); | ||
1576 | |||
1577 | printk(KERN_WARNING | ||
1578 | " node %d: slabs: %ld, objs: %ld, free: %ld\n", | ||
1579 | node, nr_slabs, nr_objs, nr_free); | ||
1580 | } | ||
1581 | } | ||
1582 | |||
1487 | /* | 1583 | /* |
1488 | * Slow path. The lockless freelist is empty or we need to perform | 1584 | * Slow path. The lockless freelist is empty or we need to perform |
1489 | * debugging duties. | 1585 | * debugging duties. |
@@ -1565,6 +1661,8 @@ new_slab: | |||
1565 | c->page = new; | 1661 | c->page = new; |
1566 | goto load_freelist; | 1662 | goto load_freelist; |
1567 | } | 1663 | } |
1664 | if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit()) | ||
1665 | slab_out_of_memory(s, gfpflags, node); | ||
1568 | return NULL; | 1666 | return NULL; |
1569 | debug: | 1667 | debug: |
1570 | if (!alloc_debug_processing(s, c->page, object, addr)) | 1668 | if (!alloc_debug_processing(s, c->page, object, addr)) |
@@ -1594,6 +1692,8 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, | |||
1594 | unsigned long flags; | 1692 | unsigned long flags; |
1595 | unsigned int objsize; | 1693 | unsigned int objsize; |
1596 | 1694 | ||
1695 | gfpflags &= slab_gfp_mask; | ||
1696 | |||
1597 | lockdep_trace_alloc(gfpflags); | 1697 | lockdep_trace_alloc(gfpflags); |
1598 | might_sleep_if(gfpflags & __GFP_WAIT); | 1698 | might_sleep_if(gfpflags & __GFP_WAIT); |
1599 | 1699 | ||
@@ -1617,6 +1717,9 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, | |||
1617 | if (unlikely((gfpflags & __GFP_ZERO) && object)) | 1717 | if (unlikely((gfpflags & __GFP_ZERO) && object)) |
1618 | memset(object, 0, objsize); | 1718 | memset(object, 0, objsize); |
1619 | 1719 | ||
1720 | kmemcheck_slab_alloc(s, gfpflags, object, c->objsize); | ||
1721 | kmemleak_alloc_recursive(object, objsize, 1, s->flags, gfpflags); | ||
1722 | |||
1620 | return object; | 1723 | return object; |
1621 | } | 1724 | } |
1622 | 1725 | ||
@@ -1746,8 +1849,10 @@ static __always_inline void slab_free(struct kmem_cache *s, | |||
1746 | struct kmem_cache_cpu *c; | 1849 | struct kmem_cache_cpu *c; |
1747 | unsigned long flags; | 1850 | unsigned long flags; |
1748 | 1851 | ||
1852 | kmemleak_free_recursive(x, s->flags); | ||
1749 | local_irq_save(flags); | 1853 | local_irq_save(flags); |
1750 | c = get_cpu_slab(s, smp_processor_id()); | 1854 | c = get_cpu_slab(s, smp_processor_id()); |
1855 | kmemcheck_slab_free(s, object, c->objsize); | ||
1751 | debug_check_no_locks_freed(object, c->objsize); | 1856 | debug_check_no_locks_freed(object, c->objsize); |
1752 | if (!(s->flags & SLAB_DEBUG_OBJECTS)) | 1857 | if (!(s->flags & SLAB_DEBUG_OBJECTS)) |
1753 | debug_check_no_obj_freed(object, c->objsize); | 1858 | debug_check_no_obj_freed(object, c->objsize); |
@@ -2557,13 +2662,16 @@ static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s, | |||
2557 | if (gfp_flags & SLUB_DMA) | 2662 | if (gfp_flags & SLUB_DMA) |
2558 | flags = SLAB_CACHE_DMA; | 2663 | flags = SLAB_CACHE_DMA; |
2559 | 2664 | ||
2560 | down_write(&slub_lock); | 2665 | /* |
2666 | * This function is called with IRQs disabled during early-boot on | ||
2667 | * single CPU so there's no need to take slub_lock here. | ||
2668 | */ | ||
2561 | if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, | 2669 | if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, |
2562 | flags, NULL)) | 2670 | flags, NULL)) |
2563 | goto panic; | 2671 | goto panic; |
2564 | 2672 | ||
2565 | list_add(&s->list, &slab_caches); | 2673 | list_add(&s->list, &slab_caches); |
2566 | up_write(&slub_lock); | 2674 | |
2567 | if (sysfs_slab_add(s)) | 2675 | if (sysfs_slab_add(s)) |
2568 | goto panic; | 2676 | goto panic; |
2569 | return s; | 2677 | return s; |
@@ -2619,7 +2727,8 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags) | |||
2619 | 2727 | ||
2620 | if (!s || !text || !kmem_cache_open(s, flags, text, | 2728 | if (!s || !text || !kmem_cache_open(s, flags, text, |
2621 | realsize, ARCH_KMALLOC_MINALIGN, | 2729 | realsize, ARCH_KMALLOC_MINALIGN, |
2622 | SLAB_CACHE_DMA|__SYSFS_ADD_DEFERRED, NULL)) { | 2730 | SLAB_CACHE_DMA|SLAB_NOTRACK|__SYSFS_ADD_DEFERRED, |
2731 | NULL)) { | ||
2623 | kfree(s); | 2732 | kfree(s); |
2624 | kfree(text); | 2733 | kfree(text); |
2625 | goto unlock_out; | 2734 | goto unlock_out; |
@@ -2713,9 +2822,10 @@ EXPORT_SYMBOL(__kmalloc); | |||
2713 | 2822 | ||
2714 | static void *kmalloc_large_node(size_t size, gfp_t flags, int node) | 2823 | static void *kmalloc_large_node(size_t size, gfp_t flags, int node) |
2715 | { | 2824 | { |
2716 | struct page *page = alloc_pages_node(node, flags | __GFP_COMP, | 2825 | struct page *page; |
2717 | get_order(size)); | ||
2718 | 2826 | ||
2827 | flags |= __GFP_COMP | __GFP_NOTRACK; | ||
2828 | page = alloc_pages_node(node, flags, get_order(size)); | ||
2719 | if (page) | 2829 | if (page) |
2720 | return page_address(page); | 2830 | return page_address(page); |
2721 | else | 2831 | else |
@@ -3021,7 +3131,7 @@ void __init kmem_cache_init(void) | |||
3021 | * kmem_cache_open for slab_state == DOWN. | 3131 | * kmem_cache_open for slab_state == DOWN. |
3022 | */ | 3132 | */ |
3023 | create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node", | 3133 | create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node", |
3024 | sizeof(struct kmem_cache_node), GFP_KERNEL); | 3134 | sizeof(struct kmem_cache_node), GFP_NOWAIT); |
3025 | kmalloc_caches[0].refcount = -1; | 3135 | kmalloc_caches[0].refcount = -1; |
3026 | caches++; | 3136 | caches++; |
3027 | 3137 | ||
@@ -3034,16 +3144,16 @@ void __init kmem_cache_init(void) | |||
3034 | /* Caches that are not of the two-to-the-power-of size */ | 3144 | /* Caches that are not of the two-to-the-power-of size */ |
3035 | if (KMALLOC_MIN_SIZE <= 64) { | 3145 | if (KMALLOC_MIN_SIZE <= 64) { |
3036 | create_kmalloc_cache(&kmalloc_caches[1], | 3146 | create_kmalloc_cache(&kmalloc_caches[1], |
3037 | "kmalloc-96", 96, GFP_KERNEL); | 3147 | "kmalloc-96", 96, GFP_NOWAIT); |
3038 | caches++; | 3148 | caches++; |
3039 | create_kmalloc_cache(&kmalloc_caches[2], | 3149 | create_kmalloc_cache(&kmalloc_caches[2], |
3040 | "kmalloc-192", 192, GFP_KERNEL); | 3150 | "kmalloc-192", 192, GFP_NOWAIT); |
3041 | caches++; | 3151 | caches++; |
3042 | } | 3152 | } |
3043 | 3153 | ||
3044 | for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) { | 3154 | for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) { |
3045 | create_kmalloc_cache(&kmalloc_caches[i], | 3155 | create_kmalloc_cache(&kmalloc_caches[i], |
3046 | "kmalloc", 1 << i, GFP_KERNEL); | 3156 | "kmalloc", 1 << i, GFP_NOWAIT); |
3047 | caches++; | 3157 | caches++; |
3048 | } | 3158 | } |
3049 | 3159 | ||
@@ -3080,7 +3190,7 @@ void __init kmem_cache_init(void) | |||
3080 | /* Provide the correct kmalloc names now that the caches are up */ | 3190 | /* Provide the correct kmalloc names now that the caches are up */ |
3081 | for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) | 3191 | for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) |
3082 | kmalloc_caches[i]. name = | 3192 | kmalloc_caches[i]. name = |
3083 | kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i); | 3193 | kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i); |
3084 | 3194 | ||
3085 | #ifdef CONFIG_SMP | 3195 | #ifdef CONFIG_SMP |
3086 | register_cpu_notifier(&slab_notifier); | 3196 | register_cpu_notifier(&slab_notifier); |
@@ -3098,6 +3208,14 @@ void __init kmem_cache_init(void) | |||
3098 | nr_cpu_ids, nr_node_ids); | 3208 | nr_cpu_ids, nr_node_ids); |
3099 | } | 3209 | } |
3100 | 3210 | ||
3211 | void __init kmem_cache_init_late(void) | ||
3212 | { | ||
3213 | /* | ||
3214 | * Interrupts are enabled now so all GFP allocations are safe. | ||
3215 | */ | ||
3216 | slab_gfp_mask = __GFP_BITS_MASK; | ||
3217 | } | ||
3218 | |||
3101 | /* | 3219 | /* |
3102 | * Find a mergeable slab cache | 3220 | * Find a mergeable slab cache |
3103 | */ | 3221 | */ |
@@ -3318,20 +3436,6 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, | |||
3318 | } | 3436 | } |
3319 | 3437 | ||
3320 | #ifdef CONFIG_SLUB_DEBUG | 3438 | #ifdef CONFIG_SLUB_DEBUG |
3321 | static unsigned long count_partial(struct kmem_cache_node *n, | ||
3322 | int (*get_count)(struct page *)) | ||
3323 | { | ||
3324 | unsigned long flags; | ||
3325 | unsigned long x = 0; | ||
3326 | struct page *page; | ||
3327 | |||
3328 | spin_lock_irqsave(&n->list_lock, flags); | ||
3329 | list_for_each_entry(page, &n->partial, lru) | ||
3330 | x += get_count(page); | ||
3331 | spin_unlock_irqrestore(&n->list_lock, flags); | ||
3332 | return x; | ||
3333 | } | ||
3334 | |||
3335 | static int count_inuse(struct page *page) | 3439 | static int count_inuse(struct page *page) |
3336 | { | 3440 | { |
3337 | return page->inuse; | 3441 | return page->inuse; |
@@ -3342,11 +3446,6 @@ static int count_total(struct page *page) | |||
3342 | return page->objects; | 3446 | return page->objects; |
3343 | } | 3447 | } |
3344 | 3448 | ||
3345 | static int count_free(struct page *page) | ||
3346 | { | ||
3347 | return page->objects - page->inuse; | ||
3348 | } | ||
3349 | |||
3350 | static int validate_slab(struct kmem_cache *s, struct page *page, | 3449 | static int validate_slab(struct kmem_cache *s, struct page *page, |
3351 | unsigned long *map) | 3450 | unsigned long *map) |
3352 | { | 3451 | { |
@@ -3715,7 +3814,7 @@ static int list_locations(struct kmem_cache *s, char *buf, | |||
3715 | to_cpumask(l->cpus)); | 3814 | to_cpumask(l->cpus)); |
3716 | } | 3815 | } |
3717 | 3816 | ||
3718 | if (num_online_nodes() > 1 && !nodes_empty(l->nodes) && | 3817 | if (nr_online_nodes > 1 && !nodes_empty(l->nodes) && |
3719 | len < PAGE_SIZE - 60) { | 3818 | len < PAGE_SIZE - 60) { |
3720 | len += sprintf(buf + len, " nodes="); | 3819 | len += sprintf(buf + len, " nodes="); |
3721 | len += nodelist_scnprintf(buf + len, PAGE_SIZE - len - 50, | 3820 | len += nodelist_scnprintf(buf + len, PAGE_SIZE - len - 50, |
@@ -4390,6 +4489,8 @@ static char *create_unique_id(struct kmem_cache *s) | |||
4390 | *p++ = 'a'; | 4489 | *p++ = 'a'; |
4391 | if (s->flags & SLAB_DEBUG_FREE) | 4490 | if (s->flags & SLAB_DEBUG_FREE) |
4392 | *p++ = 'F'; | 4491 | *p++ = 'F'; |
4492 | if (!(s->flags & SLAB_NOTRACK)) | ||
4493 | *p++ = 't'; | ||
4393 | if (p != name + 1) | 4494 | if (p != name + 1) |
4394 | *p++ = '-'; | 4495 | *p++ = '-'; |
4395 | p += sprintf(p, "%07d", s->size); | 4496 | p += sprintf(p, "%07d", s->size); |