aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-09-02 06:53:00 -0400
committerBen Myers <bpm@sgi.com>2013-09-10 14:57:03 -0400
commitfdd3cceef46f2c18c618669cfae5c0f47d6982f9 (patch)
tree4f408c2bc2bc36bf5f4da36fd0e0f51fc4857964
parent2dc164f2965b92a6efd2edb9e2813271741e96db (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.c15
-rw-r--r--fs/xfs/kmem.h9
-rw-r--r--fs/xfs/xfs_acl.c28
-rw-r--r--fs/xfs/xfs_bmap_util.c15
-rw-r--r--fs/xfs/xfs_ioctl.c34
-rw-r--r--fs/xfs/xfs_ioctl32.c18
-rw-r--r--fs/xfs/xfs_itable.c2
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 */
33void * 31void *
34kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize) 32kmem_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
76void *
77kmem_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
78void 87void
79kmem_free(const void *ptr) 88kmem_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
58extern void *kmem_alloc(size_t, xfs_km_flags_t); 58extern void *kmem_alloc(size_t, xfs_km_flags_t);
59extern void *kmem_zalloc(size_t, xfs_km_flags_t); 59extern void *kmem_zalloc(size_t, xfs_km_flags_t);
60extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
60extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t); 61extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t);
61extern void kmem_free(const void *); 62extern void kmem_free(const void *);
62 63
63static inline void *kmem_zalloc_large(size_t size)
64{
65 return vzalloc(size);
66}
67static inline void kmem_free_large(void *ptr)
68{
69 vfree(ptr);
70}
71 64
72extern void *kmem_zalloc_greedy(size_t *, size_t, size_t); 65extern 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)
181out_update_cache: 178out_update_cache:
182 set_cached_acl(inode, type, acl); 179 set_cached_acl(inode, type, acl);
183out: 180out:
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: 472out_kfree:
476 if (is_vmalloc_addr(kbuf)) 473 kmem_free(kbuf);
477 kmem_free_large(kbuf); 474out_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: 503out_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: 387out_kfree:
391 if (is_vmalloc_addr(kbuf)) 388 kmem_free(kbuf);
392 kmem_free_large(kbuf); 389out_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.