git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
nfsd: move some of fh_compose into helper functions
[safe/jmp/linux-2.6]
/
fs
/
char_dev.c
diff --git
a/fs/char_dev.c
b/fs/char_dev.c
index
e6194e2
..
a173551
100644
(file)
--- a/
fs/char_dev.c
+++ b/
fs/char_dev.c
@@
-6,13
+6,13
@@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/fs.h>
+#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/kobject.h>
#include <linux/seq_file.h>
#include <linux/kobject.h>
@@
-21,9
+21,6
@@
#include <linux/mutex.h>
#include <linux/backing-dev.h>
#include <linux/mutex.h>
#include <linux/backing-dev.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
#include "internal.h"
/*
#include "internal.h"
/*
@@
-54,7
+51,6
@@
static struct char_device_struct {
unsigned int baseminor;
int minorct;
char name[64];
unsigned int baseminor;
int minorct;
char name[64];
- struct file_operations *fops;
struct cdev *cdev; /* will die */
} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
struct cdev *cdev; /* will die */
} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
@@
-108,13
+104,6
@@
__register_chrdev_region(unsigned int major, unsigned int baseminor,
/* temporary */
if (major == 0) {
for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
/* temporary */
if (major == 0) {
for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
- /*
- * Disallow the LANANA-assigned LOCAL/EXPERIMENTAL
- * majors
- */
- if ((60 <= i && i <= 63) || (120 <= i && i <= 127) ||
- (240 <= i && i <= 254))
- continue;
if (chrdevs[i] == NULL)
break;
}
if (chrdevs[i] == NULL)
break;
}
@@
-130,7
+119,7
@@
__register_chrdev_region(unsigned int major, unsigned int baseminor,
cd->major = major;
cd->baseminor = baseminor;
cd->minorct = minorct;
cd->major = major;
cd->baseminor = baseminor;
cd->minorct = minorct;
- str
ncpy(cd->name,name, 64
);
+ str
lcpy(cd->name, name, sizeof(cd->name)
);
i = major_to_index(major);
i = major_to_index(major);
@@
-327,14
+316,13
@@
void unregister_chrdev_region(dev_t from, unsigned count)
}
}
}
}
-
int
unregister_chrdev(unsigned int major, const char *name)
+
void
unregister_chrdev(unsigned int major, const char *name)
{
struct char_device_struct *cd;
cd = __unregister_chrdev_region(major, 0, 256);
if (cd && cd->cdev)
cdev_del(cd->cdev);
kfree(cd);
{
struct char_device_struct *cd;
cd = __unregister_chrdev_region(major, 0, 256);
if (cd && cd->cdev)
cdev_del(cd->cdev);
kfree(cd);
- return 0;
}
static DEFINE_SPINLOCK(cdev_lock);
}
static DEFINE_SPINLOCK(cdev_lock);
@@
-364,7
+352,7
@@
void cdev_put(struct cdev *p)
/*
* Called every time a character special file is opened
*/
/*
* Called every time a character special file is opened
*/
-
int chrdev_open(struct inode * inode, struct file *
filp)
+
static int chrdev_open(struct inode *inode, struct file *
filp)
{
struct cdev *p;
struct cdev *new = NULL;
{
struct cdev *p;
struct cdev *new = NULL;
@@
-381,10
+369,11
@@
int chrdev_open(struct inode * inode, struct file * filp)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
+ /* Check i_cdev again in case somebody beat us to it while
+ we dropped the lock. */
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
- inode->i_cindex = idx;
list_add(&inode->i_devices, &p->list);
new = NULL;
} else if (!cdev_get(p))
list_add(&inode->i_devices, &p->list);
new = NULL;
} else if (!cdev_get(p))
@@
-395,21
+384,37
@@
int chrdev_open(struct inode * inode, struct file * filp)
cdev_put(new);
if (ret)
return ret;
cdev_put(new);
if (ret)
return ret;
+
+ ret = -ENXIO;
filp->f_op = fops_get(p->ops);
filp->f_op = fops_get(p->ops);
- if (!filp->f_op) {
- cdev_put(p);
- return -ENXIO;
- }
+ if (!filp->f_op)
+ goto out_cdev_put;
+
if (filp->f_op->open) {
if (filp->f_op->open) {
- lock_kernel();
ret = filp->f_op->open(inode,filp);
ret = filp->f_op->open(inode,filp);
- unlock_kernel();
+ if (ret)
+ goto out_cdev_put;
}
}
- if (ret)
- cdev_put(p);
+
+ return 0;
+
+ out_cdev_put:
+ cdev_put(p);
return ret;
}
return ret;
}
+int cdev_index(struct inode *inode)
+{
+ int idx;
+ struct kobject *kobj;
+
+ kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
+ if (!kobj)
+ return -1;
+ kobject_put(kobj);
+ return idx;
+}
+
void cd_forget(struct inode *inode)
{
spin_lock(&cdev_lock);
void cd_forget(struct inode *inode)
{
spin_lock(&cdev_lock);
@@
-517,9
+522,8
@@
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
- p->kobj.ktype = &ktype_cdev_dynamic;
INIT_LIST_HEAD(&p->list);
INIT_LIST_HEAD(&p->list);
- kobject_init(&p->kobj);
+ kobject_init(&p->kobj
, &ktype_cdev_dynamic
);
}
return p;
}
}
return p;
}
@@
-536,8
+540,7
@@
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
- cdev->kobj.ktype = &ktype_cdev_default;
- kobject_init(&cdev->kobj);
+ kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}
cdev->ops = fops;
}
@@
-552,6
+555,7
@@
static struct kobject *base_probe(dev_t dev, int *part, void *data)
void __init chrdev_init(void)
{
cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
void __init chrdev_init(void)
{
cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
+ bdi_init(&directly_mappable_cdev_bdi);
}
}
@@
-563,6
+567,7
@@
EXPORT_SYMBOL(cdev_init);
EXPORT_SYMBOL(cdev_alloc);
EXPORT_SYMBOL(cdev_del);
EXPORT_SYMBOL(cdev_add);
EXPORT_SYMBOL(cdev_alloc);
EXPORT_SYMBOL(cdev_del);
EXPORT_SYMBOL(cdev_add);
+EXPORT_SYMBOL(cdev_index);
EXPORT_SYMBOL(register_chrdev);
EXPORT_SYMBOL(unregister_chrdev);
EXPORT_SYMBOL(directly_mappable_cdev_bdi);
EXPORT_SYMBOL(register_chrdev);
EXPORT_SYMBOL(unregister_chrdev);
EXPORT_SYMBOL(directly_mappable_cdev_bdi);