diff options
author | Dave Chinner <dchinner@redhat.com> | 2013-09-02 06:53:00 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-09-10 14:57:03 -0400 |
commit | fdd3cceef46f2c18c618669cfae5c0f47d6982f9 (patch) | |
tree | 4f408c2bc2bc36bf5f4da36fd0e0f51fc4857964 | |
parent | 2dc164f2965b92a6efd2edb9e2813271741e96db (diff) |
xfs: factor all the kmalloc-or-vmalloc fallback allocations
We have quite a few places now where we do:
x = kmem_zalloc(large size)
if (!x)
x = kmem_zalloc_large(large size)
and do a similar dance when freeing the memory. kmem_free() already
does the correct freeing dance, and kmem_zalloc_large() is only ever
called in these constructs, so just factor it all into
kmem_zalloc_large() and kmem_free().
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r-- | fs/xfs/kmem.c | 15 | ||||
-rw-r--r-- | fs/xfs/kmem.h | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.c | 28 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 34 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl32.c | 18 | ||||
-rw-r--r-- | fs/xfs/xfs_itable.c | 2 |
7 files changed, 43 insertions, 78 deletions
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index 4a7286c1dc80..a02cfb9e3bce 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c | |||
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Greedy allocation. May fail and may return vmalloced memory. | 29 | * Greedy allocation. May fail and may return vmalloced memory. |
30 | * | ||
31 | * Must be freed using kmem_free_large. | ||
32 | */ | 30 | */ |
33 | void * | 31 | void * |
34 | kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize) | 32 | kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize) |
@@ -36,7 +34,7 @@ kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize) | |||
36 | void *ptr; | 34 | void *ptr; |
37 | size_t kmsize = maxsize; | 35 | size_t kmsize = maxsize; |
38 | 36 | ||
39 | while (!(ptr = kmem_zalloc_large(kmsize))) { | 37 | while (!(ptr = vzalloc(kmsize))) { |
40 | if ((kmsize >>= 1) <= minsize) | 38 | if ((kmsize >>= 1) <= minsize) |
41 | kmsize = minsize; | 39 | kmsize = minsize; |
42 | } | 40 | } |
@@ -75,6 +73,17 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags) | |||
75 | return ptr; | 73 | return ptr; |
76 | } | 74 | } |
77 | 75 | ||
76 | void * | ||
77 | kmem_zalloc_large(size_t size, xfs_km_flags_t flags) | ||
78 | { | ||
79 | void *ptr; | ||
80 | |||
81 | ptr = kmem_zalloc(size, flags | KM_MAYFAIL); | ||
82 | if (ptr) | ||
83 | return ptr; | ||
84 | return vzalloc(size); | ||
85 | } | ||
86 | |||
78 | void | 87 | void |
79 | kmem_free(const void *ptr) | 88 | kmem_free(const void *ptr) |
80 | { | 89 | { |
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h index b2f2620f9a87..3a7371cab508 100644 --- a/fs/xfs/kmem.h +++ b/fs/xfs/kmem.h | |||
@@ -57,17 +57,10 @@ kmem_flags_convert(xfs_km_flags_t flags) | |||
57 | 57 | ||
58 | extern void *kmem_alloc(size_t, xfs_km_flags_t); | 58 | extern void *kmem_alloc(size_t, xfs_km_flags_t); |
59 | extern void *kmem_zalloc(size_t, xfs_km_flags_t); | 59 | extern void *kmem_zalloc(size_t, xfs_km_flags_t); |
60 | extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t); | ||
60 | extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t); | 61 | extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t); |
61 | extern void kmem_free(const void *); | 62 | extern void kmem_free(const void *); |
62 | 63 | ||
63 | static inline void *kmem_zalloc_large(size_t size) | ||
64 | { | ||
65 | return vzalloc(size); | ||
66 | } | ||
67 | static inline void kmem_free_large(void *ptr) | ||
68 | { | ||
69 | vfree(ptr); | ||
70 | } | ||
71 | 64 | ||
72 | extern void *kmem_zalloc_greedy(size_t *, size_t, size_t); | 65 | extern void *kmem_zalloc_greedy(size_t *, size_t, size_t); |
73 | 66 | ||
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4ea73cc44259..0e2f37efedd0 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -152,12 +152,9 @@ xfs_get_acl(struct inode *inode, int type) | |||
152 | * go out to the disk. | 152 | * go out to the disk. |
153 | */ | 153 | */ |
154 | len = XFS_ACL_MAX_SIZE(ip->i_mount); | 154 | len = XFS_ACL_MAX_SIZE(ip->i_mount); |
155 | xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL); | 155 | xfs_acl = kmem_zalloc_large(len, KM_SLEEP); |
156 | if (!xfs_acl) { | 156 | if (!xfs_acl) |
157 | xfs_acl = kmem_zalloc_large(len); | 157 | return ERR_PTR(-ENOMEM); |
158 | if (!xfs_acl) | ||
159 | return ERR_PTR(-ENOMEM); | ||
160 | } | ||
161 | 158 | ||
162 | error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl, | 159 | error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl, |
163 | &len, ATTR_ROOT); | 160 | &len, ATTR_ROOT); |
@@ -181,10 +178,7 @@ xfs_get_acl(struct inode *inode, int type) | |||
181 | out_update_cache: | 178 | out_update_cache: |
182 | set_cached_acl(inode, type, acl); | 179 | set_cached_acl(inode, type, acl); |
183 | out: | 180 | out: |
184 | if (is_vmalloc_addr(xfs_acl)) | 181 | kmem_free(xfs_acl); |
185 | kmem_free_large(xfs_acl); | ||
186 | else | ||
187 | kfree(xfs_acl); | ||
188 | return acl; | 182 | return acl; |
189 | } | 183 | } |
190 | 184 | ||
@@ -215,12 +209,9 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
215 | struct xfs_acl *xfs_acl; | 209 | struct xfs_acl *xfs_acl; |
216 | int len = XFS_ACL_MAX_SIZE(ip->i_mount); | 210 | int len = XFS_ACL_MAX_SIZE(ip->i_mount); |
217 | 211 | ||
218 | xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL); | 212 | xfs_acl = kmem_zalloc_large(len, KM_SLEEP); |
219 | if (!xfs_acl) { | 213 | if (!xfs_acl) |
220 | xfs_acl = kmem_zalloc_large(len); | 214 | return -ENOMEM; |
221 | if (!xfs_acl) | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | 215 | ||
225 | xfs_acl_to_disk(xfs_acl, acl); | 216 | xfs_acl_to_disk(xfs_acl, acl); |
226 | 217 | ||
@@ -231,10 +222,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
231 | error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl, | 222 | error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl, |
232 | len, ATTR_ROOT); | 223 | len, ATTR_ROOT); |
233 | 224 | ||
234 | if (is_vmalloc_addr(xfs_acl)) | 225 | kmem_free(xfs_acl); |
235 | kmem_free_large(xfs_acl); | ||
236 | else | ||
237 | kfree(xfs_acl); | ||
238 | } else { | 226 | } else { |
239 | /* | 227 | /* |
240 | * A NULL ACL argument means we want to remove the ACL. | 228 | * A NULL ACL argument means we want to remove the ACL. |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index c6dc55142cbe..97f952caea74 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -612,13 +612,9 @@ xfs_getbmap( | |||
612 | 612 | ||
613 | if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx)) | 613 | if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx)) |
614 | return XFS_ERROR(ENOMEM); | 614 | return XFS_ERROR(ENOMEM); |
615 | out = kmem_zalloc(bmv->bmv_count * sizeof(struct getbmapx), KM_MAYFAIL); | 615 | out = kmem_zalloc_large(bmv->bmv_count * sizeof(struct getbmapx), 0); |
616 | if (!out) { | 616 | if (!out) |
617 | out = kmem_zalloc_large(bmv->bmv_count * | 617 | return XFS_ERROR(ENOMEM); |
618 | sizeof(struct getbmapx)); | ||
619 | if (!out) | ||
620 | return XFS_ERROR(ENOMEM); | ||
621 | } | ||
622 | 618 | ||
623 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 619 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
624 | if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { | 620 | if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { |
@@ -754,10 +750,7 @@ xfs_getbmap( | |||
754 | break; | 750 | break; |
755 | } | 751 | } |
756 | 752 | ||
757 | if (is_vmalloc_addr(out)) | 753 | kmem_free(out); |
758 | kmem_free_large(out); | ||
759 | else | ||
760 | kmem_free(out); | ||
761 | return error; | 754 | return error; |
762 | } | 755 | } |
763 | 756 | ||
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 21d9c9df9fb7..668e8f4ccf5e 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -456,12 +456,9 @@ xfs_attrlist_by_handle( | |||
456 | if (IS_ERR(dentry)) | 456 | if (IS_ERR(dentry)) |
457 | return PTR_ERR(dentry); | 457 | return PTR_ERR(dentry); |
458 | 458 | ||
459 | kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL); | 459 | kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP); |
460 | if (!kbuf) { | 460 | if (!kbuf) |
461 | kbuf = kmem_zalloc_large(al_hreq.buflen); | 461 | goto out_dput; |
462 | if (!kbuf) | ||
463 | goto out_dput; | ||
464 | } | ||
465 | 462 | ||
466 | cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; | 463 | cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; |
467 | error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, | 464 | error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, |
@@ -472,12 +469,9 @@ xfs_attrlist_by_handle( | |||
472 | if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen)) | 469 | if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen)) |
473 | error = -EFAULT; | 470 | error = -EFAULT; |
474 | 471 | ||
475 | out_kfree: | 472 | out_kfree: |
476 | if (is_vmalloc_addr(kbuf)) | 473 | kmem_free(kbuf); |
477 | kmem_free_large(kbuf); | 474 | out_dput: |
478 | else | ||
479 | kmem_free(kbuf); | ||
480 | out_dput: | ||
481 | dput(dentry); | 475 | dput(dentry); |
482 | return error; | 476 | return error; |
483 | } | 477 | } |
@@ -495,12 +489,9 @@ xfs_attrmulti_attr_get( | |||
495 | 489 | ||
496 | if (*len > XATTR_SIZE_MAX) | 490 | if (*len > XATTR_SIZE_MAX) |
497 | return EINVAL; | 491 | return EINVAL; |
498 | kbuf = kmem_zalloc(*len, KM_SLEEP | KM_MAYFAIL); | 492 | kbuf = kmem_zalloc_large(*len, KM_SLEEP); |
499 | if (!kbuf) { | 493 | if (!kbuf) |
500 | kbuf = kmem_zalloc_large(*len); | 494 | return ENOMEM; |
501 | if (!kbuf) | ||
502 | return ENOMEM; | ||
503 | } | ||
504 | 495 | ||
505 | error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); | 496 | error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); |
506 | if (error) | 497 | if (error) |
@@ -509,11 +500,8 @@ xfs_attrmulti_attr_get( | |||
509 | if (copy_to_user(ubuf, kbuf, *len)) | 500 | if (copy_to_user(ubuf, kbuf, *len)) |
510 | error = EFAULT; | 501 | error = EFAULT; |
511 | 502 | ||
512 | out_kfree: | 503 | out_kfree: |
513 | if (is_vmalloc_addr(kbuf)) | 504 | kmem_free(kbuf); |
514 | kmem_free_large(kbuf); | ||
515 | else | ||
516 | kmem_free(kbuf); | ||
517 | return error; | 505 | return error; |
518 | } | 506 | } |
519 | 507 | ||
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index d3ab9534307f..f671f7e472ac 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c | |||
@@ -371,12 +371,9 @@ xfs_compat_attrlist_by_handle( | |||
371 | return PTR_ERR(dentry); | 371 | return PTR_ERR(dentry); |
372 | 372 | ||
373 | error = -ENOMEM; | 373 | error = -ENOMEM; |
374 | kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL); | 374 | kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP); |
375 | if (!kbuf) { | 375 | if (!kbuf) |
376 | kbuf = kmem_zalloc_large(al_hreq.buflen); | 376 | goto out_dput; |
377 | if (!kbuf) | ||
378 | goto out_dput; | ||
379 | } | ||
380 | 377 | ||
381 | cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; | 378 | cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; |
382 | error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, | 379 | error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, |
@@ -387,12 +384,9 @@ xfs_compat_attrlist_by_handle( | |||
387 | if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen)) | 384 | if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen)) |
388 | error = -EFAULT; | 385 | error = -EFAULT; |
389 | 386 | ||
390 | out_kfree: | 387 | out_kfree: |
391 | if (is_vmalloc_addr(kbuf)) | 388 | kmem_free(kbuf); |
392 | kmem_free_large(kbuf); | 389 | out_dput: |
393 | else | ||
394 | kmem_free(kbuf); | ||
395 | out_dput: | ||
396 | dput(dentry); | 390 | dput(dentry); |
397 | return error; | 391 | return error; |
398 | } | 392 | } |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 8a67d53b9b7a..084b3e1741fd 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -495,7 +495,7 @@ xfs_bulkstat( | |||
495 | /* | 495 | /* |
496 | * Done, we're either out of filesystem or space to put the data. | 496 | * Done, we're either out of filesystem or space to put the data. |
497 | */ | 497 | */ |
498 | kmem_free_large(irbuf); | 498 | kmem_free(irbuf); |
499 | *ubcountp = ubelem; | 499 | *ubcountp = ubelem; |
500 | /* | 500 | /* |
501 | * Found some inodes, return them now and return the error next time. | 501 | * Found some inodes, return them now and return the error next time. |