summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/coda/dir.c2
-rw-r--r--fs/coda/pioctl.c25
-rw-r--r--fs/coda/psdev.c10
-rw-r--r--fs/dcache.c3
-rw-r--r--fs/devfs/base.c8
-rw-r--r--fs/ext2/file.c6
-rw-r--r--fs/file_table.c5
-rw-r--r--fs/hpfs/dir.c4
-rw-r--r--fs/hpfs/file.c2
-rw-r--r--fs/inode.c1
-rw-r--r--fs/jffs/inode-v23.c10
-rw-r--r--fs/jffs/jffs_fm.c8
-rw-r--r--fs/ncpfs/sock.c31
-rw-r--r--fs/nfs/inode.c8
-rw-r--r--fs/nfsd/vfs.c8
-rw-r--r--fs/openpromfs/inode.c3
-rw-r--r--fs/pipe.c3
-rw-r--r--fs/select.c41
-rw-r--r--fs/smbfs/file.c2
-rw-r--r--fs/udf/file.c6
21 files changed, 112 insertions, 76 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9a034ca60..02a2b2758 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -635,6 +635,7 @@ int blkdev_put(struct block_device *bdev, int kind)
kdev_t rdev = to_kdev_t(bdev->bd_dev); /* this should become bdev */
down(&bdev->bd_sem);
/* syncing will go here */
+ lock_kernel();
if (kind == BDEV_FILE || kind == BDEV_FS)
fsync_dev(rdev);
if (atomic_dec_and_test(&bdev->bd_openers)) {
@@ -653,6 +654,7 @@ int blkdev_put(struct block_device *bdev, int kind)
if (!atomic_read(&bdev->bd_openers))
bdev->bd_op = NULL; /* we can't rely on driver being */
/* kind to stay around. */
+ unlock_kernel();
up(&bdev->bd_sem);
return ret;
}
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index f5c53fac2..e53933710 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -635,6 +635,7 @@ int coda_release(struct inode *i, struct file *f)
unsigned short cflags = coda_flags_to_cflags(flags);
struct coda_cred *cred;
+ lock_kernel();
ENTRY;
coda_vfs_stat.release++;
@@ -655,6 +656,7 @@ int coda_release(struct inode *i, struct file *f)
CODA_FREE(cred, sizeof(*cred));
CDEBUG(D_FILE, "coda_release: result: %d\n", error);
+ unlock_kernel();
return error;
}
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c
index dd2636895..711beee06 100644
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -16,6 +16,8 @@
#include <linux/locks.h>
#include <asm/segment.h>
#include <linux/string.h>
+#define __NO_VERSION__
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/coda.h>
@@ -26,8 +28,6 @@
/* pioctl ops */
static int coda_ioctl_permission(struct inode *inode, int mask);
-static int coda_ioctl_open(struct inode *i, struct file *f);
-static int coda_ioctl_release(struct inode *i, struct file *f);
static int coda_pioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg);
@@ -39,9 +39,8 @@ struct inode_operations coda_ioctl_inode_operations =
};
struct file_operations coda_ioctl_operations = {
+ owner: THIS_MODULE,
ioctl: coda_pioctl,
- open: coda_ioctl_open,
- release: coda_ioctl_release,
};
/* the coda pioctl inode ops */
@@ -52,24 +51,6 @@ static int coda_ioctl_permission(struct inode *inode, int mask)
return 0;
}
-/* The pioctl file ops*/
-int coda_ioctl_open(struct inode *i, struct file *f)
-{
- ENTRY;
-
- CDEBUG(D_PIOCTL, "File inode number: %ld\n",
- f->f_dentry->d_inode->i_ino);
-
- EXIT;
- return 0;
-}
-
-int coda_ioctl_release(struct inode *i, struct file *f)
-{
- return 0;
-}
-
-
static int coda_pioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long user_data)
{
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 695e4158c..c475b73ac 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -292,6 +292,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
ENTRY;
/* first opener, initialize */
+ lock_kernel();
if (!vcp->vc_inuse++) {
INIT_LIST_HEAD(&vcp->vc_pending);
INIT_LIST_HEAD(&vcp->vc_processing);
@@ -301,6 +302,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
CDEBUG(D_PSDEV, "inuse: %d\n", vcp->vc_inuse);
EXIT;
+ unlock_kernel();
return 0;
}
@@ -312,13 +314,18 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
struct list_head *lh, *next;
ENTRY;
+ lock_kernel();
if ( !vcp->vc_inuse ) {
+ unlock_kernel();
printk("psdev_release: Not open.\n");
return -1;
}
CDEBUG(D_PSDEV, "psdev_release: inuse %d\n", vcp->vc_inuse);
- if (--vcp->vc_inuse) return 0;
+ if (--vcp->vc_inuse) {
+ unlock_kernel();
+ return 0;
+ }
/* Wakeup clients so they can return. */
CDEBUG(D_PSDEV, "wake up pending clients\n");
@@ -347,6 +354,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
CDEBUG(D_PSDEV, "Done.\n");
EXIT;
+ unlock_kernel();
return 0;
}
diff --git a/fs/dcache.c b/fs/dcache.c
index 0f9c59c6c..8c27b5f94 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -933,6 +933,9 @@ void d_move(struct dentry * dentry, struct dentry * target)
/**
* d_path - return the path of a dentry
* @dentry: dentry to report
+ * @vfsmnt: vfsmnt to which the dentry belongs
+ * @root: root dentry
+ * @rootmnt: vfsmnt to which the root dentry belongs
* @buffer: buffer to return value in
* @buflen: buffer length
*
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 494cb270a..38a773d72 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -3311,7 +3311,12 @@ static int devfsd_close (struct inode *inode, struct file *file)
{
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
- if (fs_info->devfsd_file != file) return 0;
+ lock_kernel();
+ if (fs_info->devfsd_file != file)
+ {
+ unlock_kernel();
+ return 0;
+ }
fs_info->devfsd_event_mask = 0;
fs_info->devfsd_file = NULL;
if (fs_info->devfsd_buffer)
@@ -3322,6 +3327,7 @@ static int devfsd_close (struct inode *inode, struct file *file)
fs_info->devfsd_buffer = NULL;
fs_info->devfsd_task = NULL;
wake_up (&fs_info->revalidate_wait_queue);
+ unlock_kernel();
return 0;
} /* End Function devfsd_close */
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index d2c137e2c..f591203c4 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
static loff_t ext2_file_lseek(struct file *, loff_t, int);
static int ext2_open_file (struct inode *, struct file *);
@@ -73,8 +74,11 @@ static loff_t ext2_file_lseek(
*/
static int ext2_release_file (struct inode * inode, struct file * filp)
{
- if (filp->f_mode & FMODE_WRITE)
+ if (filp->f_mode & FMODE_WRITE) {
+ lock_kernel();
ext2_discard_prealloc (inode);
+ unlock_kernel();
+ }
return 0;
}
diff --git a/fs/file_table.c b/fs/file_table.c
index a64bef65c..2eaceae07 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -124,11 +124,8 @@ static void __fput(struct file *filp)
struct vfsmount * mnt = filp->f_vfsmnt;
struct inode * inode = dentry->d_inode;
- if (filp->f_op && filp->f_op->release) {
- lock_kernel();
+ if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode, filp);
- unlock_kernel();
- }
fops_put(filp->f_op);
filp->f_dentry = NULL;
filp->f_vfsmnt = NULL;
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c
index 51d519d7f..15db6e936 100644
--- a/fs/hpfs/dir.c
+++ b/fs/hpfs/dir.c
@@ -7,11 +7,15 @@
*/
#include "hpfs_fn.h"
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
int hpfs_dir_release(struct inode *inode, struct file *filp)
{
+ lock_kernel();
hpfs_del_pos(inode, &filp->f_pos);
/*hpfs_write_if_changed(inode);*/
+ unlock_kernel();
return 0;
}
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index f284e3d42..fb5f566e7 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -24,7 +24,9 @@ int hpfs_open(struct inode *i, struct file *f)
int hpfs_file_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
hpfs_write_if_changed(inode);
+ unlock_kernel();
return 0;
}
diff --git a/fs/inode.c b/fs/inode.c
index 28fbd0098..62acffd58 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -261,6 +261,7 @@ static void sync_all_inodes(void)
/**
* write_inode_now - write an inode to disk
* @inode: inode to write to disk
+ * @sync: whether the write should be synchronous or not
*
* This function commits an inode to disk immediately if it is
* dirty. This is primarily needed by knfsd.
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index e088d7fba..1447554ed 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -8,7 +8,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: inode-v23.c,v 1.16 2000/07/06 14:38:10 dwmw2 Exp $
+ * $Id: inode-v23.c,v 1.17 2000/07/06 20:35:19 prumpf Exp $
*
*
* Ported to Linux 2.3.x and MTD:
@@ -1453,7 +1453,6 @@ static struct inode_operations jffs_file_inode_operations =
static struct file_operations jffs_dir_operations =
{
- read: generic_read_dir,
readdir: jffs_readdir,
};
@@ -1533,16 +1532,19 @@ jffs_delete_inode(struct inode *inode)
inode->i_size = 0;
- unlock_kernel();
clear_inode(inode);
+ unlock_kernel();
}
void
jffs_write_super(struct super_block *sb)
{
#ifdef USE_GC
- jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);
+ struct jffs_control *c = (struct jffs_control *)sb->u.generic_sbp;
+
+ if(!c->fmc->no_call_gc)
+ jffs_garbage_collect(c);
#endif
}
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
index b2644ba5e..4484af07d 100644
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -10,14 +10,13 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: jffs_fm.c,v 1.6 2000/06/30 14:13:03 dwmw2 Exp $
+ * $Id: jffs_fm.c,v 1.8 2000/07/13 13:15:33 scote1 Exp $
*
* Ported to Linux 2.3.x and MTD:
* Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
*
*/
#define __NO_VERSION__
-#include <linux/config.h>
#include <linux/malloc.h>
#include <linux/blkdev.h>
#include <linux/jffs.h>
@@ -68,7 +67,7 @@ jffs_build_begin(struct jffs_control *c, kdev_t dev)
fmc->used_size = 0;
fmc->dirty_size = 0;
- fmc->sector_size = 65536;
+ fmc->sector_size = mtd->erasesize;
fmc->max_chunk_size = fmc->sector_size >> 1;
fmc->min_free_size = (fmc->sector_size << 1) - fmc->max_chunk_size;
fmc->mtd = mtd;
@@ -614,13 +613,16 @@ jffs_flash_erasable_size(struct mtd_info *mtd, __u32 offset, __u32 size)
ssize = mtd->erasesize;
if (offset % ssize) {
+ printk(KERN_WARNING "jffs_flash_erasable_size() given non-aligned offset %lx (erasesize %lx)\n", offset, ssize);
/* The offset is not sector size aligned. */
return -1;
}
else if (offset > mtd->size) {
+ printk(KERN_WARNING "jffs_flash_erasable_size given offset off the end of device (%lx > %lx)\n", offset, mtd->size);
return -2;
}
else if (offset + size > mtd->size) {
+ printk(KERN_WARNING "jffs_flash_erasable_size() given length which runs off the end of device (ofs %lx + len %lx = %lx, > %lx)\n", offset,size, offset+size, mtd->size);
return -3;
}
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index c5923a78e..171f0cb51 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -87,7 +87,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
int result;
char *start = server->packet;
poll_table wait_table;
- struct poll_table_entry entry;
int init_timeout, max_timeout;
int timeout;
int retrans;
@@ -136,8 +135,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
break;
}
re_select:
- wait_table.nr = 0;
- wait_table.entry = &entry;
+ poll_initwait(&wait_table);
/* mb() is not necessary because ->poll() will serialize
instructions adding the wait_table waitqueues in the
waitqueue-head before going to calculate the mask-retval. */
@@ -154,13 +152,16 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
timeout = max_timeout;
}
timed_out = !schedule_timeout(timeout);
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ poll_freewait(&wait_table);
current->state = TASK_RUNNING;
if (signal_pending(current)) {
result = -ERESTARTSYS;
break;
}
+ if(wait_table.error) {
+ result = wait_table.error;
+ break;
+ }
if (timed_out) {
if (n < retrans)
continue;
@@ -179,9 +180,8 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
major_timeout_seen = 1;
continue;
}
- } else if (wait_table.nr) {
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ } else {
+ poll_freewait(&wait_table);
}
current->state = TASK_RUNNING;
@@ -262,7 +262,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
poll_table wait_table;
- struct poll_table_entry entry;
struct file *file;
struct socket *sock;
int init_timeout;
@@ -281,16 +280,14 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
init_timeout = 0x7FFF0000;
while (len) {
- wait_table.nr = 0;
- wait_table.entry = &entry;
+ poll_initwait(&wait_table);
/* mb() is not necessary because ->poll() will serialize
instructions adding the wait_table waitqueues in the
waitqueue-head before going to calculate the mask-retval. */
__set_current_state(TASK_INTERRUPTIBLE);
if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {
init_timeout = schedule_timeout(init_timeout);
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ poll_freewait(&wait_table);
current->state = TASK_RUNNING;
if (signal_pending(current)) {
return -ERESTARTSYS;
@@ -298,9 +295,11 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
if (!init_timeout) {
return -EIO;
}
- } else if (wait_table.nr) {
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ if(wait_table.error) {
+ return wait_table.error;
+ }
+ } else {
+ poll_freewait(&wait_table);
}
current->state = TASK_RUNNING;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 4ef5569fc..993dcc1a4 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -897,11 +897,15 @@ int nfs_open(struct inode *inode, struct file *filp)
int nfs_release(struct inode *inode, struct file *filp)
{
- struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth;
- struct rpc_cred *cred = nfs_file_cred(filp);
+ struct rpc_auth *auth;
+ struct rpc_cred *cred;
+ lock_kernel();
+ auth = NFS_CLIENT(inode)->cl_auth;
+ cred = nfs_file_cred(filp);
if (cred)
rpcauth_releasecred(auth, cred);
+ unlock_kernel();
return 0;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7a144d707..2cdec3ec8 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -317,7 +317,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap)
if (err)
goto out_nfserr;
if (EX_ISSYNC(fhp->fh_export))
- write_inode_now(inode, 0);
+ write_inode_now(inode, 1);
err = 0;
out:
return err;
@@ -894,7 +894,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (EX_ISSYNC(fhp->fh_export)) {
nfsd_sync_dir(dentry);
- write_inode_now(dchild->d_inode, 0);
+ write_inode_now(dchild->d_inode, 1);
}
@@ -1140,7 +1140,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
| S_IFLNK;
err = notify_change(dnew, iap);
if (!err && EX_ISSYNC(fhp->fh_export))
- write_inode_now(dentry->d_inode, 0);
+ write_inode_now(dentry->d_inode, 1);
}
}
} else
@@ -1200,7 +1200,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
if (!err) {
if (EX_ISSYNC(ffhp->fh_export)) {
nfsd_sync_dir(ddir);
- write_inode_now(dest, 0);
+ write_inode_now(dest, 1);
}
} else {
if (err == -EXDEV && rqstp->rq_vers == 2)
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 3b875a445..430f7b412 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -13,6 +13,7 @@
#include <linux/locks.h>
#include <linux/init.h>
#include <linux/malloc.h>
+#include <linux/smp_lock.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -507,6 +508,7 @@ int property_release (struct inode *inode, struct file *filp)
if (!op)
return 0;
+ lock_kernel();
node = nodes[(u16)((long)inode->u.generic_ip)].node;
if ((u16)((long)inode->u.generic_ip) == aliases) {
if ((op->flag & OPP_DIRTY) && (op->flag & OPP_STRING)) {
@@ -548,6 +550,7 @@ int property_release (struct inode *inode, struct file *filp)
op->name);
}
}
+ unlock_kernel();
kfree (filp->private_data);
return 0;
}
diff --git a/fs/pipe.c b/fs/pipe.c
index 12c160a1a..ef51478a1 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -8,7 +8,6 @@
#include <linux/file.h>
#include <linux/poll.h>
#include <linux/malloc.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -366,14 +365,12 @@ pipe_write_open(struct inode *inode, struct file *filp)
static int
pipe_rdwr_open(struct inode *inode, struct file *filp)
{
- lock_kernel();
down(PIPE_SEM(*inode));
if (filp->f_mode & FMODE_READ)
PIPE_READERS(*inode)++;
if (filp->f_mode & FMODE_WRITE)
PIPE_WRITERS(*inode)++;
up(PIPE_SEM(*inode));
- unlock_kernel();
return 0;
}
diff --git a/fs/select.c b/fs/select.c
index a9fd61953..be09afdd7 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -31,14 +31,15 @@
* understand what I'm doing here, then you understand how the linux
* sleep/wakeup mechanism works.
*
- * Two very simple procedures, poll_wait() and free_wait() make all the
+ * Two very simple procedures, poll_wait() and poll_freewait() make all the
* work. poll_wait() is an inline-function defined in <linux/poll.h>,
* as all select/poll functions have to call it to add an entry to the
* poll table.
*/
-static void free_wait(struct poll_table_page * p)
+void poll_freewait(poll_table* pt)
{
+ struct poll_table_page * p = pt->table;
while (p) {
struct poll_table_entry * entry;
struct poll_table_page *old;
@@ -66,6 +67,7 @@ void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table
new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL);
if (!new_table) {
p->error = -ENOMEM;
+ __set_current_state(TASK_RUNNING);
return;
}
new_table->nr = 0;
@@ -160,9 +162,10 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
return retval;
n = retval;
- table.error = 0;
- table.table = NULL;
+ poll_initwait(&table);
wait = &table;
+ if (!__timeout)
+ wait = NULL;
retval = 0;
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -201,11 +204,15 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
wait = NULL;
if (retval || !__timeout || signal_pending(current))
break;
+ if(table.error) {
+ retval = table.error;
+ break;
+ }
__timeout = schedule_timeout(__timeout);
}
current->state = TASK_RUNNING;
- free_wait(table.table);
+ poll_freewait(&table);
/*
* Up-to-date the caller timeout.
@@ -354,18 +361,22 @@ static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft,
struct pollfd *fds[], poll_table *wait, long timeout)
{
int count = 0;
+ poll_table* pt = wait;
for (;;) {
unsigned int i;
set_current_state(TASK_INTERRUPTIBLE);
for (i=0; i < nchunks; i++)
- do_pollfd(POLLFD_PER_PAGE, fds[i], &wait, &count);
+ do_pollfd(POLLFD_PER_PAGE, fds[i], &pt, &count);
if (nleft)
- do_pollfd(nleft, fds[nchunks], &wait, &count);
- wait = NULL;
+ do_pollfd(nleft, fds[nchunks], &pt, &count);
+ pt = NULL;
if (count || !timeout || signal_pending(current))
break;
+ if(wait->error) {
+ return wait->error;
+ }
timeout = schedule_timeout(timeout);
}
current->state = TASK_RUNNING;
@@ -376,7 +387,7 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
{
int i, j, fdcount, err;
struct pollfd **fds;
- poll_table table;
+ poll_table table, *wait;
int nchunks, nleft;
/* Do a sanity check on nfds ... */
@@ -391,10 +402,12 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
timeout = MAX_SCHEDULE_TIMEOUT;
}
- table.error = 0;
- table.table = NULL;
- err = -ENOMEM;
+ poll_initwait(&table);
+ wait = &table;
+ if (!timeout)
+ wait = NULL;
+ err = -ENOMEM;
fds = NULL;
if (nfds != 0) {
fds = (struct pollfd **)kmalloc(
@@ -429,7 +442,7 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
goto out_fds1;
}
- fdcount = do_poll(nfds, nchunks, nleft, fds, &table, timeout);
+ fdcount = do_poll(nfds, nchunks, nleft, fds, wait, timeout);
/* OK, now copy the revents fields back to user space. */
for(i=0; i < nchunks; i++)
@@ -452,6 +465,6 @@ out_fds:
if (nfds != 0)
kfree(fds);
out:
- free_wait(table.table);
+ poll_freewait(&table);
return err;
}
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index 2c3b96638..247bae08f 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -343,8 +343,10 @@ smb_file_open(struct inode *inode, struct file * file)
static int
smb_file_release(struct inode *inode, struct file * file)
{
+ lock_kernel();
if (!--inode->u.smbfs_i.openers)
smb_close(inode);
+ unlock_kernel();
return 0;
}
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 94597406d..662647088 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -38,6 +38,7 @@
#include <linux/string.h> /* memset */
#include <linux/errno.h>
#include <linux/locks.h>
+#include <linux/smp_lock.h>
#include "udf_i.h"
#include "udf_sb.h"
@@ -296,8 +297,11 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
*/
static int udf_release_file(struct inode * inode, struct file * filp)
{
- if (filp->f_mode & FMODE_WRITE)
+ if (filp->f_mode & FMODE_WRITE) {
+ lock_kernel();
udf_discard_prealloc(inode);
+ unlock_kernel();
+ }
return 0;
}