aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/devtmpfs.c
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2013-04-06 12:56:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-08 11:21:48 -0400
commit3c2670e6515cf584810f417db9b00992c8b2d75a (patch)
treebc13c7babc6c8f08b6a82d0b3848778b264d9651 /drivers/base/devtmpfs.c
parentbb2b0051d7b0772ea9d0b4be900c2d965093f5d7 (diff)
driver core: add uid and gid to devtmpfs
Some drivers want to tell userspace what uid and gid should be used for their device nodes, so allow that information to percolate through the driver core to userspace in order to make this happen. This means that some systems (i.e. Android and friends) will not need to even run a udev-like daemon for their device node manager and can just rely in devtmpfs fully, reducing their footprint even more. Signed-off-by: Kay Sievers <kay@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/devtmpfs.c')
-rw-r--r--drivers/base/devtmpfs.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 01fc5b07f951..fda52563677f 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -41,6 +41,8 @@ static struct req {
41 int err; 41 int err;
42 const char *name; 42 const char *name;
43 umode_t mode; /* 0 => delete */ 43 umode_t mode; /* 0 => delete */
44 uid_t uid;
45 gid_t gid;
44 struct device *dev; 46 struct device *dev;
45} *requests; 47} *requests;
46 48
@@ -85,7 +87,9 @@ int devtmpfs_create_node(struct device *dev)
85 return 0; 87 return 0;
86 88
87 req.mode = 0; 89 req.mode = 0;
88 req.name = device_get_devnode(dev, &req.mode, &tmp); 90 req.uid = 0;
91 req.gid = 0;
92 req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp);
89 if (!req.name) 93 if (!req.name)
90 return -ENOMEM; 94 return -ENOMEM;
91 95
@@ -121,7 +125,7 @@ int devtmpfs_delete_node(struct device *dev)
121 if (!thread) 125 if (!thread)
122 return 0; 126 return 0;
123 127
124 req.name = device_get_devnode(dev, NULL, &tmp); 128 req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp);
125 if (!req.name) 129 if (!req.name)
126 return -ENOMEM; 130 return -ENOMEM;
127 131
@@ -187,7 +191,8 @@ static int create_path(const char *nodepath)
187 return err; 191 return err;
188} 192}
189 193
190static int handle_create(const char *nodename, umode_t mode, struct device *dev) 194static int handle_create(const char *nodename, umode_t mode, uid_t uid,
195 gid_t gid, struct device *dev)
191{ 196{
192 struct dentry *dentry; 197 struct dentry *dentry;
193 struct path path; 198 struct path path;
@@ -201,14 +206,14 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
201 if (IS_ERR(dentry)) 206 if (IS_ERR(dentry))
202 return PTR_ERR(dentry); 207 return PTR_ERR(dentry);
203 208
204 err = vfs_mknod(path.dentry->d_inode, 209 err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt);
205 dentry, mode, dev->devt);
206 if (!err) { 210 if (!err) {
207 struct iattr newattrs; 211 struct iattr newattrs;
208 212
209 /* fixup possibly umasked mode */
210 newattrs.ia_mode = mode; 213 newattrs.ia_mode = mode;
211 newattrs.ia_valid = ATTR_MODE; 214 newattrs.ia_uid = uid;
215 newattrs.ia_gid = gid;
216 newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID;
212 mutex_lock(&dentry->d_inode->i_mutex); 217 mutex_lock(&dentry->d_inode->i_mutex);
213 notify_change(dentry, &newattrs); 218 notify_change(dentry, &newattrs);
214 mutex_unlock(&dentry->d_inode->i_mutex); 219 mutex_unlock(&dentry->d_inode->i_mutex);
@@ -358,10 +363,11 @@ int devtmpfs_mount(const char *mntdir)
358 363
359static DECLARE_COMPLETION(setup_done); 364static DECLARE_COMPLETION(setup_done);
360 365
361static int handle(const char *name, umode_t mode, struct device *dev) 366static int handle(const char *name, umode_t mode, uid_t uid, gid_t gid,
367 struct device *dev)
362{ 368{
363 if (mode) 369 if (mode)
364 return handle_create(name, mode, dev); 370 return handle_create(name, mode, uid, gid, dev);
365 else 371 else
366 return handle_remove(name, dev); 372 return handle_remove(name, dev);
367} 373}
@@ -387,7 +393,8 @@ static int devtmpfsd(void *p)
387 spin_unlock(&req_lock); 393 spin_unlock(&req_lock);
388 while (req) { 394 while (req) {
389 struct req *next = req->next; 395 struct req *next = req->next;
390 req->err = handle(req->name, req->mode, req->dev); 396 req->err = handle(req->name, req->mode,
397 req->uid, req->gid, req->dev);
391 complete(&req->done); 398 complete(&req->done);
392 req = next; 399 req = next;
393 } 400 }