#include #include #include #include #include #include /* * get_device- Common code to pull the device name, if any, off the front of a * path and choose the inode to begin the name lookup relative to. */ static int get_device(char *path, char **subpath, struct inode **node_store) { int i, slash = -1, colon = -1; for (i = 0; path[i] != '\0'; i ++) { if (path[i] == ':') { colon = i; break; } if (path[i] == '/') { slash = i; break; } } if (colon < 0 && slash != 0) { /* * * No colon before a slash, so no device name specified, and the slash isn't leading * or is also absent, so this is a relative path or just a bare filename. Start from * the current directory, and use the whole thing as the subpath. * */ *subpath = path; return vfs_get_curdir(node_store); } if (colon > 0) { /* device:path - get root of device's filesystem */ path[colon] = '\0'; /* device:/path - skip slash, treat as device:path */ while (path[++ colon] == '/'); *subpath = path + colon; return vfs_get_root(path, node_store); } /* * * we have either /path or :path * /path is a path relative to the root of the "boot filesystem" * :path is a path relative to the root of the current filesystem * */ int ret; if (*path == '/') { if ((ret = vfs_get_bootfs(node_store)) != 0) { return ret; } } else { assert(*path == ':'); struct inode *node; if ((ret = vfs_get_curdir(&node)) != 0) { return ret; } /* The current directory may not be a device, so it must have a fs. */ assert(node->in_fs != NULL); *node_store = fsop_get_root(node->in_fs); vop_ref_dec(node); } /* ///... or :/... */ while (*(++ path) == '/'); *subpath = path; return 0; } /* * vfs_lookup - get the inode according to the path filename */ int vfs_lookup(char *path, struct inode **node_store) { int ret; struct inode *node; if ((ret = get_device(path, &path, &node)) != 0) { return ret; } if (*path != '\0') { ret = vop_lookup(node, path, node_store); vop_ref_dec(node); return ret; } *node_store = node; return 0; } /* * vfs_lookup_parent - Name-to-vnode translation. * (In BSD, both of these are subsumed by namei().) */ int vfs_lookup_parent(char *path, struct inode **node_store, char **endp){ int ret; struct inode *node; if ((ret = get_device(path, &path, &node)) != 0) { return ret; } *endp = path; *node_store = node; return 0; }