;;; -*- Mode: Lisp; Package: File-System; Base: 10.; Readtable: T -*- ;;; Hooks into the guts of the filesystem (functions could be in fsguts) ;;; to make a faster NFS server after SUN microsystems. ;;; 8-Feb-87 18:14:08 -GJC ;;; problems: ;;; We must have a unique 32-byte string called a FILE-HANDLE ;;; for each file. In a Unix implementation this could be ;;; the disk device,inode-number,inode-generation-number. ;;; Even if the full filename could fit into 32-bytes this would ;;; not be a sufficient handle because it wouldnt cover the case ;;; of a file being created, deleted, then created again. ;;; This is considered a different file. ;;; We must be able to very quickly go from a FILE-HANDLE to an internal ;;; file object. ;;; The SERVER implementation does not depend then on lispmachine pathname ;;; manipulation. These functions server to bypass the usual pathname, access, ;;; and open and stream mechanisms. ;;; File Attributes: ;;; Directoryp, Protection/Mode, User-ID, Group-ID, SIZE, BLOCKSIZE, BLOCKS, FILEID, ;;; Access-Time, Modify-Time, Creation-Time. ;;; (what is FILEID used for?, a directory list consists of a filenames and fileids). ;;; Access-Time is not supported in FSGUTS. Group and User ID's could be generated ;;; from author by require using other SUN facilities such as yellow pages. ;;; Protection, Symbolic links, etc could me implemented using file properties. ;;; Hooks. Data returned should be lispmachine standard as possible. ;;; Dates universal time etc. ;;; (NFS-MOUNT-POINTS), returns a list of 's. It will be the responsibility of ;;; the MOUNT server to get the file handles and unix-style names of these. ;;; ;;; (NFS-FILEHANDLE->FILE ) returns NIL or a FILE. ;;; (NFS-FILE->FILEHANDLE ) => a handle. ;;; ;;; (NFS-FILE-DIRECTORY-P ) ;;; (NFS-FILE-AUTHOR ) ;;; (NFS-FILE-SIZE ) ;;; (NFS-FILE-CREATION-DATE ) ;;; (NFS-FILE-PROPERTY ) ;;; (NFS-FILE-NAME ) ;;; (NFS-FILE-TYPE ) ;;; (NFS-FILE-VERSION ) ;;; (NFS-FILE-DIRECTORY ) ;;; ;;; ;;; (NFS-FILE-SYSTEM-STATUS ) => info on blocks free, available. like LISTF prints out. ;;; ;;; (NFS-FILE-DIRECTORY-LIST ) => list of files. ;;; Calling on not a directory is an error. The server code ;;; would check NFS-FILE-DIRECTORY-P first in order to signal an informative error to the client. ;;; It will be the responsibility of the server to map names, such as foo.directory to foo. ;;; ;;; Note: there is no (NFS-FILE-LOOKUP ) because the server can do this ;;; just about as well by looking through the (NFS-FILE-DIRECTORY-LIST ). ;;; In any case if there were such a lookup it would take . ;;; ;;; (NFS-FILE-STRING-READ ) ;;; (NFS-FILE-STRING-WRITE ) ;;; ;;; ;;; (NFS-FILE-CREATE "NAME" "TYPE" "VERSION") => ( ) ;;; Adds a file to a directory . ;;; (NFS-DIRECTORY-CREATE "NAME") => ( ) ;;; Creates a directory "NAME" ;;; ;;; (NFS-FILE-DELETE ) ;;; Extra data structures involved: ;;; Must have a database which we could keep in a file. ;;; "" ;;; Directory creation sequence number. ;;; File Creation Sequence number. ;;; Our database allows us to map the DCSN of a directory very quickly ;;; after reboot without having to map over the whole file system. ;;; Once we have the directory we can list the files and linear search. ;;; We use a cache of DCSN for directories that gives the for ;;; the directory and also a hash table for further lookup. ;;; The all important NFS-FILEHANDLE->FILE operation is then in most cases but ;;; two GETHASH operations on two relatively small tables. ;;; * all file deletion needs to invalidate this cache. ;;; * all directory creation/deletion must update the cache and write the database to disk. ;;; Regular file creation by other lispmachine functions do not need to do anything ;;; special. The NFS-DIRECTORY-LIST (when reading :DISK) or NFS-FILE->FILEHANDLE ;;; can make sure a number is assigned. The FCSN can then be a number unique ;;; in the directory, not globally. The current max FCSN can then be easily ;;; stored in the directory-header. Keeping the FCSN as part of a new entry ;;; spec rather than a property has advantages of space and keeping it hidden ;;; (and unmodifiable) by the user :SET-PROPERTIES. ;;; Keeping the DCSN database hidden means we cannot keep it as a regular file in the root ;;; directory (for example). Is it the kind of thing one would want to backup? ;;; Hmmm. Lets keep it in a special directory NFS-DCSN; ;;; And since directory creation is infrequent enough we can afford ;;; to write it as NFS-DCSN;DATABASE.LISP#>. With sufficient warning about ;;; not editing by hand. ;;; ;;; (CREATE-NFS-DCSN-DATABASE) will map over the entire file system to create ;;; this database for the first time. Really it is just a way to flatten the ;;; file system into, (1 "GJC") (2 "GJC" "FOO") (3 "BAR") to make directory lookup ;;; fast. ;;; ;;; READ/WRITE. ;;; Being able to use existing stream access, need to keep open files. ;;; No indication of when to close them, so need a background process to do ;;; this. ;;; READ could do a direct disk read. But, could be inefficient to read ;;; small chunks like that. Same with write. ;;; Have a cache of disk block numbers and data, with background process ;;; to flush? ;;; need to patch defstruct of FILE, create-new-directory, create-new-file, read-directory-entry ;;; (DEFVAR *NFS-DCSN-DATABASE-FILE* "LM:NFS-DCSN;DATEBASE.QFASL#>") (DEFVAR *NFS-DCSN-DATABASE* NIL) (DEFVAR *NFS-DCSN-DATABASE-LOCK* NIL) (DEFUN GIVE-FILE-GENERATION-NUMBER (FILE) (COND ((DIRECTORY? FILE) (WHEN (NOT (EQ T *NFS-DCSN-DATABASE*)) (WITH-LOCK (*NFS-DCSN-DATABASE-LOCK*) (WHEN (NULL *NFS-DCSN-DATABASE*) (CONDITION-CASE () (OPEN *NFS-DCSN-DATABASE-FILE* :DIRECTION NIL) (FILE-NOT-FOUND (RETURN-FROM GIVE-FILE-GENERATION-NUMBER NIL)) (DIRECTORY-NOT-FOUND (RETURN-FROM GIVE-FILE-GENERATION-NUMBER NIL))))))) ('ELSE (LET ((DIRECTORY (FILE-DIRECTORY FILE))) (REQUIRE-LOCK (DIRECTORY-LOCK DIRECTORY)) (OR (FILE-ATTRIBUTE DIRECTORY :HEADER-BLOCK) (WRITE-DIRECTORY-FILES DIRECTORY)) (LET ((H (GETF (FILE-PLIST DIRECTORY) '%HEADER-INTERNAL))) (SETF (FILE-GENERATION-NUMBER FILE) (SETF (DIRHEADER-FLAG-GENERATION-COUNT H) (1+ (DIRHEADER-FLAG-GENERATION-COUNT H)))))))))