Commit 94470e8c authored by Richard Gooch's avatar Richard Gooch

Merge atnf.csiro.au:/workaholix1/kernel/v2.5/linus

into atnf.csiro.au:/workaholix1/kernel/v2.5/rgooch-2.5
parents b1b782f7 eb74db55
...@@ -1965,3 +1965,13 @@ Changes for patch v217 ...@@ -1965,3 +1965,13 @@ Changes for patch v217
- Updated README from master HTML file - Updated README from master HTML file
- Fixed module unload race in <devfs_open> - Fixed module unload race in <devfs_open>
===============================================================================
Changes for patch v218
- Removed DEVFS_FL_AUTO_OWNER flag
- Switched lingering structure field initialiser to ISO C
- Added locking when setting/clearing flags
- Documentation fix in fs/devfs/util.c
...@@ -1367,8 +1367,7 @@ static int video1394_init(struct ti_ohci *ohci) ...@@ -1367,8 +1367,7 @@ static int video1394_init(struct ti_ohci *ohci)
sprintf(name, "%d", video->id); sprintf(name, "%d", video->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + video->id; minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + video->id;
video->devfs = devfs_register(devfs_handle, name, video->devfs = devfs_register(devfs_handle, name, DEVFS_FL_DEFAULT,
DEVFS_FL_AUTO_OWNER,
IEEE1394_MAJOR, minor, IEEE1394_MAJOR, minor,
S_IFCHR | S_IRUSR | S_IWUSR, S_IFCHR | S_IRUSR | S_IWUSR,
&video1394_fops, NULL); &video1394_fops, NULL);
......
...@@ -648,6 +648,11 @@ ...@@ -648,6 +648,11 @@
20020820 Richard Gooch <rgooch@atnf.csiro.au> 20020820 Richard Gooch <rgooch@atnf.csiro.au>
Fixed module unload race in <devfs_open>. Fixed module unload race in <devfs_open>.
v1.21 v1.21
20021013 Richard Gooch <rgooch@atnf.csiro.au>
Removed DEVFS_ FL_AUTO_OWNER.
Switched lingering structure field initialiser to ISO C.
Added locking when updating FCB flags.
v1.22
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -680,7 +685,7 @@ ...@@ -680,7 +685,7 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#define DEVFS_VERSION "1.21 (20020820)" #define DEVFS_VERSION "1.22 (20021013)"
#define DEVFS_NAME "devfs" #define DEVFS_NAME "devfs"
...@@ -778,7 +783,7 @@ struct fcb_type /* File, char, block type */ ...@@ -778,7 +783,7 @@ struct fcb_type /* File, char, block type */
struct device_type device; struct device_type device;
} }
u; u;
unsigned char auto_owner:1; spinlock_t lock; /* Lock for changes */
unsigned char aopen_notify:1; unsigned char aopen_notify:1;
unsigned char removable:1; /* Belongs in device_type, but save space */ unsigned char removable:1; /* Belongs in device_type, but save space */
unsigned char open:1; /* Not entirely correct */ unsigned char open:1; /* Not entirely correct */
...@@ -860,7 +865,7 @@ struct fs_info /* This structure is for the mounted devfs */ ...@@ -860,7 +865,7 @@ struct fs_info /* This structure is for the mounted devfs */
wait_queue_head_t revalidate_wait_queue; /* Wake when devfsd sleeps */ wait_queue_head_t revalidate_wait_queue; /* Wake when devfsd sleeps */
}; };
static struct fs_info fs_info = {devfsd_buffer_lock: SPIN_LOCK_UNLOCKED}; static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED};
static kmem_cache_t *devfsd_buf_cache; static kmem_cache_t *devfsd_buf_cache;
#ifdef CONFIG_DEVFS_DEBUG #ifdef CONFIG_DEVFS_DEBUG
static unsigned int devfs_debug_init __initdata = DEBUG_NONE; static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
...@@ -1011,6 +1016,8 @@ static struct devfs_entry *_devfs_alloc_entry (const char *name, ...@@ -1011,6 +1016,8 @@ static struct devfs_entry *_devfs_alloc_entry (const char *name,
memset (new, 0, sizeof *new + namelen); /* Will set '\0' on name */ memset (new, 0, sizeof *new + namelen); /* Will set '\0' on name */
new->mode = mode; new->mode = mode;
if ( S_ISDIR (mode) ) rwlock_init (&new->u.dir.lock); if ( S_ISDIR (mode) ) rwlock_init (&new->u.dir.lock);
else if ( S_ISREG (mode) || S_ISCHR (mode) || S_ISBLK (mode) )
spin_lock_init (&new->u.fcb.lock);
atomic_set (&new->refcount, 1); atomic_set (&new->refcount, 1);
spin_lock (&counter_lock); spin_lock (&counter_lock);
new->inode.ino = inode_counter++; new->inode.ino = inode_counter++;
...@@ -1480,6 +1487,7 @@ static int wait_for_devfsd_finished (struct fs_info *fs_info) ...@@ -1480,6 +1487,7 @@ static int wait_for_devfsd_finished (struct fs_info *fs_info)
* @uid: The user ID. * @uid: The user ID.
* @gid: The group ID. * @gid: The group ID.
* @fs_info: The filesystem info. * @fs_info: The filesystem info.
* @atomic: If TRUE, an atomic allocation is required.
* *
* Returns %TRUE if an event was queued and devfsd woken up, else %FALSE. * Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
*/ */
...@@ -1626,7 +1634,6 @@ devfs_handle_t devfs_register (devfs_handle_t dir, const char *name, ...@@ -1626,7 +1634,6 @@ devfs_handle_t devfs_register (devfs_handle_t dir, const char *name,
de->inode.gid = 0; de->inode.gid = 0;
} }
de->u.fcb.ops = ops; de->u.fcb.ops = ops;
de->u.fcb.auto_owner = (flags & DEVFS_FL_AUTO_OWNER) ? TRUE : FALSE;
de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE : FALSE; de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE : FALSE;
de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE; de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
if (flags & DEVFS_FL_REMOVABLE) de->u.fcb.removable = TRUE; if (flags & DEVFS_FL_REMOVABLE) de->u.fcb.removable = TRUE;
...@@ -1893,7 +1900,7 @@ void devfs_find_and_unregister (devfs_handle_t dir, const char *name, ...@@ -1893,7 +1900,7 @@ void devfs_find_and_unregister (devfs_handle_t dir, const char *name,
type, traverse_symlinks); type, traverse_symlinks);
devfs_unregister (de); devfs_unregister (de);
devfs_put (de); devfs_put (de);
} } /* End Function devfs_find_and_unregister */
/** /**
...@@ -1913,7 +1920,6 @@ int devfs_get_flags (devfs_handle_t de, unsigned int *flags) ...@@ -1913,7 +1920,6 @@ int devfs_get_flags (devfs_handle_t de, unsigned int *flags)
if (de->hide) fl |= DEVFS_FL_HIDE; if (de->hide) fl |= DEVFS_FL_HIDE;
if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
{ {
if (de->u.fcb.auto_owner) fl |= DEVFS_FL_AUTO_OWNER;
if (de->u.fcb.aopen_notify) fl |= DEVFS_FL_AOPEN_NOTIFY; if (de->u.fcb.aopen_notify) fl |= DEVFS_FL_AOPEN_NOTIFY;
if (de->u.fcb.removable) fl |= DEVFS_FL_REMOVABLE; if (de->u.fcb.removable) fl |= DEVFS_FL_REMOVABLE;
} }
...@@ -1938,8 +1944,9 @@ int devfs_set_flags (devfs_handle_t de, unsigned int flags) ...@@ -1938,8 +1944,9 @@ int devfs_set_flags (devfs_handle_t de, unsigned int flags)
de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE; de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
{ {
de->u.fcb.auto_owner = (flags & DEVFS_FL_AUTO_OWNER) ? TRUE : FALSE; spin_lock (&de->u.fcb.lock);
de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE:FALSE; de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE:FALSE;
spin_unlock (&de->u.fcb.lock);
} }
return 0; return 0;
} /* End Function devfs_set_flags */ } /* End Function devfs_set_flags */
...@@ -2484,13 +2491,9 @@ static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr) ...@@ -2484,13 +2491,9 @@ static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr)
(int) inode->i_mode, (int) inode->i_uid, (int) inode->i_gid); (int) inode->i_mode, (int) inode->i_uid, (int) inode->i_gid);
/* Inode is not on hash chains, thus must save permissions here rather /* Inode is not on hash chains, thus must save permissions here rather
than in a write_inode() method */ than in a write_inode() method */
if ( ( !S_ISREG (inode->i_mode) && !S_ISCHR (inode->i_mode) && de->mode = inode->i_mode;
!S_ISBLK (inode->i_mode) ) || !de->u.fcb.auto_owner ) de->inode.uid = inode->i_uid;
{ de->inode.gid = inode->i_gid;
de->mode = inode->i_mode;
de->inode.uid = inode->i_uid;
de->inode.gid = inode->i_gid;
}
de->inode.atime = inode->i_atime; de->inode.atime = inode->i_atime;
de->inode.mtime = inode->i_mtime; de->inode.mtime = inode->i_mtime;
de->inode.ctime = inode->i_ctime; de->inode.ctime = inode->i_ctime;
...@@ -2589,9 +2592,7 @@ static struct inode *_devfs_get_vfs_inode (struct super_block *sb, ...@@ -2589,9 +2592,7 @@ static struct inode *_devfs_get_vfs_inode (struct super_block *sb,
inode->i_op = &devfs_symlink_iops; inode->i_op = &devfs_symlink_iops;
inode->i_size = de->u.symlink.length; inode->i_size = de->u.symlink.length;
} }
if (is_fcb && de->u.fcb.auto_owner) inode->i_mode = de->mode;
inode->i_mode = (de->mode & S_IFMT) | S_IRUGO | S_IWUGO;
else inode->i_mode = de->mode;
inode->i_uid = de->inode.uid; inode->i_uid = de->inode.uid;
inode->i_gid = de->inode.gid; inode->i_gid = de->inode.gid;
inode->i_atime = de->inode.atime; inode->i_atime = de->inode.atime;
...@@ -2708,15 +2709,11 @@ static int devfs_open (struct inode *inode, struct file *file) ...@@ -2708,15 +2709,11 @@ static int devfs_open (struct inode *inode, struct file *file)
} }
if (err < 0) return err; if (err < 0) return err;
/* Open was successful */ /* Open was successful */
if (df->open) return 0; spin_lock (&df->lock);
df->open = TRUE; /* This is the first open */ err = df->open;
if (df->auto_owner) if (!err) df->open = TRUE; /* Was not already open */
{ spin_unlock (&df->lock);
/* Change the ownership/protection to what driver specified */ if (err) return 0; /* Was already open */
inode->i_mode = de->mode;
inode->i_uid = current->euid;
inode->i_gid = current->egid;
}
if ( df->aopen_notify && !is_devfsd_or_child (fs_info) ) if ( df->aopen_notify && !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
current->euid, current->egid, fs_info, 0); current->euid, current->egid, fs_info, 0);
...@@ -2796,6 +2793,7 @@ static struct dentry_operations devfs_wait_dops = ...@@ -2796,6 +2793,7 @@ static struct dentry_operations devfs_wait_dops =
static int devfs_d_delete (struct dentry *dentry) static int devfs_d_delete (struct dentry *dentry)
{ {
int was_open;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct devfs_entry *de; struct devfs_entry *de;
struct fs_info *fs_info; struct fs_info *fs_info;
...@@ -2814,16 +2812,14 @@ static int devfs_d_delete (struct dentry *dentry) ...@@ -2814,16 +2812,14 @@ static int devfs_d_delete (struct dentry *dentry)
if (de == NULL) return 0; if (de == NULL) return 0;
if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) ) if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
return 0; return 0;
if (!de->u.fcb.open) return 0; spin_lock (&de->u.fcb.lock);
de->u.fcb.open = FALSE; was_open = de->u.fcb.open;
if (was_open) de->u.fcb.open = FALSE;
spin_unlock (&de->u.fcb.lock);
if (!was_open) return 0;
if (de->u.fcb.aopen_notify) if (de->u.fcb.aopen_notify)
devfsd_notify_de (de, DEVFSD_NOTIFY_CLOSE, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_CLOSE, inode->i_mode,
current->euid, current->egid, fs_info, 1); current->euid, current->egid, fs_info, 1);
if (!de->u.fcb.auto_owner) return 0;
/* Change the ownership/protection back */
inode->i_mode = (de->mode & S_IFMT) | S_IRUGO | S_IWUGO;
inode->i_uid = de->inode.uid;
inode->i_gid = de->inode.gid;
return 0; return 0;
} /* End Function devfs_d_delete */ } /* End Function devfs_d_delete */
......
...@@ -58,6 +58,8 @@ ...@@ -58,6 +58,8 @@
Fixed shift warning on 64 bit machines. Fixed shift warning on 64 bit machines.
20020428 Richard Gooch <rgooch@atnf.csiro.au> 20020428 Richard Gooch <rgooch@atnf.csiro.au>
Copied and used macro for error messages from fs/devfs/base.c Copied and used macro for error messages from fs/devfs/base.c
20021013 Richard Gooch <rgooch@atnf.csiro.au>
Documentation fix.
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -309,7 +311,7 @@ EXPORT_SYMBOL(devfs_alloc_devnum); ...@@ -309,7 +311,7 @@ EXPORT_SYMBOL(devfs_alloc_devnum);
* @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK). * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
* @devnum: The device number. * @devnum: The device number.
* *
* This routine is thread safe and does not block. * This routine is thread safe and may block.
*/ */
void devfs_dealloc_devnum (char type, kdev_t devnum) void devfs_dealloc_devnum (char type, kdev_t devnum)
......
...@@ -23,21 +23,14 @@ ...@@ -23,21 +23,14 @@
#define DEVFS_FL_NONE 0x000 /* This helps to make code more readable #define DEVFS_FL_NONE 0x000 /* This helps to make code more readable
*/ */
#define DEVFS_FL_AUTO_OWNER 0x001 /* When a closed inode is opened the #define DEVFS_FL_HIDE 0x001 /* Do not show entry in directory list */
ownerships are set to the opening #define DEVFS_FL_AUTO_DEVNUM 0x002 /* Automatically generate device number
process and the protection is set to
that given in <<mode>>. When the inode
is closed, ownership reverts back to
<<uid>> and <<gid>> and the protection
is set to read-write for all */
#define DEVFS_FL_HIDE 0x002 /* Do not show entry in directory list */
#define DEVFS_FL_AUTO_DEVNUM 0x004 /* Automatically generate device number
*/ */
#define DEVFS_FL_AOPEN_NOTIFY 0x008 /* Asynchronously notify devfsd on open #define DEVFS_FL_AOPEN_NOTIFY 0x004 /* Asynchronously notify devfsd on open
*/ */
#define DEVFS_FL_REMOVABLE 0x010 /* This is a removable media device */ #define DEVFS_FL_REMOVABLE 0x008 /* This is a removable media device */
#define DEVFS_FL_WAIT 0x020 /* Wait for devfsd to finish */ #define DEVFS_FL_WAIT 0x010 /* Wait for devfsd to finish */
#define DEVFS_FL_CURRENT_OWNER 0x040 /* Set initial ownership to current */ #define DEVFS_FL_CURRENT_OWNER 0x020 /* Set initial ownership to current */
#define DEVFS_FL_DEFAULT DEVFS_FL_NONE #define DEVFS_FL_DEFAULT DEVFS_FL_NONE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment