⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
字号:
/* *  linux/fs/open.c * *  Copyright (C) 1998-1999, Stephen Tweedie and Bill Hawes * *  Manage the dynamic fd arrays in the process files_struct. */#include <linux/fs.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <asm/bitops.h>/* * Allocate an fd array, using kmalloc or vmalloc. * Note: the array isn't cleared at allocation time. */struct file ** alloc_fd_array(int num){	struct file **new_fds;	int size = num * sizeof(struct file *);	if (size <= PAGE_SIZE)		new_fds = (struct file **) kmalloc(size, GFP_KERNEL);	else 		new_fds = (struct file **) vmalloc(size);	return new_fds;}void free_fd_array(struct file **array, int num){	int size = num * sizeof(struct file *);	if (!array) {		printk (KERN_ERR __FUNCTION__ "array = 0 (num = %d)\n", num);		return;	}	if (num <= NR_OPEN_DEFAULT) /* Don't free the embedded fd array! */		return;	else if (size <= PAGE_SIZE)		kfree(array);	else		vfree(array);}/* * Expand the fd array in the files_struct.  Called with the files * spinlock held for write. */int expand_fd_array(struct files_struct *files, int nr){	struct file **new_fds;	int error, nfds;		error = -EMFILE;	if (files->max_fds >= NR_OPEN || nr >= NR_OPEN)		goto out;	nfds = files->max_fds;	write_unlock(&files->file_lock);	/* 	 * Expand to the max in easy steps, and keep expanding it until	 * we have enough for the requested fd array size. 	 */	do {#if NR_OPEN_DEFAULT < 256		if (nfds < 256)			nfds = 256;		else #endif		if (nfds < (PAGE_SIZE / sizeof(struct file *)))			nfds = PAGE_SIZE / sizeof(struct file *);		else {			nfds = nfds * 2;			if (nfds > NR_OPEN)				nfds = NR_OPEN;		}	} while (nfds <= nr);	error = -ENOMEM;	new_fds = alloc_fd_array(nfds);	write_lock(&files->file_lock);	if (!new_fds)		goto out;	/* Copy the existing array and install the new pointer */	if (nfds > files->max_fds) {		struct file **old_fds;		int i;				old_fds = xchg(&files->fd, new_fds);		i = xchg(&files->max_fds, nfds);		/* Don't copy/clear the array if we are creating a new		   fd array for fork() */		if (i) {			memcpy(new_fds, old_fds, i * sizeof(struct file *));			/* clear the remainder of the array */			memset(&new_fds[i], 0,			       (nfds-i) * sizeof(struct file *)); 			write_unlock(&files->file_lock);			free_fd_array(old_fds, i);			write_lock(&files->file_lock);		}	} else {		/* Somebody expanded the array while we slept ... */		write_unlock(&files->file_lock);		free_fd_array(new_fds, nfds);		write_lock(&files->file_lock);	}	error = 0;out:	return error;}/* * Allocate an fdset array, using kmalloc or vmalloc. * Note: the array isn't cleared at allocation time. */fd_set * alloc_fdset(int num){	fd_set *new_fdset;	int size = num / 8;	if (size <= PAGE_SIZE)		new_fdset = (fd_set *) kmalloc(size, GFP_KERNEL);	else		new_fdset = (fd_set *) vmalloc(size);	return new_fdset;}void free_fdset(fd_set *array, int num){	int size = num / 8;	if (!array) {		printk (KERN_ERR __FUNCTION__ "array = 0 (num = %d)\n", num);		return;	}		if (num <= __FD_SETSIZE) /* Don't free an embedded fdset */		return;	else if (size <= PAGE_SIZE)		kfree(array);	else		vfree(array);}/* * Expand the fdset in the files_struct.  Called with the files spinlock * held for write. */int expand_fdset(struct files_struct *files, int nr){	fd_set *new_openset = 0, *new_execset = 0;	int error, nfds = 0;	error = -EMFILE;	if (files->max_fdset >= NR_OPEN || nr >= NR_OPEN)		goto out;	nfds = files->max_fdset;	write_unlock(&files->file_lock);	/* Expand to the max in easy steps */	do {		if (nfds < (PAGE_SIZE * 8))			nfds = PAGE_SIZE * 8;		else {			nfds = nfds * 2;			if (nfds > NR_OPEN)				nfds = NR_OPEN;		}	} while (nfds <= nr);	error = -ENOMEM;	new_openset = alloc_fdset(nfds);	new_execset = alloc_fdset(nfds);	write_lock(&files->file_lock);	if (!new_openset || !new_execset)		goto out;	error = 0;		/* Copy the existing tables and install the new pointers */	if (nfds > files->max_fdset) {		int i = files->max_fdset / (sizeof(unsigned long) * 8);		int count = (nfds - files->max_fdset) / 8;				/* 		 * Don't copy the entire array if the current fdset is		 * not yet initialised.  		 */		if (i) {			memcpy (new_openset, files->open_fds, files->max_fdset/8);			memcpy (new_execset, files->close_on_exec, files->max_fdset/8);			memset (&new_openset->fds_bits[i], 0, count);			memset (&new_execset->fds_bits[i], 0, count);		}				nfds = xchg(&files->max_fdset, nfds);		new_openset = xchg(&files->open_fds, new_openset);		new_execset = xchg(&files->close_on_exec, new_execset);		write_unlock(&files->file_lock);		free_fdset (new_openset, nfds);		free_fdset (new_execset, nfds);		write_lock(&files->file_lock);		return 0;	} 	/* Somebody expanded the array while we slept ... */out:	write_unlock(&files->file_lock);	if (new_openset)		free_fdset(new_openset, nfds);	if (new_execset)		free_fdset(new_execset, nfds);	write_lock(&files->file_lock);	return error;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -