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

Commit badf1662 authored by Dipankar Sarma's avatar Dipankar Sarma Committed by Linus Torvalds
Browse files

[PATCH] files: break up files struct



In order for the RCU to work, the file table array, sets and their sizes must
be updated atomically.  Instead of ensuring this through too many memory
barriers, we put the arrays and their sizes in a separate structure.  This
patch takes the first step of putting the file table elements in a separate
structure fdtable that is embedded withing files_struct.  It also changes all
the users to refer to the file table using files_fdtable() macro.  Subsequent
applciation of RCU becomes easier after this.

Signed-off-by: default avatarDipankar Sarma <dipankar@in.ibm.com>
Signed-Off-By: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c0dfb290
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -974,6 +974,7 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
	size_t size;
	long timeout;
	int ret = -EINVAL;
	struct fdtable *fdt;

	timeout = MAX_SCHEDULE_TIMEOUT;
	if (tvp) {
@@ -995,7 +996,8 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
		}
	}

	if (n < 0 || n > current->files->max_fdset)
	fdt = files_fdtable(current->files);
	if (n < 0 || n > fdt->max_fdset)
		goto out_nofds;

	/*
+5 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/bitops.h>
#include <linux/rcupdate.h>

#include <asm/errno.h>
#include <asm/intrinsics.h>
@@ -2217,15 +2218,17 @@ static void
pfm_free_fd(int fd, struct file *file)
{
	struct files_struct *files = current->files;
	struct fdtable *fdt = files_fdtable(files);

	/* 
	 * there ie no fd_uninstall(), so we do it here
	 */
	spin_lock(&files->file_lock);
        files->fd[fd] = NULL;
	rcu_assign_pointer(fdt->fd[fd], NULL);
	spin_unlock(&files->file_lock);

	if (file) put_filp(file);
	if (file)
		put_filp(file);
	put_unused_fd(fd);
}

+5 −3
Original line number Diff line number Diff line
@@ -293,11 +293,13 @@ static struct module_info {
static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg)
{
	struct inode *ino;
	struct fdtable *fdt;
	/* I wonder which of these tests are superfluous... --patrik */
	spin_lock(&current->files->file_lock);
	if (! current->files->fd[fd] ||
	    ! current->files->fd[fd]->f_dentry ||
	    ! (ino = current->files->fd[fd]->f_dentry->d_inode) ||
	fdt = files_fdtable(current->files);
	if (! fdt->fd[fd] ||
	    ! fdt->fd[fd]->f_dentry ||
	    ! (ino = fdt->fd[fd]->f_dentry->d_inode) ||
	    ! S_ISSOCK(ino->i_mode)) {
		spin_unlock(&current->files->file_lock);
		return TBADF;
+3 −1
Original line number Diff line number Diff line
@@ -2454,6 +2454,7 @@ static void __do_SAK(void *arg)
	int		i;
	struct file	*filp;
	struct tty_ldisc *disc;
	struct fdtable *fdt;
	
	if (!tty)
		return;
@@ -2480,7 +2481,8 @@ static void __do_SAK(void *arg)
		task_lock(p);
		if (p->files) {
			spin_lock(&p->files->file_lock);
			for (i=0; i < p->files->max_fds; i++) {
			fdt = files_fdtable(p->files);
			for (i=0; i < fdt->max_fds; i++) {
				filp = fcheck_files(p->files, i);
				if (!filp)
					continue;
+5 −3
Original line number Diff line number Diff line
@@ -798,6 +798,7 @@ static inline int de_thread(struct task_struct *tsk)
static inline void flush_old_files(struct files_struct * files)
{
	long j = -1;
	struct fdtable *fdt;

	spin_lock(&files->file_lock);
	for (;;) {
@@ -805,12 +806,13 @@ static inline void flush_old_files(struct files_struct * files)

		j++;
		i = j * __NFDBITS;
		if (i >= files->max_fds || i >= files->max_fdset)
		fdt = files_fdtable(files);
		if (i >= fdt->max_fds || i >= fdt->max_fdset)
			break;
		set = files->close_on_exec->fds_bits[j];
		set = fdt->close_on_exec->fds_bits[j];
		if (!set)
			continue;
		files->close_on_exec->fds_bits[j] = 0;
		fdt->close_on_exec->fds_bits[j] = 0;
		spin_unlock(&files->file_lock);
		for ( ; set ; i++,set >>= 1) {
			if (set & 1) {
Loading