BUG: A Level 3 Volume Lock Might Deadlock on Windows 95

ID: Q176905

The information in this article applies to:

SYMPTOMS

Deadlock might occur when a Windows 95 application tries to take a level 3 volume lock. The following is a typical scenario:

    Process A (32-bit)                           Process B (16-bit)
 _________________________                    _________________________
|                         |                  |                         |
| 1. Acquire level 2 lock |                  |                         |
|                         |                  |                         |
|                         | 2. Process A     |                         |
|                         |    preempted     |                         |
|                         | ---------------> |                         |
|                         |                  | 3. Attempt a file write |
|                         |                  |                         |
|                         |                  |    -acquire kernel32    |
|                         |                  |     lock                |
|                         |                  |                         |
|                         |                  |    -IFS manager blocks  |
|                         |                  |     on write (Process A |
|                         |                  |     owns level 2 lock)  |
|                         | 4. Process A     |                         |
|                         |    rescheduled   |                         |
|                         | <--------------- |                         |
| 5. Request for level 3  |                  |                         |
|    lock blocks on       |                  |                         |
|    request for kernel32 |                  |                         |
|    lock (owned by       |                  |                         |
|    Process B)           |                  |                         |
|_________________________|                  |_________________________|

1. Process A, a 32-bit Windows application, acquires a level 2 volume lock.

2. Process A's running thread is preempted.

3. Process B makes a 16-bit Windows API call requiring write access on the

   locked drive. The API acquires the kernel32 lock prior to passing
   the request to the IFS manager. The thread is blocked because it is
   denied write access until process A releases the level 2 lock.

4. Process A is rescheduled.

5. Process A requests the level 3 volume lock. The level 3 lock first

   tries to acquire the kernel32 lock. The thread subsequently blocks,
   since the kernel32 lock is already owned by process B.

Both processes are now blocked, each one is waiting on a resource that the other owns.

CAUSE

The deadlock takes place because the order in which the resources (write access to the disk and the kernel32 lock) are requested differs between the two processes and because the acquisition of these resources is not an atomic transaction. Furthermore, the problem only seems to show up when another process is performing 16-bit file I/O on the locked volume.

RESOLUTION

There is no viable workaround for 32-bit code. The Windows 95 disk utilities avoid this problem by thunking to 16-bit code, thereby assuring that the acquisition of the level 2 and level 3 volume locks is done atomically.

    Process A (32-bit)                           Process B (16-bit)
 _________________________                    _________________________
|                         |                  |                         |
| 1. Thunk to 16-bit code |                  |                         |
|                         |                  |                         |
| 2. Acquire level 2 lock |                  |                         |
|                         |                  |                         |
| 3. Acquire level 3 lock |                  |                         |
|    (acquires kernel32   |                  |                         |
|    lock)                |                  |                         |
|                         |                  |                         |
| 4. Return from thunk    |                  |                         |
|                         |                  |                         |
|                         | 5. Process A     |                         |
|                         |    preempted     |                         |
|                         | ---------------> |                         |
|                         |                  | 6. Write blocks on      |
|                         |                  |    request for kernel32 |
|                         |                  |    lock                 |
|                         |                  |                         |
|                         | 7. Process A     |                         |
|                         |    rescheduled   |                         |
|                         | <--------------- |                         |
|                         |                  |                         |
| 8. Release level 3 lock |                  |                         |
|    (releases kernel32   |                  |                         |
|    lock)                |                  |                         |
|_________________________|                  |_________________________|

There is no deadlock here, since process B is no longer blocked. In reality, process A may be preempted between steps 2 and 3 above, but since it will then own the Win16 mutex, no other 16-bit process may be scheduled. Note that this will have consequences on the code design. To ensure atomicity, the Win16 mutex must not be released between requests for the level 2 and level 3 volume locks. Hence, these operations must be performed from within the context of a single thunk.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

Note that this problem is fixed in the Windows 95 OEM Service Release 2 (OSR2).

Additional query words: disk I/O diskio access kernel base win95

Keywords          : kbAPI kbKernBase kbGrpKernBase 
Version           : WINNT:
Platform          : winnt
Hardware          : x86
Issue type        : kbbug

Last Reviewed: November 20, 1997