“u.u_cdir” defines the “inode” of a process’s current directory. A process inherits its parent’s current directory at birth (“newproc”, 1883). The current directory may be changed using the “chdir” (3538) system call;
Note that “func” is a parameter to “namei” and is always either “uchar” (7689) or “schar” (7679);
“iget” (7276) is called to:
wait until such time as the “inode” corresponding to “dp” is no longer locked;
check that the associated file system is still mounted;
increment the reference count;
lock the “inode”;
Multiple slashes are acceptable! (i.e.
“////a///b/” is the same as “/a/b”);
Any attempt to replace or delete the current working directory or the root directory is bounced immediately!
The label “cloop” marks the beginning of a program loop that extends to line 7667. Each cycle analyses a component of the pathname (i.e. a string terminated by a null character or one or more slashes). Note that a name may be constructed from many different characters (7571);
The end of the pathname has been reached (successfully). Return the current value of “dp”;
“search” permission for directories is coded in the same way as “execute” permission for other files;
Copy the name into a more accessible location before attempting to match it with a directory entry. Note that a name of greater than “DIRSIZ” characters is truncated;
“u.u_count” is set to the number of entries in the directory;
The label “eloop” marks the beginning of a program loop which extends to line 7647. Each cycle of the loop handles a single directory entry;
If the directory has been searched (linearly!) without matching the supplied pathname component, then there must be an error unless:
this is the last component of the pathname, i.e. “c==‘\0’ ”;
the file is to be created, i.e. “flag == 1”; ard
the user program has “write” permission for the directory;
Record the “inode” address for the directory for the new file in “u.u_pdir”;
If a suitable slot for a new directory entry has previously been encountered (7642), store the value in “u.u_offset[1]”; else set the “IUPD” fIag for the “dp” designated “inode” (but why?);
When appropriate, read a new block from the directory file (note the use of “bread”) (why not “breada”?), after carefully releasing any previously held buffer;
Copy the eight words of the directory entry into the array “u.u_dent”. The reason for copying before comparing is obscure! Can this actually be more efficient? (The reason for copying the whole directory at all is rather perplexing to the author of these notes.);
This comparison makes efficient use of a single character pointer register variable, “cp”. The loop would be even more efficient if word by word comparison were used;
The “eloop” cycle is terminated by one of:
return(NULL); (7610) goto out; (7605, 7613)
a successful match so that the branch to “eloop” (7647) is not taken;
If the name is to be deleted (“flag==2”), if the pathname has been completed, and if the user program has “write” access to the directory, then return a pointer to the directory “inode”;
Save the device identity temporarily (why not in the register “c”?) and call “iput” (7344) to unlock “dp”, to decrement the reference count on “dp” and to perform any consequent processlng;
Revalidate “dp” to point to the “inode” for the next level file;
“dp==NULL” shouldn’t happen, since the directory says the file exists! However “inode” table overflows and i/o errors can occur, and sometimes the file system may be left in an inconsistent state after a system crash.