              <<< VAXAXP::NOTES$:[NOTES$LIBRARY]VMSNOTES.NOTE;1 >>>
               -< VAX and Alpha VMS - Digital Internal Use Only >-
================================================================================
Note 223.4       VMS directory, how to repair or perhaps delete?         4 of 20
GIDDAY::GILLINGS "a crucible of informative mistak" 156 lines  31-JAN-1995 23:53
                             -< As it happens.... >-
--------------------------------------------------------------------------------
  Having had a run on calls with this problem recently, I've done a bit of 
  investigating. The problem is that the directory has a backlink that
  points to itself. The file is inaccessible as it's not in any accessible
  directory tree. Every instance I've ever seen (about 10 now) has been
  associated with Pathworks file services on the disk in question. By,
  coincidence one of the Pathworks people here recently discovered that
  an attempt from DOS to copy a directory into itself, for example:

  F:\ADIR> MOVE *.* SUBDIR

  where SUBDIR is a subdirectory of ADIR

  will fail when the file is on a DOS disk, but will succeed if the directory
  is a file service on a VMS system. The result is that the directory and any
  files contained within it simply vanish. Now we know where they're going!

  VMS disallows this operation from DCL (it gets -RMS-E-IDR, invalid directory
  rename operation) so I suspect that each operating system is expecting the
  other to perform the check. 

  The good news - apparently ANALYZE/DISK in a subsequent version of VMS
  (Zeta??) will recognise this error and be able to fix it. The problem is
  also resolved in 4.2-1 ECO 6 of Pathworks for VMS file server which 
  (so I'm told) dumplicates the normal DOS behaviour.

  To diagnose the problem, let ANALYZE/DISK go into a loop, then look
  at the process from SDA in another session. To find the FID of the bad
  directory look in R6 on a VAX or R11 on Alpha. See VMSNOTES_V10 note 860
  for some discussion - that's where I learned the magic register numbers.
  You can then double check the diagnosis by examining the file header with
  a command similar to:

$ DUMP/FILE/BLOCK=(START:n,COUNT:1) disk:[000000]INDEXF.SYS

  where n is FID+DiskOffset. Probably the easiest way to find the offset
  is to start with n=FID, look at the actual FID you get, take the difference
  and add it to the original FID. Once you've located the header, verify that
  the backlink is the same as the FID.

  Now, one way of correcting this is to use a program to open the file by FID,
  clear the DIRECTORY bit, delete the file and then use ANALYZE/DISK/REPAIR
  to move the files which were in the directory to [SYSLOST]. The trouble with
  this is that most of the disks I've seen in this state have multiple 
  instances on them, so SYSLOST gets a bit crowded and it's tedious to move
  the files to their rightful place. A more promising approach is to simply
  clear the backlink to (0,0,0). I haven't been able to do a complete test of
  this yet so I'm not entirely certain what the result will be. I expect to
  find the directory, intact in [SYSLOST]. However, it may contain an "alias"
  entry pointing to itself which could be tricky to remove. I have a customer
  checking this tonight. I've included the program I used to clear the
  backlink below.
						John Gillings, Sydney CSC

        .TITLE BlastBacklink
;;;
;;;
;!!!WARNING!!!!WARNING!!!!!!!WARNING!!!!!WARNING!!!!!!!!WARNING!!!!!!!
;!!                                                                 !!
;!! ALL STATEMENTS WITH A COMMENT OF '****' MUST BE MODIFIED        !!
;!! BY THE USER TO POINT TO THE APPROPRIATE DISK AND FILE.          !!
;!!    There are 4 statements that need to be modified.             !!
;!!                                                                 !!
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
; This program clears the directory backlink in the header of a file specified
; by file ID. The primary purpose is to correct directory files which have
; become entered into themselves, thereby causing ANALYZE/DISK into a COM
; loop for systems running OpenVMS V6.1 and lower.
;
; Problem reference: VMSNOTES 830.0
;
; Diagnostic is to check the looping ANALYZE/DISK process from SDA and
; examine R6 (VAX) or R11 (AXP) to determine the suspect file ID. From
; there dump the header of the file in INDEXF.SYS to verify that the
; backlink is the same as the file ID.
;
; This program can then be used to clear the backlink, after which a run of
; ANALYZE/DISK/REPAIR can be used to place the directory into SYSLOST. Note
; that there may be multiple looped directories, so make sure you can get
; a run of ANALYZE/DISK/NOREPAIR to complete, before repairing the disk.
;
        .LIBRARY /SYS$SHARE:LIB/
        $FIBDEF
        $ATRDEF
;
; *** THE FOLLOWING 4 LINES MUST BE MODIFIED TO SPECIFY THE FILE TO FIX
dev:            .ASCID  /NOSUCHDEV:/   ;**** disk name where file resides
FILE_FID=                              ;**** First number in FID
FILE_SEQ=                              ;**** Second number in FID
FILE_RVN=                              ;**** Third number in FID
;
; ***
iosb:           .QUAD                      ;IOSB for QIO
dev_chan:       .BLKW 1                    ;IO channel for output file
fib_descr:      .LONG FIB$K_LENGTH         ;File Information Block
                .LONG fib_block            ; descriptor for ACP QIO
fib_block:      .BLKB FIB$K_LENGTH         ; used to open the file.
atr_block:      .WORD ATR$S_BACKLINK       ;File attributes block
                .WORD ATR$C_BACKLINK       ; used to get the file id
                .ADDRESS atr_bklk_buf      ; of the directory file.
                .LONG 0
atr_bklk_buf:   .WORD 0
                .WORD 0
                .WORD 0

        .ENTRY BEGIN, ^M<>
;
; Store the file id for the corrupt file in the FIB.
;
        MOVW #FILE_FID, fib_block+FIB$W_FID_NUM
        MOVW #FILE_SEQ, fib_block+FIB$W_FID_SEQ
        MOVW #FILE_RVN, fib_block+FIB$W_FID_RVN
;
; Set the access control bits and name string control bits
; in the FIB.
;
        MOVL #FIB$M_WRITE!FIB$M_WRITETHRU,fib_block+FIB$L_ACCTL
        MOVL #FIB$M_FINDFID,fib_block+FIB$W_NMCTL
;
; Assign a channel to the disk containing the file to be deleted
;
        $ASSIGN_S devnam=dev, chan=dev_chan
        BLBS R0,1$
        BRW bye
;
; Open file via file-id
;
1$:     $QIOW_S chan=dev_chan,-
                func=#IO$_ACCESS!IO$M_ACCESS,-
                iosb=iosb,-
                p1=fib_descr
        BLBC R0,bye
        MOVZWL iosb,R0
        BLBC R0,bye
;
; Clear the backlink
;
        $QIOW_S chan=dev_chan,-
                func=#IO$_MODIFY,-
                iosb=iosb,-
                p1=fib_descr,-
                p5=#atr_block
        BLBC R0,bye
        MOVZWL iosb,R0
        BLBC R0,bye
;
; Close file
;
        $QIOW_S chan=dev_chan,-
                func=#IO$_DEACCESS, -
                iosb=iosb, -
                p1=fib_descr
        BLBC R0,bye
        MOVZWL iosb,R0
bye:    $EXIT_S R0
        .END begin
