Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-cor…
Browse files Browse the repository at this point in the history
…e-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (27 commits)
  Driver core: fix race in dev_driver_string
  Driver Core: Early platform driver buffer
  sysfs: sysfs_setattr remove unnecessary permission check.
  sysfs: Factor out sysfs_rename from sysfs_rename_dir and sysfs_move_dir
  sysfs: Propagate renames to the vfs on demand
  sysfs: Gut sysfs_addrm_start and sysfs_addrm_finish
  sysfs: In sysfs_chmod_file lazily propagate the mode change.
  sysfs: Implement sysfs_getattr & sysfs_permission
  sysfs: Nicely indent sysfs_symlink_inode_operations
  sysfs: Update s_iattr on link and unlink.
  sysfs: Fix locking and factor out sysfs_sd_setattr
  sysfs: Simplify iattr time assignments
  sysfs: Simplify sysfs_chmod_file semantics
  sysfs: Use dentry_ops instead of directly playing with the dcache
  sysfs: Rename sysfs_d_iput to sysfs_dentry_iput
  sysfs: Update sysfs_setxattr so it updates secdata under the sysfs_mutex
  debugfs: fix create mutex racy fops and private data
  Driver core: Don't remove kobjects in device_shutdown.
  firmware_class: make request_firmware_nowait more useful
  Driver-Core: devtmpfs - set root directory mode to 0755
  ...
  • Loading branch information
torvalds committed Dec 11, 2009
2 parents 748e566 + 3589972 commit f58df54
Show file tree
Hide file tree
Showing 21 changed files with 428 additions and 506 deletions.
14 changes: 10 additions & 4 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ static inline int device_is_not_partition(struct device *dev)
*/
const char *dev_driver_string(const struct device *dev)
{
return dev->driver ? dev->driver->name :
struct device_driver *drv;

/* dev->driver can change to NULL underneath us because of unbinding,
* so be careful about accessing it. dev->bus and dev->class should
* never change once they are set, so they don't need special care.
*/
drv = ACCESS_ONCE(dev->driver);
return drv ? drv->name :
(dev->bus ? dev->bus->name :
(dev->class ? dev->class->name : ""));
}
Expand Down Expand Up @@ -986,6 +993,8 @@ int device_add(struct device *dev)
AttrsError:
device_remove_class_symlinks(dev);
SymlinkError:
if (MAJOR(dev->devt))
devtmpfs_delete_node(dev);
if (MAJOR(dev->devt))
device_remove_sys_dev_entry(dev);
devtattrError:
Expand Down Expand Up @@ -1728,8 +1737,5 @@ void device_shutdown(void)
dev->driver->shutdown(dev);
}
}
kobject_put(sysfs_dev_char_kobj);
kobject_put(sysfs_dev_block_kobj);
kobject_put(dev_kobj);
async_synchronize_full();
}
100 changes: 50 additions & 50 deletions drivers/base/devtmpfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ static int dev_mount = 1;
static int dev_mount;
#endif

static rwlock_t dirlock;

static int __init mount_param(char *str)
{
dev_mount = simple_strtoul(str, NULL, 0);
Expand Down Expand Up @@ -74,47 +76,35 @@ static int dev_mkdir(const char *name, mode_t mode)
dentry = lookup_create(&nd, 1);
if (!IS_ERR(dentry)) {
err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
if (!err)
/* mark as kernel-created inode */
dentry->d_inode->i_private = &dev_mnt;
dput(dentry);
} else {
err = PTR_ERR(dentry);
}
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);

mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
path_put(&nd.path);
return err;
}

