diff options
Diffstat (limited to 'drivers/char/misc.c')
| -rw-r--r-- | drivers/char/misc.c | 34 | 
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 778273c9324..ffa97d261cf 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -114,7 +114,7 @@ static int misc_open(struct inode * inode, struct file * file)  	int minor = iminor(inode);  	struct miscdevice *c;  	int err = -ENODEV; -	const struct file_operations *old_fops, *new_fops = NULL; +	const struct file_operations *new_fops = NULL;  	mutex_lock(&misc_mtx); @@ -141,17 +141,11 @@ static int misc_open(struct inode * inode, struct file * file)  	}  	err = 0; -	old_fops = file->f_op; -	file->f_op = new_fops; +	replace_fops(file, new_fops);  	if (file->f_op->open) {  		file->private_data = c; -		err=file->f_op->open(inode,file); -		if (err) { -			fops_put(file->f_op); -			file->f_op = fops_get(old_fops); -		} +		err = file->f_op->open(inode,file);  	} -	fops_put(old_fops);  fail:  	mutex_unlock(&misc_mtx);  	return err; @@ -183,28 +177,30 @@ static const struct file_operations misc_fops = {  int misc_register(struct miscdevice * misc)  { -	struct miscdevice *c;  	dev_t dev;  	int err = 0;  	INIT_LIST_HEAD(&misc->list);  	mutex_lock(&misc_mtx); -	list_for_each_entry(c, &misc_list, list) { -		if (c->minor == misc->minor) { -			mutex_unlock(&misc_mtx); -			return -EBUSY; -		} -	}  	if (misc->minor == MISC_DYNAMIC_MINOR) {  		int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);  		if (i >= DYNAMIC_MINORS) { -			mutex_unlock(&misc_mtx); -			return -EBUSY; +			err = -EBUSY; +			goto out;  		}  		misc->minor = DYNAMIC_MINORS - i - 1;  		set_bit(i, misc_minors); +	} else { +		struct miscdevice *c; + +		list_for_each_entry(c, &misc_list, list) { +			if (c->minor == misc->minor) { +				err = -EBUSY; +				goto out; +			} +		}  	}  	dev = MKDEV(MISC_MAJOR, misc->minor); @@ -258,7 +254,7 @@ int misc_deregister(struct miscdevice *misc)  EXPORT_SYMBOL(misc_register);  EXPORT_SYMBOL(misc_deregister); -static char *misc_devnode(struct device *dev, mode_t *mode) +static char *misc_devnode(struct device *dev, umode_t *mode)  {  	struct miscdevice *c = dev_get_drvdata(dev);  | 
