patch for 2.1.89 fs/open, fcntl

Bill Hawes (whawes@star.net)
Sat, 07 Mar 1998 15:30:19 -0500


This is a multi-part message in MIME format.
--------------B3771E54EF1754C375679165
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

The attached patch takes care of a few more references to the files->fd[] array.
I've added an inline function fcheck(fd) to file.h to handle the cases where we
just want to test whether the file slot is occupied, but don't need to add a use
count.

Regards,
Bill
--------------B3771E54EF1754C375679165
Content-Type: text/plain; charset=us-ascii; name="fd_files89-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="fd_files89-patch"

--- linux-2.1.89/include/linux/file.h.old Sat Mar 7 11:32:18 1998
+++ linux-2.1.89/include/linux/file.h Sat Mar 7 14:39:01 1998
@@ -1,19 +1,41 @@
+/*
+ * Wrapper functions for accessing the file_struct fd array.
+ */
+
#ifndef __LINUX_FILE_H
#define __LINUX_FILE_H

-extern inline struct file * fget(unsigned long fd)
+extern int __fput(struct file *);
+extern void insert_file_free(struct file *file);
+
+/*
+ * Check whether the specified fd has an open file.
+ */
+extern inline struct file * fcheck(unsigned int fd)
{
struct file * file = NULL;
- if (fd < NR_OPEN) {
+
+ if (fd < NR_OPEN)
file = current->files->fd[fd];
- if (file)
- file->f_count++;
- }
return file;
}

-extern int __fput(struct file *);
-extern void insert_file_free(struct file *file);
+extern inline struct file * fget(unsigned int fd)
+{
+ struct file * file = fcheck(fd);
+
+ if (file)
+ file->f_count++;
+ return file;
+}
+
+/*
+ * Install a file pointer in the fd array.
+ */
+extern inline void fd_install(unsigned int fd, struct file *file)
+{
+ current->files->fd[fd] = file;
+}

/* It does not matter which list it is on. */
extern inline void remove_filp(struct file *file)
@@ -45,14 +67,6 @@
remove_filp(file);
insert_file_free(file);
}
-}
-
-/*
- * Install a file pointer in the files structure.
- */
-extern inline void fd_install(unsigned long fd, struct file *file)
-{
- current->files->fd[fd] = file;
}

#endif
--- linux-2.1.89/fs/open.c.old Sat Mar 7 11:32:16 1998
+++ linux-2.1.89/fs/open.c Sat Mar 7 14:55:48 1998
@@ -681,24 +681,37 @@
}

/*
- * Find an empty file descriptor entry, and mark it busy
+ * Find an empty file descriptor entry, and mark it busy.
*/
int get_unused_fd(void)
{
- int fd;
struct files_struct * files = current->files;
+ int fd, error;

+ error = -EMFILE;
fd = find_first_zero_bit(&files->open_fds, NR_OPEN);
/*
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
- if (fd < current->rlim[RLIMIT_NOFILE].rlim_cur) {
- FD_SET(fd, &files->open_fds);
- FD_CLR(fd, &files->close_on_exec);
- return fd;
+ if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+ goto out;
+
+ /* Check here for fd > files->max_fds to do dynamic expansion */
+
+ FD_SET(fd, &files->open_fds);
+ FD_CLR(fd, &files->close_on_exec);
+#if 1
+ /* Sanity check */
+ if (files->fd[fd] != NULL) {
+ printk("get_unused_fd: slot %d not NULL!\n", fd);
+ files->fd[fd] = NULL;
}
- return -EMFILE;
+#endif
+ error = fd;
+
+out:
+ return error;
}

inline void put_unused_fd(unsigned int fd)
@@ -796,15 +809,15 @@
{
int error;
struct file * filp;
- struct files_struct * files;

lock_kernel();
- files = current->files;
error = -EBADF;
- if (fd < NR_OPEN && (filp = files->fd[fd]) != NULL) {
+ filp = fcheck(fd);
+ if (filp) {
+ struct files_struct * files = current->files;
+ files->fd[fd] = NULL;
put_unused_fd(fd);
FD_CLR(fd, &files->close_on_exec);
- files->fd[fd] = NULL;
error = close_fp(filp, files);
}
unlock_kernel();
--- linux-2.1.89/fs/fcntl.c.old Mon Dec 1 11:14:13 1997
+++ linux-2.1.89/fs/fcntl.c Sat Mar 7 14:35:04 1998
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
+#include <linux/file.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -22,18 +23,32 @@
static inline int dupfd(unsigned int fd, unsigned int arg)
{
struct files_struct * files = current->files;
+ struct file * file;
+ int error;

- if (fd >= NR_OPEN || !files->fd[fd])
- return -EBADF;
+ error = -EINVAL;
if (arg >= NR_OPEN)
- return -EINVAL;
+ goto out;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ error = -EMFILE;
arg = find_next_zero_bit(&files->open_fds, NR_OPEN, arg);
if (arg >= current->rlim[RLIMIT_NOFILE].rlim_cur)
- return -EMFILE;
+ goto out_putf;
FD_SET(arg, &files->open_fds);
FD_CLR(arg, &files->close_on_exec);
- (files->fd[arg] = files->fd[fd])->f_count++;
- return arg;
+ fd_install(arg, file);
+ error = arg;
+out:
+ return error;
+
+out_putf:
+ fput(file);
+ goto out;
}

asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
@@ -41,7 +56,7 @@
int err = -EBADF;

lock_kernel();
- if (oldfd >= NR_OPEN || !current->files->fd[oldfd])
+ if (!fcheck(oldfd))
goto out;
err = newfd;
if (newfd == oldfd)
@@ -51,7 +66,7 @@
goto out; /* following POSIX.1 6.2.1 */

sys_close(newfd);
- err = dupfd(oldfd,newfd);
+ err = dupfd(oldfd, newfd);
out:
unlock_kernel();
return err;
@@ -62,7 +77,7 @@
int ret;

lock_kernel();
- ret = dupfd(fildes,0);
+ ret = dupfd(fildes, 0);
unlock_kernel();
return ret;
}
@@ -101,12 +116,13 @@
long err = -EBADF;

lock_kernel();
- if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+ filp = fget(fd);
+ if (!filp)
goto out;
err = 0;
switch (cmd) {
case F_DUPFD:
- err = dupfd(fd,arg);
+ err = dupfd(fd, arg);
break;
case F_GETFD:
err = FD_ISSET(fd, &current->files->close_on_exec);
@@ -158,6 +174,7 @@
err = -EINVAL;
break;
}
+ fput(filp);
out:
unlock_kernel();
return err;

--------------B3771E54EF1754C375679165--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu