STATIC struct inode * linvfs_alloc_inode( struct super_block *sb) { vnode_t *vp; vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_cachep, kmem_flags_convert(KM_SLEEP)); if (!vp) return NULL; return LINVFS_GET_IP(vp); }
static char * __strdup(const char *str, int flags) { char *ptr; int n; n = strlen(str); ptr = kmalloc(n + 1, kmem_flags_convert(flags)); if (ptr) memcpy(ptr, str, n + 1); return (ptr); }
char * kmem_asprintf(const char *fmt, ...) { va_list ap; char *ptr; do { va_start(ap, fmt); ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, ap); va_end(ap); } while (ptr == NULL); return (ptr); }
char * kmem_vasprintf(const char *fmt, va_list ap) { va_list aq; char *ptr; do { va_copy(aq, ap); ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, aq); va_end(aq); } while (ptr == NULL); return (ptr); }
struct _buf * kobj_open_file(const char *name) { struct _buf *file; vnode_t *vp; int rc; file = kmalloc(sizeof(_buf_t), kmem_flags_convert(KM_SLEEP)); if (file == NULL) return ((_buf_t *)-1UL); if ((rc = vn_open(name, UIO_SYSSPACE, FREAD, 0644, &vp, 0, 0))) { kfree(file); return ((_buf_t *)-1UL); } file->vp = vp; return (file); } /* kobj_open_file() */
/* * General purpose unified implementation of kmem_alloc(). It is an * amalgamation of Linux and Illumos allocator design. It should never be * exported to ensure that code using kmem_alloc()/kmem_zalloc() remains * relatively portable. Consumers may only access this function through * wrappers that enforce the common flags to ensure portability. */ inline void * spl_kmem_alloc_impl(size_t size, int flags, int node) { gfp_t lflags = kmem_flags_convert(flags); int use_vmem = 0; void *ptr; /* * Log abnormally large allocations and rate limit the console output. * Allocations larger than spl_kmem_alloc_warn should be performed * through the vmem_alloc()/vmem_zalloc() interfaces. */ if ((spl_kmem_alloc_warn > 0) && (size > spl_kmem_alloc_warn) && !(flags & KM_VMEM)) { printk(KERN_WARNING "Large kmem_alloc(%lu, 0x%x), please file an issue at:\n" "https://github.com/zfsonlinux/zfs/issues/new\n", (unsigned long)size, flags); dump_stack(); } /* * Use a loop because kmalloc_node() can fail when GFP_KERNEL is used * unlike kmem_alloc() with KM_SLEEP on Illumos. */ do { /* * Calling kmalloc_node() when the size >= spl_kmem_alloc_max * is unsafe. This must fail for all for kmem_alloc() and * kmem_zalloc() callers. * * For vmem_alloc() and vmem_zalloc() callers it is permissible * to use __vmalloc(). However, in general use of __vmalloc() * is strongly discouraged because a global lock must be * acquired. Contention on this lock can significantly * impact performance so frequently manipulating the virtual * address space is strongly discouraged. */ if ((size > spl_kmem_alloc_max) || use_vmem) { if (flags & KM_VMEM) { ptr = __vmalloc(size, lflags, PAGE_KERNEL); } else { return (NULL); } } else { ptr = kmalloc_node(size, lflags, node); } if (likely(ptr) || (flags & KM_NOSLEEP)) return (ptr); /* * For vmem_alloc() and vmem_zalloc() callers retry immediately * using __vmalloc() which is unlikely to fail. */ if ((flags & KM_VMEM) && (use_vmem == 0)) { use_vmem = 1; continue; } /* * Use cond_resched() instead of congestion_wait() to avoid * deadlocking systems where there are no block devices. */ cond_resched(); } while (1); return (NULL); }