diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-11 12:08:24 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-14 09:15:28 -0400 |
commit | 73d049a40fc6269189c4e2ba6792cb5dd054883c (patch) | |
tree | a713747cd06926ad89bfa9b36ea13dd20bbc507f /kernel/sysctl_binary.c | |
parent | 5b6ca027d85b7438c84b78a54ccdc2e53f2909cd (diff) |
open-style analog of vfs_path_lookup()
new function: file_open_root(dentry, mnt, name, flags) opens the file
vfs_path_lookup would arrive to.
Note that name can be empty; in that case the usual requirement that
dentry should be a directory is lifted.
open-coded equivalents switched to it, may_open() got down exactly
one caller and became static.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/sysctl_binary.c')
-rw-r--r-- | kernel/sysctl_binary.c | 19 |
1 files changed, 1 insertions, 18 deletions
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index b875bedf7c9a..3b8e028b9601 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c | |||
@@ -1321,13 +1321,11 @@ static ssize_t binary_sysctl(const int *name, int nlen, | |||
1321 | void __user *oldval, size_t oldlen, void __user *newval, size_t newlen) | 1321 | void __user *oldval, size_t oldlen, void __user *newval, size_t newlen) |
1322 | { | 1322 | { |
1323 | const struct bin_table *table = NULL; | 1323 | const struct bin_table *table = NULL; |
1324 | struct nameidata nd; | ||
1325 | struct vfsmount *mnt; | 1324 | struct vfsmount *mnt; |
1326 | struct file *file; | 1325 | struct file *file; |
1327 | ssize_t result; | 1326 | ssize_t result; |
1328 | char *pathname; | 1327 | char *pathname; |
1329 | int flags; | 1328 | int flags; |
1330 | int acc_mode; | ||
1331 | 1329 | ||
1332 | pathname = sysctl_getname(name, nlen, &table); | 1330 | pathname = sysctl_getname(name, nlen, &table); |
1333 | result = PTR_ERR(pathname); | 1331 | result = PTR_ERR(pathname); |
@@ -1337,28 +1335,17 @@ static ssize_t binary_sysctl(const int *name, int nlen, | |||
1337 | /* How should the sysctl be accessed? */ | 1335 | /* How should the sysctl be accessed? */ |
1338 | if (oldval && oldlen && newval && newlen) { | 1336 | if (oldval && oldlen && newval && newlen) { |
1339 | flags = O_RDWR; | 1337 | flags = O_RDWR; |
1340 | acc_mode = MAY_READ | MAY_WRITE; | ||
1341 | } else if (newval && newlen) { | 1338 | } else if (newval && newlen) { |
1342 | flags = O_WRONLY; | 1339 | flags = O_WRONLY; |
1343 | acc_mode = MAY_WRITE; | ||
1344 | } else if (oldval && oldlen) { | 1340 | } else if (oldval && oldlen) { |
1345 | flags = O_RDONLY; | 1341 | flags = O_RDONLY; |
1346 | acc_mode = MAY_READ; | ||
1347 | } else { | 1342 | } else { |
1348 | result = 0; | 1343 | result = 0; |
1349 | goto out_putname; | 1344 | goto out_putname; |
1350 | } | 1345 | } |
1351 | 1346 | ||
1352 | mnt = current->nsproxy->pid_ns->proc_mnt; | 1347 | mnt = current->nsproxy->pid_ns->proc_mnt; |
1353 | result = vfs_path_lookup(mnt->mnt_root, mnt, pathname, 0, &nd); | 1348 | file = file_open_root(mnt->mnt_root, mnt, pathname, flags); |
1354 | if (result) | ||
1355 | goto out_putname; | ||
1356 | |||
1357 | result = may_open(&nd.path, acc_mode, flags); | ||
1358 | if (result) | ||
1359 | goto out_putpath; | ||
1360 | |||
1361 | file = dentry_open(nd.path.dentry, nd.path.mnt, flags, current_cred()); | ||
1362 | result = PTR_ERR(file); | 1349 | result = PTR_ERR(file); |
1363 | if (IS_ERR(file)) | 1350 | if (IS_ERR(file)) |
1364 | goto out_putname; | 1351 | goto out_putname; |
@@ -1370,10 +1357,6 @@ out_putname: | |||
1370 | putname(pathname); | 1357 | putname(pathname); |
1371 | out: | 1358 | out: |
1372 | return result; | 1359 | return result; |
1373 | |||
1374 | out_putpath: | ||
1375 | path_put(&nd.path); | ||
1376 | goto out_putname; | ||
1377 | } | 1360 | } |
1378 | 1361 | ||
1379 | 1362 | ||