summaryrefslogtreecommitdiffstats
path: root/fs/readdir.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
committer <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
commit19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch)
tree40b1cb534496a7f1ca0f5c314a523c69f1fee464 /fs/readdir.c
parent7206675c40394c78a90e74812bbdbf8cf3cca1be (diff)
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'fs/readdir.c')
-rw-r--r--fs/readdir.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/fs/readdir.c b/fs/readdir.c
index e81415644..aaea5b45f 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -10,6 +10,8 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -55,23 +57,28 @@ static int fillonedir(void * __buf, const char * name, int namlen, off_t offset,
asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count)
{
- int error;
+ int error = -EBADF;
struct file * file;
struct readdir_callback buf;
+ lock_kernel();
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
+ error = -ENOTDIR;
if (!file->f_op || !file->f_op->readdir)
- return -ENOTDIR;
+ goto out;
error = verify_area(VERIFY_WRITE, dirent, sizeof(struct old_linux_dirent));
if (error)
- return error;
+ goto out;
buf.count = 0;
buf.dirent = dirent;
error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);
if (error < 0)
- return error;
- return buf.count;
+ goto out;
+ error = buf.count;
+out:
+ unlock_kernel();
+ return error;
}
/*
@@ -121,25 +128,32 @@ asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count)
struct file * file;
struct linux_dirent * lastdirent;
struct getdents_callback buf;
- int error;
+ int error = -EBADF;
+ lock_kernel();
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
+ error = -ENOTDIR;
if (!file->f_op || !file->f_op->readdir)
- return -ENOTDIR;
+ goto out;
error = verify_area(VERIFY_WRITE, dirent, count);
if (error)
- return error;
+ goto out;
buf.current_dir = (struct linux_dirent *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
if (error < 0)
- return error;
+ goto out;
lastdirent = buf.previous;
- if (!lastdirent)
- return buf.error;
- put_user(file->f_pos, &lastdirent->d_off);
- return count - buf.count;
+ if (!lastdirent) {
+ error = buf.error;
+ } else {
+ put_user(file->f_pos, &lastdirent->d_off);
+ error = count - buf.count;
+ }
+out:
+ unlock_kernel();
+ return error;
}