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>
This commit is contained in:
parent
2dc164f296
commit
fdd3cceef4
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Greedy allocation. May fail and may return vmalloced memory.
|
* Greedy allocation. May fail and may return vmalloced memory.
|
||||||
*
|
|
||||||
* Must be freed using kmem_free_large.
|
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize)
|
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)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
size_t kmsize = maxsize;
|
size_t kmsize = maxsize;
|
||||||
|
|
||||||
while (!(ptr = kmem_zalloc_large(kmsize))) {
|
while (!(ptr = vzalloc(kmsize))) {
|
||||||
if ((kmsize >>= 1) <= minsize)
|
if ((kmsize >>= 1) <= minsize)
|
||||||
kmsize = minsize;
|
kmsize = minsize;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +73,17 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = kmem_zalloc(size, flags | KM_MAYFAIL);
|
||||||
|
if (ptr)
|
||||||
|
return ptr;
|
||||||
|
return vzalloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kmem_free(const void *ptr)
|
kmem_free(const void *ptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,17 +57,10 @@ kmem_flags_convert(xfs_km_flags_t flags)
|
||||||
|
|
||||||
extern void *kmem_alloc(size_t, xfs_km_flags_t);
|
extern void *kmem_alloc(size_t, xfs_km_flags_t);
|
||||||
extern void *kmem_zalloc(size_t, xfs_km_flags_t);
|
extern void *kmem_zalloc(size_t, xfs_km_flags_t);
|
||||||
|
extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
|
||||||
extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t);
|
extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t);
|
||||||
extern void kmem_free(const void *);
|
extern void kmem_free(const void *);
|
||||||
|
|
||||||
static inline void *kmem_zalloc_large(size_t size)
|
|
||||||
{
|
|
||||||
return vzalloc(size);
|
|
||||||
}
|
|
||||||
static inline void kmem_free_large(void *ptr)
|
|
||||||
{
|
|
||||||
vfree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void *kmem_zalloc_greedy(size_t *, size_t, size_t);
|
extern void *kmem_zalloc_greedy(size_t *, size_t, size_t);
|
||||||
|
|
||||||
|
|
|
@ -152,12 +152,9 @@ xfs_get_acl(struct inode *inode, int type)
|
||||||
* go out to the disk.
|
* go out to the disk.
|
||||||
*/
|
*/
|
||||||
len = XFS_ACL_MAX_SIZE(ip->i_mount);
|
len = XFS_ACL_MAX_SIZE(ip->i_mount);
|
||||||
xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
|
xfs_acl = kmem_zalloc_large(len, KM_SLEEP);
|
||||||
if (!xfs_acl) {
|
|
||||||
xfs_acl = kmem_zalloc_large(len);
|
|
||||||
if (!xfs_acl)
|
if (!xfs_acl)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
|
||||||
|
|
||||||
error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl,
|
error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl,
|
||||||
&len, ATTR_ROOT);
|
&len, ATTR_ROOT);
|
||||||
|
@ -181,10 +178,7 @@ xfs_get_acl(struct inode *inode, int type)
|
||||||
out_update_cache:
|
out_update_cache:
|
||||||
set_cached_acl(inode, type, acl);
|
set_cached_acl(inode, type, acl);
|
||||||
out:
|
out:
|
||||||
if (is_vmalloc_addr(xfs_acl))
|
kmem_free(xfs_acl);
|
||||||
kmem_free_large(xfs_acl);
|
|
||||||
else
|
|
||||||
kfree(xfs_acl);
|
|
||||||
return acl;
|
return acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,12 +209,9 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
||||||
struct xfs_acl *xfs_acl;
|
struct xfs_acl *xfs_acl;
|
||||||
int len = XFS_ACL_MAX_SIZE(ip->i_mount);
|
int len = XFS_ACL_MAX_SIZE(ip->i_mount);
|
||||||
|
|
||||||
xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
|
xfs_acl = kmem_zalloc_large(len, KM_SLEEP);
|
||||||
if (!xfs_acl) {
|
|
||||||
xfs_acl = kmem_zalloc_large(len);
|
|
||||||
if (!xfs_acl)
|
if (!xfs_acl)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
xfs_acl_to_disk(xfs_acl, acl);
|
xfs_acl_to_disk(xfs_acl, acl);
|
||||||
|
|
||||||
|
@ -231,10 +222,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
||||||
error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
|
error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
|
||||||
len, ATTR_ROOT);
|
len, ATTR_ROOT);
|
||||||
|
|
||||||
if (is_vmalloc_addr(xfs_acl))
|
kmem_free(xfs_acl);
|
||||||
kmem_free_large(xfs_acl);
|
|
||||||
else
|
|
||||||
kfree(xfs_acl);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* A NULL ACL argument means we want to remove the ACL.
|
* A NULL ACL argument means we want to remove the ACL.
|
||||||
|
|
|
@ -612,13 +612,9 @@ xfs_getbmap(
|
||||||
|
|
||||||
if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx))
|
if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx))
|
||||||
return XFS_ERROR(ENOMEM);
|
return XFS_ERROR(ENOMEM);
|
||||||
out = kmem_zalloc(bmv->bmv_count * sizeof(struct getbmapx), KM_MAYFAIL);
|
out = kmem_zalloc_large(bmv->bmv_count * sizeof(struct getbmapx), 0);
|
||||||
if (!out) {
|
|
||||||
out = kmem_zalloc_large(bmv->bmv_count *
|
|
||||||
sizeof(struct getbmapx));
|
|
||||||
if (!out)
|
if (!out)
|
||||||
return XFS_ERROR(ENOMEM);
|
return XFS_ERROR(ENOMEM);
|
||||||
}
|
|
||||||
|
|
||||||
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
||||||
if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
|
if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
|
||||||
|
@ -754,9 +750,6 @@ xfs_getbmap(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_vmalloc_addr(out))
|
|
||||||
kmem_free_large(out);
|
|
||||||
else
|
|
||||||
kmem_free(out);
|
kmem_free(out);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,12 +456,9 @@ xfs_attrlist_by_handle(
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
return PTR_ERR(dentry);
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL);
|
kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP);
|
||||||
if (!kbuf) {
|
|
||||||
kbuf = kmem_zalloc_large(al_hreq.buflen);
|
|
||||||
if (!kbuf)
|
if (!kbuf)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
}
|
|
||||||
|
|
||||||
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
||||||
error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
|
error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
|
||||||
|
@ -472,12 +469,9 @@ xfs_attrlist_by_handle(
|
||||||
if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
|
if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
|
|
||||||
out_kfree:
|
out_kfree:
|
||||||
if (is_vmalloc_addr(kbuf))
|
|
||||||
kmem_free_large(kbuf);
|
|
||||||
else
|
|
||||||
kmem_free(kbuf);
|
kmem_free(kbuf);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -495,12 +489,9 @@ xfs_attrmulti_attr_get(
|
||||||
|
|
||||||
if (*len > XATTR_SIZE_MAX)
|
if (*len > XATTR_SIZE_MAX)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
kbuf = kmem_zalloc(*len, KM_SLEEP | KM_MAYFAIL);
|
kbuf = kmem_zalloc_large(*len, KM_SLEEP);
|
||||||
if (!kbuf) {
|
|
||||||
kbuf = kmem_zalloc_large(*len);
|
|
||||||
if (!kbuf)
|
if (!kbuf)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
|
error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -509,10 +500,7 @@ xfs_attrmulti_attr_get(
|
||||||
if (copy_to_user(ubuf, kbuf, *len))
|
if (copy_to_user(ubuf, kbuf, *len))
|
||||||
error = EFAULT;
|
error = EFAULT;
|
||||||
|
|
||||||
out_kfree:
|
out_kfree:
|
||||||
if (is_vmalloc_addr(kbuf))
|
|
||||||
kmem_free_large(kbuf);
|
|
||||||
else
|
|
||||||
kmem_free(kbuf);
|
kmem_free(kbuf);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,12 +371,9 @@ xfs_compat_attrlist_by_handle(
|
||||||
return PTR_ERR(dentry);
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL);
|
kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP);
|
||||||
if (!kbuf) {
|
|
||||||
kbuf = kmem_zalloc_large(al_hreq.buflen);
|
|
||||||
if (!kbuf)
|
if (!kbuf)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
}
|
|
||||||
|
|
||||||
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
||||||
error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
|
error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
|
||||||
|
@ -387,12 +384,9 @@ xfs_compat_attrlist_by_handle(
|
||||||
if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
|
if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
|
|
||||||
out_kfree:
|
out_kfree:
|
||||||
if (is_vmalloc_addr(kbuf))
|
|
||||||
kmem_free_large(kbuf);
|
|
||||||
else
|
|
||||||
kmem_free(kbuf);
|
kmem_free(kbuf);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,7 +495,7 @@ xfs_bulkstat(
|
||||||
/*
|
/*
|
||||||
* Done, we're either out of filesystem or space to put the data.
|
* Done, we're either out of filesystem or space to put the data.
|
||||||
*/
|
*/
|
||||||
kmem_free_large(irbuf);
|
kmem_free(irbuf);
|
||||||
*ubcountp = ubelem;
|
*ubcountp = ubelem;
|
||||||
/*
|
/*
|
||||||
* Found some inodes, return them now and return the error next time.
|
* Found some inodes, return them now and return the error next time.
|
||||||
|
|
Loading…
Reference in New Issue