patch-2.4.14 linux/fs/devfs/base.c
Next file: linux/fs/dquot.c
Previous file: linux/fs/cramfs/uncompress.c
Back to the patch index
Back to the overall index
- Lines: 72
- Date:
Sat Nov 3 10:06:38 2001
- Orig file:
v2.4.13/linux/fs/devfs/base.c
- Orig date:
Thu Oct 11 08:02:26 2001
diff -u --recursive --new-file v2.4.13/linux/fs/devfs/base.c linux/fs/devfs/base.c
@@ -555,6 +555,11 @@
Fixed buffer underrun in <try_modload>.
Moved down_read() from <search_for_entry_in_dir> to <find_entry>
v0.119
+ 20011029 Richard Gooch <rgooch@atnf.csiro.au>
+ Fixed race in <devfsd_ioctl> when setting event mask.
+ 20011103 Richard Gooch <rgooch@atnf.csiro.au>
+ Avoid deadlock in <devfs_follow_link> by using temporary buffer.
+ v0.120
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -587,7 +592,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "0.119 (20011009)"
+#define DEVFS_VERSION "0.120 (20011103)"
#define DEVFS_NAME "devfs"
@@ -3029,13 +3034,25 @@
{
int err;
struct devfs_entry *de;
+ char *copy;
de = get_devfs_entry_from_vfs_inode (dentry->d_inode, TRUE);
if (!de) return -ENODEV;
down_read (&symlink_rwsem);
- err = de->registered ? vfs_follow_link (nd,
- de->u.symlink.linkname) : -ENODEV;
+ if (!de->registered)
+ {
+ up_read (&symlink_rwsem);
+ return -ENODEV;
+ }
+ copy = kmalloc (de->u.symlink.length + 1, GFP_KERNEL);
+ if (copy) memcpy (copy, de->u.symlink.linkname, de->u.symlink.length + 1);
up_read (&symlink_rwsem);
+ if (copy)
+ {
+ err = vfs_follow_link (nd, copy);
+ kfree (copy);
+ }
+ else err = -ENOMEM;
return err;
} /* End Function devfs_follow_link */
@@ -3212,7 +3229,6 @@
{
int ival;
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
- static spinlock_t lock = SPIN_LOCK_UNLOCKED;
switch (cmd)
{
@@ -3226,7 +3242,14 @@
doesn't matter who gets in first, as long as only one gets it */
if (fs_info->devfsd_task == NULL)
{
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+
if ( !spin_trylock (&lock) ) return -EBUSY;
+ if (fs_info->devfsd_task != NULL)
+ { /* We lost the race... */
+ spin_unlock (&lock);
+ return -EBUSY;
+ }
fs_info->devfsd_task = current;
spin_unlock (&lock);
fs_info->devfsd_file = file;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)