History

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.

Al Viro committed 15 years ago

Commit 73d049a1 parent 5b6ca027 files · +77 −84Browse files

Unified · Split

7 files
  1. arch/um/drivers/mconsole_kern.c +2 −19
  2. fs/internal.h +2 −0
  3. fs/namei.c +52 −28
  4. fs/nfsctl.c +4 −17
  5. fs/open.c +14 −0
  6. include/linux/fs.h +2 −2
  7. kernel/sysctl_binary.c +1 −18
arch/um/drivers/mconsole_kern.c+2−19
@@ -124,35 +124,18 @@ void mconsole_log(struct mc_request *req) · 123 unmodified lines
124124 #if 0
125125 void mconsole_proc(struct mc_request *req)
126126 {
127− struct nameidata nd;
128127 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
129128 struct file *file;
130− int n, err;
129+ int n;
131130 char *ptr = req->request.data, *buf;
132131 mm_segment_t old_fs = get_fs();
133132
134133 ptr += strlen("proc");
135134 ptr = skip_spaces(ptr);
136135
137− err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd);
138− if (err) {
139− mconsole_reply(req, "Failed to look up file", 1, 0);
140− goto out;
141− }
142−
143− err = may_open(&nd.path, MAY_READ, O_RDONLY);
144− if (result) {
145− mconsole_reply(req, "Failed to open file", 1, 0);
146− path_put(&nd.path);
147− goto out;
148− }
149−
150− file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
151− current_cred());
152− err = PTR_ERR(file);
136+ file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
153137 if (IS_ERR(file)) {
154138 mconsole_reply(req, "Failed to open file", 1, 0);
155− path_put(&nd.path);
156139 goto out;
157140 }
158141
fs/internal.h+2−0
@@ -114,6 +114,8 @@ struct open_flags { · 113 unmodified lines
114114 };
115115 extern struct file *do_filp_open(int dfd, const char *pathname,
116116 const struct open_flags *op, int lookup_flags);
117+extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
118+ const char *, const struct open_flags *, int lookup_flags);
117119
118120 /*
119121 * inode.c
fs/namei.c+52−28
@@ -1487,11 +1487,13 @@ static int path_init(int dfd, const char *name, unsigned int flags, · 1486 unmodified lines
14871487 nd->depth = 0;
14881488 if (flags & LOOKUP_ROOT) {
14891489 struct inode *inode = nd->root.dentry->d_inode;
1490− if (!inode->i_op->lookup)
1491− return -ENOTDIR;
1492− retval = inode_permission(inode, MAY_EXEC);
1493− if (retval)
1494− return retval;
1490+ if (*name) {
1491+ if (!inode->i_op->lookup)
1492+ return -ENOTDIR;
1493+ retval = inode_permission(inode, MAY_EXEC);
1494+ if (retval)
1495+ return retval;
1496+ }
14951497 nd->path = nd->root;
14961498 nd->inode = inode;
14971499 if (flags & LOOKUP_RCU) {
@@ -1937,7 +1939,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, · 439 unmodified lines
19371939 return error;
19381940 }
19391941
1940−int may_open(struct path *path, int acc_mode, int flag)
1942+static int may_open(struct path *path, int acc_mode, int flag)
19411943 {
19421944 struct dentry *dentry = path->dentry;
19431945 struct inode *inode = dentry->d_inode;
@@ -2250,11 +2252,10 @@ exit: · 306 unmodified lines
22502252 }
22512253
22522254 static struct file *path_openat(int dfd, const char *pathname,
2253− const struct open_flags *op, int flags)
2255+ struct nameidata *nd, const struct open_flags *op, int flags)
22542256 {
22552257 struct file *base = NULL;
22562258 struct file *filp;
2257− struct nameidata nd;
22582259 struct path path;
22592260 int count = 0;
22602261 int error;
@@ -2264,27 +2265,27 @@ static struct file *path_openat(int dfd, const char *pathname, · 3 unmodified lines
22642265 return ERR_PTR(-ENFILE);
22652266
22662267 filp->f_flags = op->open_flag;
2267− nd.intent.open.file = filp;
2268− nd.intent.open.flags = open_to_namei_flags(op->open_flag);
2269− nd.intent.open.create_mode = op->mode;
2268+ nd->intent.open.file = filp;
2269+ nd->intent.open.flags = open_to_namei_flags(op->open_flag);
2270+ nd->intent.open.create_mode = op->mode;
22702271
2271− error = path_init(dfd, pathname, flags | LOOKUP_PARENT, &nd, &base);
2272+ error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base);
22722273 if (unlikely(error))
22732274 goto out_filp;
22742275
22752276 current->total_link_count = 0;
2276− error = link_path_walk(pathname, &nd);
2277+ error = link_path_walk(pathname, nd);
22772278 if (unlikely(error))
22782279 goto out_filp;
22792280
2280− filp = do_last(&nd, &path, op, pathname);
2281+ filp = do_last(nd, &path, op, pathname);
22812282 while (unlikely(!filp)) { /* trailing symlink */
22822283 struct path link = path;
22832284 struct inode *linki = link.dentry->d_inode;
22842285 void *cookie;
2285− if (!(nd.flags & LOOKUP_FOLLOW) || count++ == 32) {
2286− path_put_conditional(&path, &nd);
2287− path_put(&nd.path);
2286+ if (!(nd->flags & LOOKUP_FOLLOW) || count++ == 32) {
2287+ path_put_conditional(&path, nd);
2288+ path_put(&nd->path);
22882289 filp = ERR_PTR(-ELOOP);
22892290 break;
22902291 }
@@ -2299,23 +2300,23 @@ static struct file *path_openat(int dfd, const char *pathname, · 8 unmodified lines
22992300 * have to putname() it when we are done. Procfs-like symlinks
23002301 * just set LAST_BIND.
23012302 */
2302− nd.flags |= LOOKUP_PARENT;
2303− nd.flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
2304− error = __do_follow_link(&link, &nd, &cookie);
2303+ nd->flags |= LOOKUP_PARENT;
2304+ nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
2305+ error = __do_follow_link(&link, nd, &cookie);
23052306 if (unlikely(error))
23062307 filp = ERR_PTR(error);
23072308 else
2308− filp = do_last(&nd, &path, op, pathname);
2309+ filp = do_last(nd, &path, op, pathname);
23092310 if (!IS_ERR(cookie) && linki->i_op->put_link)
2310− linki->i_op->put_link(link.dentry, &nd, cookie);
2311+ linki->i_op->put_link(link.dentry, nd, cookie);
23112312 path_put(&link);
23122313 }
23132314 out:
2314− if (nd.root.mnt && !(nd.flags & LOOKUP_ROOT))
2315− path_put(&nd.root);
2315+ if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
2316+ path_put(&nd->root);
23162317 if (base)
23172318 fput(base);
2318− release_open_intent(&nd);
2319+ release_open_intent(nd);
23192320 return filp;
23202321
23212322 out_filp:
@@ -2326,16 +2327,39 @@ out_filp: · 4 unmodified lines
23262327 struct file *do_filp_open(int dfd, const char *pathname,
23272328 const struct open_flags *op, int flags)
23282329 {
2330+ struct nameidata nd;
23292331 struct file *filp;
23302332
2331− filp = path_openat(dfd, pathname, op, flags | LOOKUP_RCU);
2333+ filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
23322334 if (unlikely(filp == ERR_PTR(-ECHILD)))
2333− filp = path_openat(dfd, pathname, op, flags);
2335+ filp = path_openat(dfd, pathname, &nd, op, flags);
23342336 if (unlikely(filp == ERR_PTR(-ESTALE)))
2335− filp = path_openat(dfd, pathname, op, flags | LOOKUP_REVAL);
2337+ filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_REVAL);
23362338 return filp;
23372339 }
23382340
2341+struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
2342+ const char *name, const struct open_flags *op, int flags)
2343+{
2344+ struct nameidata nd;
2345+ struct file *file;
2346+
2347+ nd.root.mnt = mnt;
2348+ nd.root.dentry = dentry;
2349+
2350+ flags |= LOOKUP_ROOT;
2351+
2352+ if (dentry->d_inode->i_op->follow_link)
2353+ return ERR_PTR(-ELOOP);
2354+
2355+ file = path_openat(-1, name, &nd, op, flags | LOOKUP_RCU);
2356+ if (unlikely(file == ERR_PTR(-ECHILD)))
2357+ file = path_openat(-1, name, &nd, op, flags);
2358+ if (unlikely(file == ERR_PTR(-ESTALE)))
2359+ file = path_openat(-1, name, &nd, op, flags | LOOKUP_REVAL);
2360+ return file;
2361+}
2362+
23392363 /**
23402364 * lookup_create - lookup a dentry, creating it if it doesn't exist
23412365 * @nd: nameidata info
fs/nfsctl.c+4−17
@@ -22,30 +22,17 @@ · 21 unmodified lines
2222
2323 static struct file *do_open(char *name, int flags)
2424 {
25− struct nameidata nd;
2625 struct vfsmount *mnt;
27− int error;
26+ struct file *file;
2827
2928 mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
3029 if (IS_ERR(mnt))
3130 return (struct file *)mnt;
3231
33− error = vfs_path_lookup(mnt->mnt_root, mnt, name, 0, &nd);
34− mntput(mnt); /* drop do_kern_mount reference */
35− if (error)
36− return ERR_PTR(error);
37−
38− if (flags == O_RDWR)
39− error = may_open(&nd.path, MAY_READ|MAY_WRITE, flags);
40− else
41− error = may_open(&nd.path, MAY_WRITE, flags);
32+ file = file_open_root(mnt->mnt_root, mnt, name, flags);
4233
43− if (!error)
44− return dentry_open(nd.path.dentry, nd.path.mnt, flags,
45− current_cred());
46−
47− path_put(&nd.path);
48− return ERR_PTR(error);
34+ mntput(mnt); /* drop do_kern_mount reference */
35+ return file;
4936 }
5037
5138 static struct {
fs/open.c+14−0
@@ -959,6 +959,20 @@ struct file *filp_open(const char *filename, int flags, int mode) · 958 unmodified lines
959959 }
960960 EXPORT_SYMBOL(filp_open);
961961
962+struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
963+ const char *filename, int flags)
964+{
965+ struct open_flags op;
966+ int lookup = build_open_flags(flags, 0, &op);
967+ if (flags & O_CREAT)
968+ return ERR_PTR(-EINVAL);
969+ if (!filename && (flags & O_DIRECTORY))
970+ if (!dentry->d_inode->i_op->lookup)
971+ return ERR_PTR(-ENOTDIR);
972+ return do_file_open_root(dentry, mnt, filename, &op, lookup);
973+}
974+EXPORT_SYMBOL(file_open_root);
975+
962976 long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
963977 {
964978 struct open_flags op;
include/linux/fs.h+2−2
@@ -1990,6 +1990,8 @@ extern int do_fallocate(struct file *file, int mode, loff_t offset, · 1989 unmodified lines
19901990 extern long do_sys_open(int dfd, const char __user *filename, int flags,
19911991 int mode);
19921992 extern struct file *filp_open(const char *, int, int);
1993+extern struct file *file_open_root(struct dentry *, struct vfsmount *,
1994+ const char *, int);
19931995 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
19941996 const struct cred *);
19951997 extern int filp_close(struct file *, fl_owner_t id);
@@ -2205,8 +2207,6 @@ extern struct file *create_read_pipe(struct file *f, int flags); · 209 unmodified lines
22052207 extern struct file *create_write_pipe(int flags);
22062208 extern void free_write_pipe(struct file *);
22072209
2208−extern int may_open(struct path *, int, int);
2209−
22102210 extern int kernel_read(struct file *, loff_t, char *, unsigned long);
22112211 extern struct file * open_exec(const char *);
22122212
kernel/sysctl_binary.c+1−18
@@ -1321,13 +1321,11 @@ static ssize_t binary_sysctl(const int *name, int nlen, · 1320 unmodified lines
13211321 void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
13221322 {
13231323 const struct bin_table *table = NULL;
1324− struct nameidata nd;
13251324 struct vfsmount *mnt;
13261325 struct file *file;
13271326 ssize_t result;
13281327 char *pathname;
13291328 int flags;
1330− int acc_mode;
13311329
13321330 pathname = sysctl_getname(name, nlen, &table);
13331331 result = PTR_ERR(pathname);
@@ -1337,28 +1335,17 @@ static ssize_t binary_sysctl(const int *name, int nlen, · 3 unmodified lines
13371335 /* How should the sysctl be accessed? */
13381336 if (oldval && oldlen && newval && newlen) {
13391337 flags = O_RDWR;
1340− acc_mode = MAY_READ | MAY_WRITE;
13411338 } else if (newval && newlen) {
13421339 flags = O_WRONLY;
1343− acc_mode = MAY_WRITE;
13441340 } else if (oldval && oldlen) {
13451341 flags = O_RDONLY;
1346− acc_mode = MAY_READ;
13471342 } else {
13481343 result = 0;
13491344 goto out_putname;
13501345 }
13511346
13521347 mnt = current->nsproxy->pid_ns->proc_mnt;
1353− result = vfs_path_lookup(mnt->mnt_root, mnt, pathname, 0, &nd);
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());
1348+ file = file_open_root(mnt->mnt_root, mnt, pathname, flags);
13621349 result = PTR_ERR(file);
13631350 if (IS_ERR(file))
13641351 goto out_putname;
@@ -1370,10 +1357,6 @@ out_putname: · 5 unmodified lines
13701357 putname(pathname);
13711358 out:
13721359 return result;
1373−
1374−out_putpath:
1375− path_put(&nd.path);
1376− goto out_putname;
13771360 }
13781361
13791362

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t