anchor.diff:    `(mezzano.supervisor:with-mutex ((fat32-host-lock ,host))
        ,@body))
   
  -(defun read-dir-from-pathname (host pathname)
  -  (loop
  -     with disk = (partition host)
  -     with fat32 = (fat32-structure host)
  -     for dir-name on (pathname-directory pathname)
  -     for dir =
  -       (cond
  -         ;; Read root dir
  -         ((eql :absolute (car dir-name))
  -          (mezzano.fat32-file-system:read-dir-from-cluster
  -           (mezzano.fat32-file-system:read-cluster
  -            fat32 disk
  -            (mezzano.fat32-file-system::first-root-dir-sector fat32))
  -           fat32))
  -         ;; Travel path
  -         (t (loop
  -               for file in dir
  -               when (string= (car dir-name) (virtual-dir-name file))
  -               do (return (read-dir-from-file (fat32-structure host)
  -                                              (partition host)
  -                                              file))
  -               finally
  -                 (:error (error 'simple-file-error
  -                                :pathname pathname
  -                                :format-control "Directory ~S does not exist. ~S"
  -                                :format-arguments (list (car dir-name) pathname))))))
  -     ;; Returt all files and subdirectories in dir
  -     finally (return dir)))
  -
  -;; WIP Don't require to load entire file
  -;; TODO Add write suport
  +(defmethod delete-file-using-host ((host fat32-host) path &key)
  +  (let* ((disk (partition host))
  +         (fat32 (fat32-structure host)))
  +    (multiple-value-bind (cluster cluster-sector start) (find-file host path)
  +      (remove-file cluster
  +                   start
  +                   disk
  +                   cluster-sector
  +                   fat32))))
  +
  +(defun write-file-size (stream)
  +  (let* ((host (host stream))
  +         (path (file-stream-pathname stream))
  +         (file-length (read-buffer-size stream))
  +         (disk (partition host))
  +         (fat32 (fat32-structure host)))
  +    (multiple-value-bind (cluster cluster-sector offset) (find-file host path)
  +      (when offset
  +        (setf (aref cluster (+ 28 offset)) (ldb (byte 8 0) file-length)
  +              (aref cluster (+ 29 offset)) (ldb (byte 8 8) file-length)
  +              (aref cluster (+ 30 offset)) (ldb (byte 8 16) file-length)
  +              (aref cluster (+ 31 offset)) (ldb (byte 8 24) file-length))
  +
  +        (write-cluster disk
  +                       cluster-sector
  +                       fat32
  +                       cluster)))))
  +
  +(defun file-name (path)
  +  "Return file name"
  +  (unless (or (eql :wild (pathname-name path))
  +              (eql :wild (pathname-type path)))
  +    (if (pathname-type path)
  +        (concatenate 'string (pathname-name path) "." (pathname-type path))
  +        (pathname-name path))))
  +
  +(defun find-file (host pathname)
  +  (loop :with fat32 := (fat32-structure host)
  +        :with disk := (partition host)
  +        :with file-name := (file-name pathname)
  +        :with cluster-sector := (first-root-dir-sector fat32)
  +        :with cluster := (read-cluster fat32 disk cluster-sector)
  +        :for file :in (rest (pathname-directory pathname))
  +        :do (do-files (start) cluster
  +              (when (string= file (read-long-name cluster start))
  +                (let ((sector (first-sector-of-cluster fat32
  +                                                       (read-first-cluster cluster start))))
  +                  (setf cluster
  +                        (read-cluster fat32 disk
  +                                      sector)))))
  +        :finally (do-files (start) cluster
  +                   (when (string= file-name (read-long-name cluster start))
  +                     (return-from find-file (values cluster cluster-sector start))))))
  +
  +;; WIP
   (defmethod open-using-host ((host fat32-host) pathname
                               &key direction element-type if-exists if-does-not-exist external-format)
  -
     (with-fat32-host-locked (host)
       (let ((buffer nil)
             (read-buffer-position 0)
  -          (read-buffer-size 0))
  -
  -      (when (member direction '(:output :io))
  -        (error "Feature not implemented: ~a, ~a" ':output ':io))
  -      
  -      (loop
  -         with file-name = (concatenate 'string (pathname-name pathname)
  -                                       "." (pathname-type pathname))
  -         for file in (read-dir-from-pathname host pathname)
  -         when (string= file-name (virtual-dir-name file))
  -         do (progn
  -              (setf buffer (mezzano.fat32-file-system:read-file file (partition host)
  -                                                                (fat32-structure host))
  -                    read-buffer-position (* (fat32-bytes-per-sector (fat32-structure host))
  -                                            (virtual-dir-first-cluster file))
  -                    read-buffer-size (virtual-dir-file-size file))
  -              (return))
  -         finally
  -           (ecase if-does-not-exist
  -             (:error (error 'simple-file-error
  -                            :pathname pathname
  -                            :format-control "File ~A does not exist. ~S"
  -                            :format-arguments (list pathname file-name)))
  -             (:create (error "Feature :create not implemented for :if-does-not-exist"))))
  -
  +          (buffer-offset 0)
  +          (read-buffer-size 0)
  +          (created-file nil)
  +          (abort-action nil))
  +
  +      (multiple-value-bind (cluster cluster-sector start) (find-file host pathname)
  +        (if start
  +            (progn (setf buffer (read-file (fat32-structure host)
  +                                           (partition host)
  +                                           cluster
  +                                           start)
  +                         read-buffer-position (first-sector-of-cluster (fat32-structure host)
  +                                                                       (read-first-cluster cluster start))
  +                         read-buffer-size (read-size cluster start)))
  +            (ecase if-does-not-exist
  +              (:error (error 'simple-file-error
  +                             :pathname pathname
  +                             :format-control "File ~A does not exist. ~S"
  +                             :format-arguments (list pathname (pathname-name pathname))))
  +              (:create (setf created-file t
  +                             abort-action :delete)
  +               (error "Feature :create not implemented for :if-does-not-exist")))))
  +
  +      (when (and (not created-file) (member direction '(:output :io)))
  +        (ecase if-exists
  +          (:error (error 'simple-file-error
  +                         :pathname pathname
  +                         :format-control "File ~A exists."
  +                         :format-arguments (list pathname)))
  +          ((:new-version
  +            :rename
  +            :rename-and-delete)
  +           (when t
  +             (error 'simple-file-error
  +                    :pathname pathname
  +                    :format-control "Could not rename ~S."
  +                    :format-arguments (list pathname)))
  +           (when t
  +             (error 'simple-file-error
  +                    :pathname pathname
  +                    :format-control "Could not supersede ~S."
  +                    :format-arguments (list pathname)))
  +           (when created-file
  +             (error "Cannot create ~A. ~S" pathname)))
  +          (:supersede
  +           (setf abort-action :delete)
  +           (when nil
  +             (error 'simple-file-error
  +                    :pathname pathname
  +                    :format-control "Could not supersede ~S."
  +                    :format-arguments (list pathname)))
  +           (unless created-file
  +             (error "Cannot create ~A. ~S" pathname)))
  +          ((:overwrite) t)
  +          ((:append)
  +           (setf buffer-offset read-buffer-size))
  +          ((nil) (return-from open-using-host nil))))
         (let ((stream (cond ((or (eql element-type :default)
                                  (subtypep element-type 'character))
                              (assert (member external-format '(:default :utf-8))
                                      (external-format))
                              (make-instance 'fat32-file-character-stream
  +                                          :pathname pathname
  +                                          :host host
                                             :direction direction
                                             :read-buffer buffer
                                             :read-buffer-position read-buffer-position
  +                                          :buffer-offset buffer-offset
                                             :read-buffer-size read-buffer-size))
                             ((and (subtypep element-type '(unsigned-byte 8))
                                   (subtypep '(unsigned-byte 8) element-type))
                              (assert (eql external-format :default) (external-format))
                              (make-instance 'fat32-file-stream
  +                                          :pathname pathname
  +                                          :host host
                                             :direction direction
                                             :read-buffer buffer
                                             :read-buffer-position read-buffer-position
  +                                          :buffer-offset buffer-offset
                                             :read-buffer-size read-buffer-size))
                             (t (error "Unsupported element-type ~S." element-type)))))
           stream))))
   
   (defmethod directory-using-host ((host fat32-host) pathname &key)
  -  (loop
  -     for file in (read-dir-from-pathname host pathname)
  -     unless (or (string= "." (virtual-dir-name file))
  -                (string= ".." (virtual-dir-name file)))
  -     collecting
  -       (parse-simple-file-path host
  -                               (format nil
  -                                       (if (file-p file)
  -                                           "~a~a"
  -                                           "~a~a>")
  -                                       (unparse-pathname-directory pathname host)
  -                                       (virtual-dir-name file)))))
  -
  +  (let ((cluster (find-file host pathname)))
  +    (let (stack '())
  +      (do-files (file) cluster
  +        (push
  +         (parse-simple-file-path host
  +                                 (format nil
  +                                         (if (file-p cluster file)
  +                                             "~a~a"
  +                                             "~a~a>")
  +                                         (unparse-pathname-directory pathname host)
  +                                         (read-long-name cluster file)))
  +         stack))
  +      (return-from directory-using-host stack))))
  +
  +;; WIP
   (defmethod ensure-directories-exist-using-host ((host fat32-host) pathname &key verbose)
     (error "Feature not implemented: ~a" 'ensure-directories-exist-using-host))
   
  +;; WIP
   (defmethod rename-file-using-host ((host fat32-host) source dest)
     (error "Feature not implemented: ~a" 'rename-file-using-host))
   
  +;; WIP
   (defmethod file-write-date-using-host ((host fat32-host) path)
  -  (loop
  -     with file-name = (concatenate 'string (pathname-name path)
  -                                   "." (pathname-type path))
  -     for file in (read-dir-from-pathname host path)
  -     when (string= file-name (virtual-dir-name file))
  -     do (multiple-value-bind (second minute hour) (decode-time (virtual-dir-write-time file))
  -          (multiple-value-bind (day month year) (decode-date (virtual-dir-write-date file))
  -            (return (encode-universal-time second minute hour day month year))))))
  +  (error "Feature not implemented: ~a" 'file-write-date-using-host))
   
   (defmethod delete-file-using-host ((host fat32-host) path &key)
  -  (error "Feature not implemented: ~a" 'delete-file-using-host))
  +  (let* ((disk (partition host))
  +         (fat32 (fat32-structure host)))
  +    (multiple-value-bind (cluster cluster-sector start) (find-file host path)
  +      (remove-file cluster
  +                   start
  +                   disk
  +                   cluster-sector
  +                   fat32))))
   
   (defmethod expunge-directory-using-host ((host fat32-host) path &key)
  -  (error "Feature not implemented: ~a" 'expunge-directory-using-host))
  -
  +  (declare (ignore host path))
  +  t)
  +
  +;; Sort name eql truename?
   (defmethod stream-truename ((stream fat32-file-stream))
     (file-stream-pathname stream))
   
  
positive.code:             (write-string type s)))
        s)))
  
  (defmethod unparse-pathname (pathname (host fat32-host))
    (unparse-simple-file-path pathname))
  
  (defmethod unparse-pathname-file (pathname (host fat32-host))
    (let ((name (pathname-name pathname))
          (type (pathname-type pathname)))
      (when name
        (with-output-to-string (s)
          (write-string name s)
          (when type
            (write-char #\. s)
            (write-string type s))))))
  
  (defmethod unparse-pathname-directory (pathname (host fat32-host))
    (let ((dir (pathname-directory pathname)))
      (with-output-to-string (s)
        (when (eql (first dir) :absolute)
          (write-char #\> s))
        (dolist (d (rest dir))
          (cond
            ((stringp d) (write-string d s))
            ((eql d :up) (write-string ".." s))
            ((eql d :wild) (write-char #\* s))
            ((eql d :wild-inferiors) (write-string "**" s))
            (t (error "Invalid directory component ~S." d)))
          (write-char #\> s)))))
  
  (defclass fat32-file-stream (sys.gray:fundamental-binary-input-stream
                               sys.gray:fundamental-binary-output-stream
                               file-stream)
    ((path :initarg :path :reader path)
     (pathname :initarg :pathname :reader file-stream-pathname)
     (host :initarg :host :reader host)
     (direction :initarg :direction :reader direction)
  
negative.code: (defun check-bytes-per-sector (bytes-per-sector)
    "Ensure that bytes-per-sector is valid."
    (loop :for n :in '(512 1024 2048 4096)
          :do (when (= n bytes-per-sector)
                (return bytes-per-sector))
          :finally (error "Bad bytes-per-sector : ~a .
  Valid bytes-per-sector are 512, 1024, 2048 and 4096" bytes-per-sector)))
  
  (defun check-sectors-per-cluster (sectors-per-cluster bytes-per-sector)
    (loop :for n :in '(1 2 4 8 16 32 64 128)
          :do (when (= n sectors-per-cluster)
                (return sectors-per-cluster))
          :finally (error "Bad sectors-per-cluster : ~a .
  Valid bytes-per-sector are 1,2,4,8,16,32,64,128" sectors-per-cluster))
    (when (> (* sectors-per-cluster bytes-per-sector)
             32768)
  