static int create_path(const char *nodepath)
{
char *path;
struct nameidata nd;
int err = 0;

path = kstrdup(nodepath, GFP_KERNEL);
if (!path)
return -ENOMEM;

err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
path, LOOKUP_PARENT, &nd);
if (err == 0) {
struct dentry *dentry;

/* create directory right away */
dentry = lookup_create(&nd, 1);
if (!IS_ERR(dentry)) {
err = vfs_mkdir(nd.path.dentry->d_inode,
dentry, 0755);
dput(dentry);
}
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
int err;

path_put(&nd.path);
} else if (err == -ENOENT) {
read_lock(&dirlock);
err = dev_mkdir(nodepath, 0755);
if (err == -ENOENT) {
char *path;
char *s;

/* parent directories do not exist, create them */
path = kstrdup(nodepath, GFP_KERNEL);
if (!path)
return -ENOMEM;
s = path;
while (1) {
for (;;) {
s = strchr(s, '/');
if (!s)
break;
Expand All @@ -125,9 +115,9 @@ static int create_path(const char *nodepath)
s[0] = '/';
s++;
}
kfree(path);
}

kfree(path);
read_unlock(&dirlock);
return err;
}

Expand Down Expand Up @@ -156,34 +146,40 @@ int devtmpfs_create_node(struct device *dev)
mode |= S_IFCHR;

curr_cred = override_creds(&init_cred);

err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
nodename, LOOKUP_PARENT, &nd);
if (err == -ENOENT) {
/* create missing parent directories */
create_path(nodename);
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
nodename, LOOKUP_PARENT, &nd);
if (err)
goto out;
}
if (err)
goto out;

dentry = lookup_create(&nd, 0);
if (!IS_ERR(dentry)) {
int umask;

umask = sys_umask(0000);
err = vfs_mknod(nd.path.dentry->d_inode,
dentry, mode, dev->devt);
sys_umask(umask);
/* mark as kernel created inode */
if (!err)
if (!err) {
struct iattr newattrs;

/* fixup possibly umasked mode */
newattrs.ia_mode = mode;
newattrs.ia_valid = ATTR_MODE;
mutex_lock(&dentry->d_inode->i_mutex);
notify_change(dentry, &newattrs);
mutex_unlock(&dentry->d_inode->i_mutex);

/* mark as kernel-created inode */
dentry->d_inode->i_private = &dev_mnt;
}
dput(dentry);
} else {
err = PTR_ERR(dentry);
}
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);

mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
path_put(&nd.path);
out:
kfree(tmp);
Expand All @@ -205,16 +201,21 @@ static int dev_rmdir(const char *name)
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
if (!IS_ERR(dentry)) {
if (dentry->d_inode)
err = vfs_rmdir(nd.path.dentry->d_inode, dentry);
else
if (dentry->d_inode) {
if (dentry->d_inode->i_private == &dev_mnt)
err = vfs_rmdir(nd.path.dentry->d_inode,
dentry);
else
err = -EPERM;
} else {
err = -ENOENT;
}
dput(dentry);
} else {
err = PTR_ERR(dentry);
}
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);

mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
path_put(&nd.path);
return err;
}
Expand All @@ -228,7 +229,8 @@ static int delete_path(const char *nodepath)
if (!path)
return -ENOMEM;

while (1) {
write_lock(&dirlock);
for (;;) {
char *base;

base = strrchr(path, '/');
Expand All @@ -239,6 +241,7 @@ static int delete_path(const char *nodepath)
if (err)
break;
}
write_unlock(&dirlock);

kfree(path);
return err;
Expand Down Expand Up @@ -322,9 +325,8 @@ int devtmpfs_delete_node(struct device *dev)
* If configured, or requested by the commandline, devtmpfs will be
* auto-mounted after the kernel mounted the root filesystem.
*/
int devtmpfs_mount(const char *mountpoint)
int devtmpfs_mount(const char *mntdir)
{
struct path path;
int err;

if (!dev_mount)
Expand All @@ -333,15 +335,11 @@ int devtmpfs_mount(const char *mountpoint)
if (!dev_mnt)
return 0;

err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
if (err)
return err;
err = do_add_mount(dev_mnt, &path, 0, NULL);
err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL);
if (err)
printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
else
printk(KERN_INFO "devtmpfs: mounted\n");
path_put(&path);
return err;
}

Expand All @@ -354,14 +352,16 @@ int __init devtmpfs_init(void)
int err;
struct vfsmount *mnt;

rwlock_init(&dirlock);

err = register_filesystem(&dev_fs_type);
if (err) {
printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
"type %i\n", err);
return err;
}

