18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * memfd_create system call and file sealing support
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Code was originally included in shmem.c, and broken out to facilitate
58c2ecf20Sopenharmony_ci * use by hugetlbfs as well as tmpfs.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * This file is released under the GPL.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/fs.h>
118c2ecf20Sopenharmony_ci#include <linux/vfs.h>
128c2ecf20Sopenharmony_ci#include <linux/pagemap.h>
138c2ecf20Sopenharmony_ci#include <linux/file.h>
148c2ecf20Sopenharmony_ci#include <linux/mm.h>
158c2ecf20Sopenharmony_ci#include <linux/sched/signal.h>
168c2ecf20Sopenharmony_ci#include <linux/khugepaged.h>
178c2ecf20Sopenharmony_ci#include <linux/syscalls.h>
188c2ecf20Sopenharmony_ci#include <linux/hugetlb.h>
198c2ecf20Sopenharmony_ci#include <linux/shmem_fs.h>
208c2ecf20Sopenharmony_ci#include <linux/memfd.h>
218c2ecf20Sopenharmony_ci#include <uapi/linux/memfd.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * We need a tag: a new tag would expand every xa_node by 8 bytes,
258c2ecf20Sopenharmony_ci * so reuse a tag which we firmly believe is never set or cleared on tmpfs
268c2ecf20Sopenharmony_ci * or hugetlbfs because they are memory only filesystems.
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_ci#define MEMFD_TAG_PINNED        PAGECACHE_TAG_TOWRITE
298c2ecf20Sopenharmony_ci#define LAST_SCAN               4       /* about 150ms max */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic void memfd_tag_pins(struct xa_state *xas)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	struct page *page;
348c2ecf20Sopenharmony_ci	int latency = 0;
358c2ecf20Sopenharmony_ci	int cache_count;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	lru_add_drain();
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	xas_lock_irq(xas);
408c2ecf20Sopenharmony_ci	xas_for_each(xas, page, ULONG_MAX) {
418c2ecf20Sopenharmony_ci		cache_count = 1;
428c2ecf20Sopenharmony_ci		if (!xa_is_value(page) &&
438c2ecf20Sopenharmony_ci		    PageTransHuge(page) && !PageHuge(page))
448c2ecf20Sopenharmony_ci			cache_count = HPAGE_PMD_NR;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci		if (!xa_is_value(page) &&
478c2ecf20Sopenharmony_ci		    page_count(page) - total_mapcount(page) != cache_count)
488c2ecf20Sopenharmony_ci			xas_set_mark(xas, MEMFD_TAG_PINNED);
498c2ecf20Sopenharmony_ci		if (cache_count != 1)
508c2ecf20Sopenharmony_ci			xas_set(xas, page->index + cache_count);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci		latency += cache_count;
538c2ecf20Sopenharmony_ci		if (latency < XA_CHECK_SCHED)
548c2ecf20Sopenharmony_ci			continue;
558c2ecf20Sopenharmony_ci		latency = 0;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci		xas_pause(xas);
588c2ecf20Sopenharmony_ci		xas_unlock_irq(xas);
598c2ecf20Sopenharmony_ci		cond_resched();
608c2ecf20Sopenharmony_ci		xas_lock_irq(xas);
618c2ecf20Sopenharmony_ci	}
628c2ecf20Sopenharmony_ci	xas_unlock_irq(xas);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/*
668c2ecf20Sopenharmony_ci * Setting SEAL_WRITE requires us to verify there's no pending writer. However,
678c2ecf20Sopenharmony_ci * via get_user_pages(), drivers might have some pending I/O without any active
688c2ecf20Sopenharmony_ci * user-space mappings (eg., direct-IO, AIO). Therefore, we look at all pages
698c2ecf20Sopenharmony_ci * and see whether it has an elevated ref-count. If so, we tag them and wait for
708c2ecf20Sopenharmony_ci * them to be dropped.
718c2ecf20Sopenharmony_ci * The caller must guarantee that no new user will acquire writable references
728c2ecf20Sopenharmony_ci * to those pages to avoid races.
738c2ecf20Sopenharmony_ci */
748c2ecf20Sopenharmony_cistatic int memfd_wait_for_pins(struct address_space *mapping)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	XA_STATE(xas, &mapping->i_pages, 0);
778c2ecf20Sopenharmony_ci	struct page *page;
788c2ecf20Sopenharmony_ci	int error, scan;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	memfd_tag_pins(&xas);
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	error = 0;
838c2ecf20Sopenharmony_ci	for (scan = 0; scan <= LAST_SCAN; scan++) {
848c2ecf20Sopenharmony_ci		int latency = 0;
858c2ecf20Sopenharmony_ci		int cache_count;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci		if (!xas_marked(&xas, MEMFD_TAG_PINNED))
888c2ecf20Sopenharmony_ci			break;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci		if (!scan)
918c2ecf20Sopenharmony_ci			lru_add_drain_all();
928c2ecf20Sopenharmony_ci		else if (schedule_timeout_killable((HZ << scan) / 200))
938c2ecf20Sopenharmony_ci			scan = LAST_SCAN;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci		xas_set(&xas, 0);
968c2ecf20Sopenharmony_ci		xas_lock_irq(&xas);
978c2ecf20Sopenharmony_ci		xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) {
988c2ecf20Sopenharmony_ci			bool clear = true;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci			cache_count = 1;
1018c2ecf20Sopenharmony_ci			if (!xa_is_value(page) &&
1028c2ecf20Sopenharmony_ci			    PageTransHuge(page) && !PageHuge(page))
1038c2ecf20Sopenharmony_ci				cache_count = HPAGE_PMD_NR;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci			if (!xa_is_value(page) && cache_count !=
1068c2ecf20Sopenharmony_ci			    page_count(page) - total_mapcount(page)) {
1078c2ecf20Sopenharmony_ci				/*
1088c2ecf20Sopenharmony_ci				 * On the last scan, we clean up all those tags
1098c2ecf20Sopenharmony_ci				 * we inserted; but make a note that we still
1108c2ecf20Sopenharmony_ci				 * found pages pinned.
1118c2ecf20Sopenharmony_ci				 */
1128c2ecf20Sopenharmony_ci				if (scan == LAST_SCAN)
1138c2ecf20Sopenharmony_ci					error = -EBUSY;
1148c2ecf20Sopenharmony_ci				else
1158c2ecf20Sopenharmony_ci					clear = false;
1168c2ecf20Sopenharmony_ci			}
1178c2ecf20Sopenharmony_ci			if (clear)
1188c2ecf20Sopenharmony_ci				xas_clear_mark(&xas, MEMFD_TAG_PINNED);
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci			latency += cache_count;
1218c2ecf20Sopenharmony_ci			if (latency < XA_CHECK_SCHED)
1228c2ecf20Sopenharmony_ci				continue;
1238c2ecf20Sopenharmony_ci			latency = 0;
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci			xas_pause(&xas);
1268c2ecf20Sopenharmony_ci			xas_unlock_irq(&xas);
1278c2ecf20Sopenharmony_ci			cond_resched();
1288c2ecf20Sopenharmony_ci			xas_lock_irq(&xas);
1298c2ecf20Sopenharmony_ci		}
1308c2ecf20Sopenharmony_ci		xas_unlock_irq(&xas);
1318c2ecf20Sopenharmony_ci	}
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	return error;
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic unsigned int *memfd_file_seals_ptr(struct file *file)
1378c2ecf20Sopenharmony_ci{
1388c2ecf20Sopenharmony_ci	if (shmem_file(file))
1398c2ecf20Sopenharmony_ci		return &SHMEM_I(file_inode(file))->seals;
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci#ifdef CONFIG_HUGETLBFS
1428c2ecf20Sopenharmony_ci	if (is_file_hugepages(file))
1438c2ecf20Sopenharmony_ci		return &HUGETLBFS_I(file_inode(file))->seals;
1448c2ecf20Sopenharmony_ci#endif
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	return NULL;
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci#define F_ALL_SEALS (F_SEAL_SEAL | \
1508c2ecf20Sopenharmony_ci		     F_SEAL_SHRINK | \
1518c2ecf20Sopenharmony_ci		     F_SEAL_GROW | \
1528c2ecf20Sopenharmony_ci		     F_SEAL_WRITE | \
1538c2ecf20Sopenharmony_ci		     F_SEAL_FUTURE_WRITE)
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_cistatic int memfd_add_seals(struct file *file, unsigned int seals)
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	struct inode *inode = file_inode(file);
1588c2ecf20Sopenharmony_ci	unsigned int *file_seals;
1598c2ecf20Sopenharmony_ci	int error;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	/*
1628c2ecf20Sopenharmony_ci	 * SEALING
1638c2ecf20Sopenharmony_ci	 * Sealing allows multiple parties to share a tmpfs or hugetlbfs file
1648c2ecf20Sopenharmony_ci	 * but restrict access to a specific subset of file operations. Seals
1658c2ecf20Sopenharmony_ci	 * can only be added, but never removed. This way, mutually untrusted
1668c2ecf20Sopenharmony_ci	 * parties can share common memory regions with a well-defined policy.
1678c2ecf20Sopenharmony_ci	 * A malicious peer can thus never perform unwanted operations on a
1688c2ecf20Sopenharmony_ci	 * shared object.
1698c2ecf20Sopenharmony_ci	 *
1708c2ecf20Sopenharmony_ci	 * Seals are only supported on special tmpfs or hugetlbfs files and
1718c2ecf20Sopenharmony_ci	 * always affect the whole underlying inode. Once a seal is set, it
1728c2ecf20Sopenharmony_ci	 * may prevent some kinds of access to the file. Currently, the
1738c2ecf20Sopenharmony_ci	 * following seals are defined:
1748c2ecf20Sopenharmony_ci	 *   SEAL_SEAL: Prevent further seals from being set on this file
1758c2ecf20Sopenharmony_ci	 *   SEAL_SHRINK: Prevent the file from shrinking
1768c2ecf20Sopenharmony_ci	 *   SEAL_GROW: Prevent the file from growing
1778c2ecf20Sopenharmony_ci	 *   SEAL_WRITE: Prevent write access to the file
1788c2ecf20Sopenharmony_ci	 *
1798c2ecf20Sopenharmony_ci	 * As we don't require any trust relationship between two parties, we
1808c2ecf20Sopenharmony_ci	 * must prevent seals from being removed. Therefore, sealing a file
1818c2ecf20Sopenharmony_ci	 * only adds a given set of seals to the file, it never touches
1828c2ecf20Sopenharmony_ci	 * existing seals. Furthermore, the "setting seals"-operation can be
1838c2ecf20Sopenharmony_ci	 * sealed itself, which basically prevents any further seal from being
1848c2ecf20Sopenharmony_ci	 * added.
1858c2ecf20Sopenharmony_ci	 *
1868c2ecf20Sopenharmony_ci	 * Semantics of sealing are only defined on volatile files. Only
1878c2ecf20Sopenharmony_ci	 * anonymous tmpfs and hugetlbfs files support sealing. More
1888c2ecf20Sopenharmony_ci	 * importantly, seals are never written to disk. Therefore, there's
1898c2ecf20Sopenharmony_ci	 * no plan to support it on other file types.
1908c2ecf20Sopenharmony_ci	 */
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	if (!(file->f_mode & FMODE_WRITE))
1938c2ecf20Sopenharmony_ci		return -EPERM;
1948c2ecf20Sopenharmony_ci	if (seals & ~(unsigned int)F_ALL_SEALS)
1958c2ecf20Sopenharmony_ci		return -EINVAL;
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	inode_lock(inode);
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	file_seals = memfd_file_seals_ptr(file);
2008c2ecf20Sopenharmony_ci	if (!file_seals) {
2018c2ecf20Sopenharmony_ci		error = -EINVAL;
2028c2ecf20Sopenharmony_ci		goto unlock;
2038c2ecf20Sopenharmony_ci	}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	if (*file_seals & F_SEAL_SEAL) {
2068c2ecf20Sopenharmony_ci		error = -EPERM;
2078c2ecf20Sopenharmony_ci		goto unlock;
2088c2ecf20Sopenharmony_ci	}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) {
2118c2ecf20Sopenharmony_ci		error = mapping_deny_writable(file->f_mapping);
2128c2ecf20Sopenharmony_ci		if (error)
2138c2ecf20Sopenharmony_ci			goto unlock;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci		error = memfd_wait_for_pins(file->f_mapping);
2168c2ecf20Sopenharmony_ci		if (error) {
2178c2ecf20Sopenharmony_ci			mapping_allow_writable(file->f_mapping);
2188c2ecf20Sopenharmony_ci			goto unlock;
2198c2ecf20Sopenharmony_ci		}
2208c2ecf20Sopenharmony_ci	}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	*file_seals |= seals;
2238c2ecf20Sopenharmony_ci	error = 0;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ciunlock:
2268c2ecf20Sopenharmony_ci	inode_unlock(inode);
2278c2ecf20Sopenharmony_ci	return error;
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_cistatic int memfd_get_seals(struct file *file)
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	unsigned int *seals = memfd_file_seals_ptr(file);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	return seals ? *seals : -EINVAL;
2358c2ecf20Sopenharmony_ci}
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_cilong memfd_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
2388c2ecf20Sopenharmony_ci{
2398c2ecf20Sopenharmony_ci	long error;
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci	switch (cmd) {
2428c2ecf20Sopenharmony_ci	case F_ADD_SEALS:
2438c2ecf20Sopenharmony_ci		/* disallow upper 32bit */
2448c2ecf20Sopenharmony_ci		if (arg > UINT_MAX)
2458c2ecf20Sopenharmony_ci			return -EINVAL;
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci		error = memfd_add_seals(file, arg);
2488c2ecf20Sopenharmony_ci		break;
2498c2ecf20Sopenharmony_ci	case F_GET_SEALS:
2508c2ecf20Sopenharmony_ci		error = memfd_get_seals(file);
2518c2ecf20Sopenharmony_ci		break;
2528c2ecf20Sopenharmony_ci	default:
2538c2ecf20Sopenharmony_ci		error = -EINVAL;
2548c2ecf20Sopenharmony_ci		break;
2558c2ecf20Sopenharmony_ci	}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci	return error;
2588c2ecf20Sopenharmony_ci}
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci#define MFD_NAME_PREFIX "memfd:"
2618c2ecf20Sopenharmony_ci#define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1)
2628c2ecf20Sopenharmony_ci#define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN)
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB)
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ciSYSCALL_DEFINE2(memfd_create,
2678c2ecf20Sopenharmony_ci		const char __user *, uname,
2688c2ecf20Sopenharmony_ci		unsigned int, flags)
2698c2ecf20Sopenharmony_ci{
2708c2ecf20Sopenharmony_ci	unsigned int *file_seals;
2718c2ecf20Sopenharmony_ci	struct file *file;
2728c2ecf20Sopenharmony_ci	int fd, error;
2738c2ecf20Sopenharmony_ci	char *name;
2748c2ecf20Sopenharmony_ci	long len;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	if (!(flags & MFD_HUGETLB)) {
2778c2ecf20Sopenharmony_ci		if (flags & ~(unsigned int)MFD_ALL_FLAGS)
2788c2ecf20Sopenharmony_ci			return -EINVAL;
2798c2ecf20Sopenharmony_ci	} else {
2808c2ecf20Sopenharmony_ci		/* Allow huge page size encoding in flags. */
2818c2ecf20Sopenharmony_ci		if (flags & ~(unsigned int)(MFD_ALL_FLAGS |
2828c2ecf20Sopenharmony_ci				(MFD_HUGE_MASK << MFD_HUGE_SHIFT)))
2838c2ecf20Sopenharmony_ci			return -EINVAL;
2848c2ecf20Sopenharmony_ci	}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	/* length includes terminating zero */
2878c2ecf20Sopenharmony_ci	len = strnlen_user(uname, MFD_NAME_MAX_LEN + 1);
2888c2ecf20Sopenharmony_ci	if (len <= 0)
2898c2ecf20Sopenharmony_ci		return -EFAULT;
2908c2ecf20Sopenharmony_ci	if (len > MFD_NAME_MAX_LEN + 1)
2918c2ecf20Sopenharmony_ci		return -EINVAL;
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	name = kmalloc(len + MFD_NAME_PREFIX_LEN, GFP_KERNEL);
2948c2ecf20Sopenharmony_ci	if (!name)
2958c2ecf20Sopenharmony_ci		return -ENOMEM;
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	strcpy(name, MFD_NAME_PREFIX);
2988c2ecf20Sopenharmony_ci	if (copy_from_user(&name[MFD_NAME_PREFIX_LEN], uname, len)) {
2998c2ecf20Sopenharmony_ci		error = -EFAULT;
3008c2ecf20Sopenharmony_ci		goto err_name;
3018c2ecf20Sopenharmony_ci	}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	/* terminating-zero may have changed after strnlen_user() returned */
3048c2ecf20Sopenharmony_ci	if (name[len + MFD_NAME_PREFIX_LEN - 1]) {
3058c2ecf20Sopenharmony_ci		error = -EFAULT;
3068c2ecf20Sopenharmony_ci		goto err_name;
3078c2ecf20Sopenharmony_ci	}
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	fd = get_unused_fd_flags((flags & MFD_CLOEXEC) ? O_CLOEXEC : 0);
3108c2ecf20Sopenharmony_ci	if (fd < 0) {
3118c2ecf20Sopenharmony_ci		error = fd;
3128c2ecf20Sopenharmony_ci		goto err_name;
3138c2ecf20Sopenharmony_ci	}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	if (flags & MFD_HUGETLB) {
3168c2ecf20Sopenharmony_ci		struct user_struct *user = NULL;
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci		file = hugetlb_file_setup(name, 0, VM_NORESERVE, &user,
3198c2ecf20Sopenharmony_ci					HUGETLB_ANONHUGE_INODE,
3208c2ecf20Sopenharmony_ci					(flags >> MFD_HUGE_SHIFT) &
3218c2ecf20Sopenharmony_ci					MFD_HUGE_MASK);
3228c2ecf20Sopenharmony_ci	} else
3238c2ecf20Sopenharmony_ci		file = shmem_file_setup(name, 0, VM_NORESERVE);
3248c2ecf20Sopenharmony_ci	if (IS_ERR(file)) {
3258c2ecf20Sopenharmony_ci		error = PTR_ERR(file);
3268c2ecf20Sopenharmony_ci		goto err_fd;
3278c2ecf20Sopenharmony_ci	}
3288c2ecf20Sopenharmony_ci	file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
3298c2ecf20Sopenharmony_ci	file->f_flags |= O_LARGEFILE;
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	if (flags & MFD_ALLOW_SEALING) {
3328c2ecf20Sopenharmony_ci		file_seals = memfd_file_seals_ptr(file);
3338c2ecf20Sopenharmony_ci		if (file_seals)
3348c2ecf20Sopenharmony_ci			*file_seals &= ~F_SEAL_SEAL;
3358c2ecf20Sopenharmony_ci	}
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci	fd_install(fd, file);
3388c2ecf20Sopenharmony_ci	kfree(name);
3398c2ecf20Sopenharmony_ci	return fd;
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_cierr_fd:
3428c2ecf20Sopenharmony_ci	put_unused_fd(fd);
3438c2ecf20Sopenharmony_cierr_name:
3448c2ecf20Sopenharmony_ci	kfree(name);
3458c2ecf20Sopenharmony_ci	return error;
3468c2ecf20Sopenharmony_ci}
347