From f1da2c3860e301527d56a1ef0b56c649ee7c4b1b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 15 Jul 2000 03:32:22 +0000 Subject: Merge with Linux 2.4.0-test5-pre1. This works again on Origin UP. The IP22 cache bugs which are plaguing some machines are still unfixed. --- fs/block_dev.c | 2 ++ fs/coda/dir.c | 2 ++ fs/coda/pioctl.c | 25 +++---------------------- fs/coda/psdev.c | 10 +++++++++- fs/dcache.c | 3 +++ fs/devfs/base.c | 8 +++++++- fs/ext2/file.c | 6 +++++- fs/file_table.c | 5 +---- fs/hpfs/dir.c | 4 ++++ fs/hpfs/file.c | 2 ++ fs/inode.c | 1 + fs/jffs/inode-v23.c | 10 ++++++---- fs/jffs/jffs_fm.c | 8 +++++--- fs/ncpfs/sock.c | 31 +++++++++++++++---------------- fs/nfs/inode.c | 8 ++++++-- fs/nfsd/vfs.c | 8 ++++---- fs/openpromfs/inode.c | 3 +++ fs/pipe.c | 3 --- fs/select.c | 41 +++++++++++++++++++++++++++-------------- fs/smbfs/file.c | 2 ++ fs/udf/file.c | 6 +++++- 21 files changed, 112 insertions(+), 76 deletions(-) (limited to 'fs') 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 #include #include +#define __NO_VERSION__ +#include #include #include @@ -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 #include +#include 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 +#include 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 #include #include #include @@ -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 #include #include +#include #include #include @@ -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 #include #include -#include #include #include @@ -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 , * 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 /* memset */ #include #include +#include #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; } -- cgit v1.2.3