mnt = kern_mount(&dev_fs_type);
mnt = kern_mount_data(&dev_fs_type, "mode=0755");
if (IS_ERR(mnt)) {
err = PTR_ERR(mnt);
printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
Expand Down
14 changes: 6 additions & 8 deletions drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,12 +601,9 @@ request_firmware_work_func(void *arg)
}
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->uevent);
if (ret < 0)
fw_work->cont(NULL, fw_work->context);
else {
fw_work->cont(fw, fw_work->context);
release_firmware(fw);
}

fw_work->cont(fw, fw_work->context);

module_put(fw_work->module);
kfree(fw_work);
return ret;
Expand All @@ -619,6 +616,7 @@ request_firmware_work_func(void *arg)
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
* @gfp: allocation flags
* @context: will be passed over to @cont, and
* @fw may be %NULL if firmware request fails.
* @cont: function will be called asynchronously when the firmware
Expand All @@ -631,12 +629,12 @@ request_firmware_work_func(void *arg)
int
request_firmware_nowait(
struct module *module, int uevent,
const char *name, struct device *device, void *context,
const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
struct task_struct *task;
struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
GFP_ATOMIC);
gfp);

if (!fw_work)
return -ENOMEM;
Expand Down
29 changes: 22 additions & 7 deletions drivers/base/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,7 @@ static __initdata LIST_HEAD(early_platform_device_list);
int __init early_platform_driver_register(struct early_platform_driver *epdrv,
char *buf)
{
unsigned long index;
char *tmp;
int n;

/* Simply add the driver to the end of the global list.
Expand All @@ -1019,13 +1019,28 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
list_move(&epdrv->list, &early_platform_driver_list);

if (!strcmp(buf, epdrv->pdrv->driver.name))
/* Allow passing parameters after device name */
if (buf[n] == '\0' || buf[n] == ',')
epdrv->requested_id = -1;
else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10,
&index) == 0)
epdrv->requested_id = index;
else
epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
else {
epdrv->requested_id = simple_strtoul(&buf[n + 1],
&tmp, 10);

if (buf[n] != '.' || (tmp == &buf[n + 1])) {
epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
n = 0;
} else
n += strcspn(&buf[n + 1], ",") + 1;
}

if (buf[n] == ',')
n++;

if (epdrv->bufsize) {
memcpy(epdrv->buffer, &buf[n],
min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
epdrv->buffer[epdrv->bufsize - 1] = '\0';
}
}

return 0;
Expand Down
9 changes: 7 additions & 2 deletions drivers/firmware/dell_rbu.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,12 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
{
rbu_data.entry_created = 0;

if (!fw || !fw->size)
if (!fw)
return;

if (!fw->size)
goto out;

spin_lock(&rbu_data.lock);
if (!strcmp(image_type, "mono")) {
if (!img_update_realloc(fw->size))
Expand All @@ -568,6 +571,8 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
} else
pr_debug("invalid image type specified.\n");
spin_unlock(&rbu_data.lock);
out:
release_firmware(fw);
}

static ssize_t read_rbu_image_type(struct kobject *kobj,
Expand Down Expand Up @@ -615,7 +620,7 @@ static ssize_t write_rbu_image_type(struct kobject *kobj,
spin_unlock(&rbu_data.lock);
req_firm_rc = request_firmware_nowait(THIS_MODULE,
FW_ACTION_NOHOTPLUG, "dell_rbu",
&rbu_device->dev, &context,
&rbu_device->dev, GFP_KERNEL, &context,
callbackfn_rbu);
if (req_firm_rc) {
printk(KERN_ERR
Expand Down
13 changes: 12 additions & 1 deletion drivers/misc/hpilo.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,20 @@ struct ilo_hwinfo {

struct pci_dev *ilo_dev;

/*
* open_lock serializes ccb_cnt during open and close
* [ irq disabled ]
* -> alloc_lock used when adding/removing/searching ccb_alloc,
* which represents all ccbs open on the device
* --> fifo_lock controls access to fifo queues shared with hw
*
* Locks must be taken in this order, but open_lock and alloc_lock
* are optional, they do not need to be held in order to take a
* lower level lock.
*/
spinlock_t open_lock;
spinlock_t alloc_lock;
spinlock_t fifo_lock;
spinlock_t open_lock;

struct cdev cdev;
};
Expand Down
Loading

0 comments on commit f58df54

Please sign in to comment.