]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
xfs: factor all the kmalloc-or-vmalloc fallback allocations
authorDave Chinner <dchinner@redhat.com>
Mon, 2 Sep 2013 10:53:00 +0000 (20:53 +1000)
committerBen Myers <bpm@sgi.com>
Tue, 10 Sep 2013 18:57:03 +0000 (13:57 -0500)
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>
fs/xfs/kmem.c
fs/xfs/kmem.h
fs/xfs/xfs_acl.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_ioctl32.c
fs/xfs/xfs_itable.c

index 4a7286c1dc80d270af40a3733870bb9dd769ee82..a02cfb9e3bcea43d49a033f313387fa217aa789c 100644 (file)
@@ -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)
 {
index b2f2620f9a87b9f1bf6836c8faf3d5039e7af94f..3a7371cab508a7ffea0fc9441d5319026ce089e2 100644 (file)
@@ -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);
 
index 4ea73cc44259030acdc7f66c8af3ff1f2cd88615..0e2f37efedd0547a05b5bec4c0109db83192bb72 100644 (file)
@@ -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);
-               if (!xfs_acl)
-                       return ERR_PTR(-ENOMEM);
-       }
+       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);
-                       if (!xfs_acl)
-                               return -ENOMEM;
-               }
+               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.
index c6dc55142cbe1c7a87ab622c97d3d48660037669..97f952caea74bd8311a3269ca7520e87b01fcb18 100644 (file)
@@ -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));
-               if (!out)
-                       return XFS_ERROR(ENOMEM);
-       }
+       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,10 +750,7 @@ xfs_getbmap(
                        break;
        }
 
-       if (is_vmalloc_addr(out))
-               kmem_free_large(out);
-       else
-               kmem_free(out);
+       kmem_free(out);
        return error;
 }
 
index 21d9c9df9fb72fa0695cc2e2f4a87a0a6550209a..668e8f4ccf5e7201e8e6a360cd26668484f6d515 100644 (file)
@@ -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);
-               if (!kbuf)
-                       goto out_dput;
-       }
+       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,
@@ -472,12 +469,9 @@ xfs_attrlist_by_handle(
        if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
                error = -EFAULT;
 
- out_kfree:
-       if (is_vmalloc_addr(kbuf))
-               kmem_free_large(kbuf);
-       else
-               kmem_free(kbuf);
- out_dput:
+out_kfree:
+       kmem_free(kbuf);
+out_dput:
        dput(dentry);
        return error;
 }
@@ -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);
-               if (!kbuf)
-                       return ENOMEM;
-       }
+       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)
@@ -509,11 +500,8 @@ xfs_attrmulti_attr_get(
        if (copy_to_user(ubuf, kbuf, *len))
                error = EFAULT;
 
- out_kfree:
-       if (is_vmalloc_addr(kbuf))
-               kmem_free_large(kbuf);
-       else
-               kmem_free(kbuf);
+out_kfree:
+       kmem_free(kbuf);
        return error;
 }
 
index d3ab9534307fcaa7e863be8965f80311090ce499..f671f7e472ac008511ca4df2068c9d4fb91d169c 100644 (file)
@@ -371,12 +371,9 @@ xfs_compat_attrlist_by_handle(
                return PTR_ERR(dentry);
 
        error = -ENOMEM;
-       kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL);
-       if (!kbuf) {
-               kbuf = kmem_zalloc_large(al_hreq.buflen);
-               if (!kbuf)
-                       goto out_dput;
-       }
+       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,
@@ -387,12 +384,9 @@ xfs_compat_attrlist_by_handle(
        if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
                error = -EFAULT;
 
- out_kfree:
-       if (is_vmalloc_addr(kbuf))
-               kmem_free_large(kbuf);
-       else
-               kmem_free(kbuf);
- out_dput:
+out_kfree:
+       kmem_free(kbuf);
+out_dput:
        dput(dentry);
        return error;
 }
index 8a67d53b9b7aa4e5d1dfd6be6ed45a2d1caef8e8..084b3e1741fd0346cac1d8279ed8085553ee7486 100644 (file)
@@ -495,7 +495,7 @@ xfs_bulkstat(
        /*
         * Done, we're either out of filesystem or space to put the data.
         */
-       kmem_free_large(irbuf);
+       kmem_free(irbuf);
        *ubcountp = ubelem;
        /*
         * Found some inodes, return them now and return the error next time.