Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fdd3ccee authored by Dave Chinner's avatar Dave Chinner Committed by Ben Myers
Browse files

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarMark Tinguely <tinguely@sgi.com>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>
parent 2dc164f2
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -27,8 +27,6 @@

/*
 * Greedy allocation.  May fail and may return vmalloced memory.
 *
 * Must be freed using kmem_free_large.
 */
void *
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;
	size_t		kmsize = maxsize;

	while (!(ptr = kmem_zalloc_large(kmsize))) {
	while (!(ptr = vzalloc(kmsize))) {
		if ((kmsize >>= 1) <= minsize)
			kmsize = minsize;
	}
@@ -75,6 +73,17 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags)
	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
kmem_free(const void *ptr)
{
+1 −8
Original line number Diff line number Diff line
@@ -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_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_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);

+8 −20
Original line number Diff line number Diff line
@@ -152,12 +152,9 @@ xfs_get_acl(struct inode *inode, int type)
	 * go out to the disk.
	 */
	len = XFS_ACL_MAX_SIZE(ip->i_mount);
	xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
	if (!xfs_acl) {
		xfs_acl = kmem_zalloc_large(len);
	xfs_acl = kmem_zalloc_large(len, KM_SLEEP);
	if (!xfs_acl)
		return ERR_PTR(-ENOMEM);
	}

	error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl,
							&len, ATTR_ROOT);
@@ -181,10 +178,7 @@ xfs_get_acl(struct inode *inode, int type)
out_update_cache:
	set_cached_acl(inode, type, acl);
out:
	if (is_vmalloc_addr(xfs_acl))
		kmem_free_large(xfs_acl);
	else
		kfree(xfs_acl);
	kmem_free(xfs_acl);
	return acl;
}

@@ -215,12 +209,9 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
		struct xfs_acl *xfs_acl;
		int len = XFS_ACL_MAX_SIZE(ip->i_mount);

		xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
		if (!xfs_acl) {
			xfs_acl = kmem_zalloc_large(len);
		xfs_acl = kmem_zalloc_large(len, KM_SLEEP);
		if (!xfs_acl)
			return -ENOMEM;
		}

		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,
				len, ATTR_ROOT);

		if (is_vmalloc_addr(xfs_acl))
			kmem_free_large(xfs_acl);
		else
			kfree(xfs_acl);
		kmem_free(xfs_acl);
	} else {
		/*
		 * A NULL ACL argument means we want to remove the ACL.
+4 −11
Original line number Diff line number Diff line
@@ -612,13 +612,9 @@ xfs_getbmap(

	if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx))
		return XFS_ERROR(ENOMEM);
	out = kmem_zalloc(bmv->bmv_count * sizeof(struct getbmapx), KM_MAYFAIL);
	if (!out) {
		out = kmem_zalloc_large(bmv->bmv_count *
					sizeof(struct getbmapx));
	out = kmem_zalloc_large(bmv->bmv_count * sizeof(struct getbmapx), 0);
	if (!out)
		return XFS_ERROR(ENOMEM);
	}

	xfs_ilock(ip, XFS_IOLOCK_SHARED);
	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
@@ -754,9 +750,6 @@ xfs_getbmap(
			break;
	}

	if (is_vmalloc_addr(out))
		kmem_free_large(out);
	else
	kmem_free(out);
	return error;
}
+11 −23
Original line number Diff line number Diff line
@@ -456,12 +456,9 @@ xfs_attrlist_by_handle(
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL);
	if (!kbuf) {
		kbuf = kmem_zalloc_large(al_hreq.buflen);
	kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP);
	if (!kbuf)
		goto out_dput;
	}

	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
	error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
@@ -473,9 +470,6 @@ xfs_attrlist_by_handle(
		error = -EFAULT;

out_kfree:
	if (is_vmalloc_addr(kbuf))
		kmem_free_large(kbuf);
	else
	kmem_free(kbuf);
out_dput:
	dput(dentry);
@@ -495,12 +489,9 @@ xfs_attrmulti_attr_get(

	if (*len > XATTR_SIZE_MAX)
		return EINVAL;
	kbuf = kmem_zalloc(*len, KM_SLEEP | KM_MAYFAIL);
	if (!kbuf) {
		kbuf = kmem_zalloc_large(*len);
	kbuf = kmem_zalloc_large(*len, KM_SLEEP);
	if (!kbuf)
		return ENOMEM;
	}

	error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
	if (error)
@@ -510,9 +501,6 @@ xfs_attrmulti_attr_get(
		error = EFAULT;

out_kfree:
	if (is_vmalloc_addr(kbuf))
		kmem_free_large(kbuf);
	else
	kmem_free(kbuf);
	return error;
}
Loading