Section 14.9. Path-Name Management


14.9. Path-Name Management

All but a few of the vnode methods operate on vnode pointers rather than on path names. Before calling file system vnode methods, the vnode framework first converts path names and file descriptors into vnode references. File descriptors may be directly translated into vnodes for the files they referenced, whereas path names must be converted into vnodes by a lookup of the path-name components and a reference to the underlying file. The file-system-independent lookuppn() function converts path names to vnodes. An additional wrapper, lookupname(), converts path names from user-mode system calls.

14.9.1. The lookuppn() Method

Given a path name, the lookuppn() method attempts to return a pointer to the vnode the path represents. If the vnode is already available, then a new reference to the vnode is established. If no vnode is available, one is created. The lookuppn() function decomposes the components of the path name, separating them by "/" and ".", and calls the file-system-specific vop_lookup() method (see below) for each component of the path name.

If the path name begins with a "/", path-name traversal starts at the user's root directory. Otherwise, it starts at the vnode pointed to by the user's current directory. lookuppn() TRaverses the path one component at a time, using the vop_lookup() vnode method.

If a directory vnode has v_vfsmountedhere set, then it is a mount point. If lookuppn() encounters a mount point while going down the file system tree, then it follows the vnode's v_vfsmountedhere pointer to the mounted file system and calls the vfs_root() method to obtain the root vnode for the file system. Pathname traversal then continues from this point.

If lookuppn() encounters a root vnode (VROOT flag in v_flag set) when following "..", then lookuppn() follows the vfs_vnodecovered pointer in the vnode's associated vfs to obtain the covered vnode.

If lookuppn() encounters a symbolic link, then it calls the vn_readlink() vnode method to obtain the symbolic link. If the symbolic link begins with a "/", the path-name traversal is restarted from the root directory; otherwise, the traversal continues from the last directory. The caller of lookuppn() specifies whether the last component of the path name is to be followed if it is a symbolic link.

This procedure continues until the path name is exhausted or an error occurs. When lookuppn() completes, it returns a vnode representing the desired file.

14.9.2. The vop_lookup() Method

The vop_lookup() method searches a directory for a path-name component matching the supplied path name. The vop_lookup() method accepts a directory vnode and a string path-name component as an argument and returns a vnode pointer to the vnode representing the file. If the file cannot be located, then ENOENT is returned.

Many regular file systems will first check the directory name lookup cache, and if an entry is found there, the entry is returned. If the entry is not found in the directory name cache, then a real lookup of the file is performed.

14.9.3. The vop_readdir() Method

The vop_readdir() method reads chunks of the directory into a uio structure. Each chunk can contain as many entries as will fit within the size supplied by the uio structure. The uio_resid structure member shows the size of the getdents request in bytes, which is divided by the size of the directory entry made by the vop_readdir() method to calculate how many directory entries to return.

Directories are read from disk with the buffered kernel file functions fbread and fbwrite. These functions, described below, are provided as part of the generic file system infrastructure.

/*  * A struct fbuf is used to get a mapping to part of a file using the  * segkmap facilities.  After you get a mapping, you can fbrelse() it  * (giving a seg code to pass back to segmap_release), you can fbwrite()  * it (causes a synchronous write back using the file mapping information),  * or you can fbiwrite it (causing indirect synchronous write back to  * the block number given without using the file mapping information).  */ struct fbuf {         caddr_t fb_addr;         uint_t  fb_count; }; extern int fbread(struct vnode *, offset_t, uint_t, enum seg_rw, struct fbuf **); Returns a pointer to locked kernel virtual address for the given <vp, off> for len bytes. The read may not cross a boundary of MAXBSIZE (8192) bytes. extern void fbzero(struct vnode *, offset_t, uint_t, struct fbuf **); Similar to fbread(), but calls segmap_pagecreate(), not segmap_fault(), so that SOFTLOCK can create the pages without using VOP_GETPAGE(). Then, fbzero() zeroes up to the length rounded to a page boundary. extern int fbwrite(struct fbuf *); Direct write. extern int fbiwrite(struct fbuf *, struct vnode *, daddr_t bn, int bsize); Writes directly and invalidates pages. extern int fbdwrite(struct fbuf *); Delayed write. extern void fbrelse(struct fbuf *, enum seg_rw); Releases fbp.                                                       See usr/src/uts/common/sys/fbuf.h 


14.9.4. Path-Name Traversal Functions

Several path-name manipulation functions assist with decomposition of path names. The path-name functions use a path-name structure, shown below, to pass around path-name components.

/*  * Pathname structure.  * System calls that operate on path names gather the path name  * from the system call into this structure and reduce it by  * peeling off translated components.  If a symbolic link is  * encountered the new path name to be translated is also  * assembled in this structure.  *  * By convention pn_buf is not changed once it's been set to point  * to the underlying storage; routines which manipulate the path name  * do so by changing pn_path and pn_pathlen.  pn_pathlen is redundant  * since the path name is null-terminated, but is provided to make  * some computations faster.  */ typedef struct pathname {         char    *pn_buf;                 /* underlying storage */         char    *pn_path;                /* remaining pathname */         size_t  pn_pathlen;              /* remaining length */         size_t  pn_bufsize;              /* total size of pn_buf */ } pathname_t;                                                   See usr/src/uts/common/sys/pathname.h 


The path-name functions are shown below.

void pn_alloc(struct pathname *pnp); Allocates a new path-name buffer.Structure is typically an automatic variable in calling routine for convenience.May sleep in the call to kmem_alloc() and so must not be called from interrupt level. int pn_get(char *str, enum uio_seg seg, struct pathname *pnp); Copies path-name string from user and mounts arguments into a struct path name. int pn_set(struct pathname *pnp, char *path); Sets a path name to the supplied string. int pn_insert(struct pathname *pnp, struct pathname *sympnp, size_t complen); Combines two argument path names by putting the second argument before the first in the first's buffer.  This isn't very general; it is designed specifically for symbolic link processing. This function copies the symlink in-place in the path name.  This is to ensure that vnode path caching remains correct.  At the point where this is called (from lookuppnvp), we have called pn_getcomponent(), found it is a symlink, and are now replacing the contents.  The complen parameter indicates how much of the path name to replace. If the symlink is an absolute path, then we overwrite the entire contents of the pathname. int pn_getsymlink(vnode_t *vp, struct pathname *pnp, cred_t *crp); Follows a symbolic link for a path name. int pn_getcomponent(struct pathname *pnp, char *component); Extracts the next delimited path-name component. void pn_setlast(struct pathname *pnp); Sets pn_path to the last component in the path name, updating pn_pathlen.  If pathname is empty or degenerate, leaves pn_path pointing at NULL char.The path name is explicitly null-terminated so that any trailing slashes are effectively removed. void pn_skipslash(struct pathname *pnp); Skips over consecutive slashes in the path name. int pn_fixslash(struct pathname *pnp); Eliminates any trailing slashes in the path name. int pn_addslash(struct pathname *pnp); Add sa slash to the end of the path name, if it will fit.Return ENAMETOOLONG if it won't. void pn_free(struct pathname *pnp); Frees a struct path name.                                                   See usr/src/uts/common/sys/pathname.h 





SolarisT Internals. Solaris 10 and OpenSolaris Kernel Architecture
Solaris Internals: Solaris 10 and OpenSolaris Kernel Architecture (2nd Edition)
ISBN: 0131482092
EAN: 2147483647
Year: 2004
Pages: 244

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net