kerneltest/f32test/demandpaging/t_clamp.cpp
changeset 286 48e57fb1237e
parent 36 538db54a451d
equal deleted inserted replaced
285:ff5437e4337c 286:48e57fb1237e
   214 	test (r==KErrNone);
   214 	test (r==KErrNone);
   215 	}
   215 	}
   216 
   216 
   217 
   217 
   218 
   218 
       
   219 void RemountFileSystem(TInt aDriveNo, TDesC& aFsName, TDesC& aFsExtName0, TDesC& aFsExtName1)
       
   220 	{
       
   221 	TInt r;
       
   222 	if(aFsExtName0.Length() > 0)
       
   223 		{
       
   224 		r=TheFs.MountFileSystem(aFsName,aFsExtName0,aDriveNo);
       
   225 		test(r==KErrNone);
       
   226 		}
       
   227 	else if(aFsExtName1.Length() > 0) // untested !
       
   228 		{
       
   229 		r=TheFs.MountFileSystem(aFsName,aFsExtName1,aDriveNo);
       
   230 		test(r==KErrNone);
       
   231 		}
       
   232 	else 
       
   233 		{
       
   234 		r=TheFs.MountFileSystem(aFsName,aDriveNo);
       
   235 		test(r==KErrNone);
       
   236 		}
       
   237 	}
       
   238 
   219 LOCAL_C void TestDeferredDismount(TDesC& aRoot, TDesC& aFileName, RFileClamp* handlePtr)
   239 LOCAL_C void TestDeferredDismount(TDesC& aRoot, TDesC& aFileName, RFileClamp* handlePtr)
   220 	{
   240 	{
   221 	// Open and clamp file, register for dismount notification, then issue 
   241 	// Open and clamp file, register for dismount notification, then issue 
   222 	// dismount instruction.
   242 	// dismount instruction.
   223 	// Since there are no other clients registered for dismount notification,
   243 	// Since there are no other clients registered for dismount notification,
   229 	const TInt KMaxFileSystemNameLength=100; // Arbitrary length
   249 	const TInt KMaxFileSystemNameLength=100; // Arbitrary length
   230 	const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length
   250 	const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length
   231 	TBuf<KMaxFileSystemNameLength> fsName;
   251 	TBuf<KMaxFileSystemNameLength> fsName;
   232 	TBuf<KMaxFileSystemExtNameLength> fsExtName_0;
   252 	TBuf<KMaxFileSystemExtNameLength> fsExtName_0;
   233 	TBuf<KMaxFileSystemExtNameLength> fsExtName_1;
   253 	TBuf<KMaxFileSystemExtNameLength> fsExtName_1;
   234 	TBool fsExt0Present=EFalse;
       
   235 	TBool fsExt1Present=EFalse;
       
   236 	TInt driveNo, r;
   254 	TInt driveNo, r;
   237 	r=TheFs.CharToDrive(aRoot[0], driveNo);
   255 	r=TheFs.CharToDrive(aRoot[0], driveNo);
   238 	test(r==KErrNone);
   256 	test(r==KErrNone);
   239 	r=TheFs.FileSystemName(fsName, driveNo);
   257 	r=TheFs.FileSystemName(fsName, driveNo);
   240 	test(r==KErrNone);
   258 	test(r==KErrNone);
   241 	r=TheFs.ExtensionName(fsExtName_0,driveNo,0);
   259 
   242 	if(r==KErrNone)
   260 	//*******************************************************************************************************
   243 		fsExt0Present=ETrue;
       
   244 	r=TheFs.ExtensionName(fsExtName_1,driveNo,1);
       
   245 	if(r==KErrNone)
       
   246 		fsExt1Present=ETrue;
       
   247 
       
   248 	// Create a file & write to it so that we can test whether dismounting works correctly with dirty data
   261 	// Create a file & write to it so that we can test whether dismounting works correctly with dirty data
       
   262 	//*******************************************************************************************************
       
   263 	test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with dirty data, registered clients & clamped files"));
       
   264 
   249 	TDriveInfo driveInfo;
   265 	TDriveInfo driveInfo;
   250 	test(TheFs.Drive(driveInfo, driveNo) == KErrNone);
   266 	test(TheFs.Drive(driveInfo, driveNo) == KErrNone);
   251 	TFileName dirtyFileName(_L("dirtyFile.tst"));
   267 	TFileName dirtyFileName(_L("dirtyFile.tst"));
   252 	RFile dirtyFile;
   268 	RFile dirtyFile;
   253 	if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   269 	TBool writeProtectedMedia = driveInfo.iMediaAtt & KMediaAttWriteProtected;
       
   270 	if (!writeProtectedMedia)
   254 		{
   271 		{
   255 		r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite);
   272 		r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite);
   256 		test(r==KErrNone);
   273 		test(r==KErrNone);
   257 		r=dirtyFile.Write(_L8("My name is Michael Caine"));
   274 		r=dirtyFile.Write(_L8("My name is Michael Caine"));
   258 		test(r==KErrNone);
   275 		test(r==KErrNone);
   266 	test(r==KErrNone);
   283 	test(r==KErrNone);
   267 	testFile.Close();
   284 	testFile.Close();
   268 
   285 
   269 	TRequestStatus clientNotify=KErrNone;
   286 	TRequestStatus clientNotify=KErrNone;
   270 	TRequestStatus clientDismount=KErrNone;
   287 	TRequestStatus clientDismount=KErrNone;
   271 	TheFs.NotifyDismount(driveNo, clientNotify); // Register for notification
   288 	TheFs.NotifyDismount(driveNo, clientNotify); // Register for dismount notification
   272 	test(clientNotify == KRequestPending);
   289 	test(clientNotify == KRequestPending);
   273 	
   290 
       
   291 	// register for disk change notifcation, so we can detect when dismount has actually taken place
       
   292 	TRequestStatus diskChangeStatus;
       
   293 	TheFs.NotifyChange(ENotifyDisk, diskChangeStatus);
       
   294 	test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int());
       
   295 	test(diskChangeStatus == KRequestPending); // no disk change yet
       
   296 	
       
   297 
   274 	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients);
   298 	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients);
   275 	test(clientDismount == KRequestPending);
   299 	test(clientDismount == KRequestPending);
   276 	User::WaitForRequest(clientNotify);
   300 	User::WaitForRequest(clientNotify);
   277 	test(clientNotify == KErrNone);
   301 	test(clientNotify == KErrNone);
   278 
   302 
   279 	r=TheFs.AllowDismount(driveNo);	// Respond to dismount notification
   303 	r=TheFs.AllowDismount(driveNo);	// Respond to dismount notification
   280 	test(r == KErrNone);
   304 	test(r == KErrNone);
   281 	test(clientDismount == KRequestPending); // Dismount is deferred
   305 	test(clientDismount == KRequestPending); // Dismount is deferred
       
   306 	test(diskChangeStatus == KRequestPending); // no disk change yet
   282 
   307 
   283 	//
   308 	//
   284 	// Now unclamp the file, and check that the deferred dismount is performed.
   309 	// Now unclamp the file, and check that the deferred dismount is performed.
   285 	r=handlePtr->Close(TheFs);
   310 	r=handlePtr->Close(TheFs);
   286 	test(r==KErrNone);
   311 	test(r==KErrNone);
   287 	User::WaitForRequest(clientDismount);
   312 	User::WaitForRequest(clientDismount);
   288 	test(clientDismount == KErrNone);	
   313 	test(clientDismount == KErrNone);	
   289 
   314 
       
   315 	// wait for disk change notification following dismount
       
   316 	User::WaitForRequest(diskChangeStatus);
       
   317 	test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount
       
   318 	r = TheFs.Drive(driveInfo, driveNo);
       
   319 	test (r==KErrNone);
       
   320 	test (driveInfo.iType == EMediaNotPresent);
       
   321 
       
   322 	// re-register for disk change notifcation, so we can detect when remount has actually taken place
       
   323 	TheFs.NotifyChange(ENotifyDisk, diskChangeStatus);
       
   324 	test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int());
       
   325 	test(diskChangeStatus == KRequestPending); // no disk change yet
       
   326 	
   290 	// Try to write to the opened file: this should return KErrNotReady as there is no drive thread
   327 	// Try to write to the opened file: this should return KErrNotReady as there is no drive thread
   291 	if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   328 	if (!writeProtectedMedia)
   292 		{
   329 		{
   293 		r=dirtyFile.Write(_L8("My name isn't really Michael Caine"));
   330 		r=dirtyFile.Write(_L8("My name isn't really Michael Caine"));
   294 		test(r==KErrNotReady);
   331 		test(r==KErrNotReady);
   295 		}
   332 		}
   296 
   333 
   297 	// Re-mount the file system
   334 	// Re-mount the file system
   298 	if(fsExt0Present)
   335 	RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1);
   299 		{
   336 
   300 		r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo);
   337 	// wait for disk change notification following remount
   301 		test(r==KErrNone);
   338 	User::WaitForRequest(diskChangeStatus);
   302 		}
   339 	test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount
   303 	else if(fsExt1Present) // untested !
   340 	r = TheFs.Drive(driveInfo, driveNo);
   304 		{
   341 	test (r==KErrNone);
   305 		r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo);
   342 	test (driveInfo.iType != EMediaNotPresent);
   306 		test(r==KErrNone);
       
   307 		}
       
   308 	else 
       
   309 		{
       
   310 		r=TheFs.MountFileSystem(fsName,driveNo);
       
   311 		test_KErrNone(r);
       
   312 		}
       
   313 
   343 
   314 	// create some more dirty data to verify that the file server can cope with the drive thread 
   344 	// create some more dirty data to verify that the file server can cope with the drive thread 
   315 	// having gone & come back again
   345 	// having gone & come back again
   316 	if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   346 	if (!writeProtectedMedia)
   317 		{
   347 		{
   318 		r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish."));
   348 		r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish."));
   319 		test(r==KErrDisMounted);
   349 		test(r==KErrDisMounted);
   320 
   350 
   321 		dirtyFile.Close();
   351 		dirtyFile.Close();
   322 		r = TheFs.Delete(dirtyFileName);
   352 		r = TheFs.Delete(dirtyFileName);
   323 		test(r == KErrNone);
   353 		test(r == KErrNone);
   324 		}
   354 		}
   325 
   355 
       
   356 	//*******************************************************************************************************
   326 	// Issue a EFsDismountNotifyClients with no clients but with files clamped
   357 	// Issue a EFsDismountNotifyClients with no clients but with files clamped
   327 	// & verify that the dismount request completes when clamps are removed
   358 	// & verify that the dismount request completes when clamps are removed
       
   359 	//*******************************************************************************************************
       
   360 	test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with no registered clients & clamped files"));
       
   361 
   328 	r=testFile.Open(TheFs,aFileName,EFileRead);
   362 	r=testFile.Open(TheFs,aFileName,EFileRead);
   329 	test(r==KErrNone);
   363 	test(r==KErrNone);
   330 	r=handlePtr->Clamp(testFile);
   364 	r=handlePtr->Clamp(testFile);
   331 	test(r==KErrNone);
   365 	test(r==KErrNone);
   332 	testFile.Close();
   366 	testFile.Close();
   336 	r=handlePtr->Close(TheFs);
   370 	r=handlePtr->Close(TheFs);
   337 	test(r==KErrNone);
   371 	test(r==KErrNone);
   338 	User::WaitForRequest(clientDismount);
   372 	User::WaitForRequest(clientDismount);
   339 	test(clientDismount == KErrNone);	
   373 	test(clientDismount == KErrNone);	
   340 	// Re-mount the file system again
   374 	// Re-mount the file system again
   341 	if(fsExt0Present)
   375 	RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1);
   342 		{
       
   343 		r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo);
       
   344 		test(r==KErrNone);
       
   345 		}
       
   346 	else if(fsExt1Present) // untested !
       
   347 		{
       
   348 		r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo);
       
   349 		test(r==KErrNone);
       
   350 		}
       
   351 	else 
       
   352 		{
       
   353 		r=TheFs.MountFileSystem(fsName,driveNo);
       
   354 		test_KErrNone(r);
       
   355 		}
       
   356 
   376 
   357 
   377 
   358 	// Issue a EFsDismountForceDismount with no clients but with files clamped
   378 	// Issue a EFsDismountForceDismount with no clients but with files clamped
   359 	// & verify that the dismount request completes when clamps are removed
   379 	// & verify that the dismount request completes when clamps are removed
   360 	r=testFile.Open(TheFs,aFileName,EFileRead);
   380 	r=testFile.Open(TheFs,aFileName,EFileRead);
   367 	test(clientDismount == KRequestPending);
   387 	test(clientDismount == KRequestPending);
   368 	r=handlePtr->Close(TheFs);
   388 	r=handlePtr->Close(TheFs);
   369 	test(r==KErrNone);
   389 	test(r==KErrNone);
   370 	User::WaitForRequest(clientDismount);
   390 	User::WaitForRequest(clientDismount);
   371 	test(clientDismount == KErrNone);	
   391 	test(clientDismount == KErrNone);	
       
   392 
       
   393 
   372 	// Re-mount the file system again
   394 	// Re-mount the file system again
   373 	if(fsExt0Present)
   395 	RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1);
   374 		{
   396 
   375 		r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo);
   397 
   376 		test(r==KErrNone);
   398 	const TInt KNumClients = 5;
   377 		}
   399     RFs clientFs[KNumClients];
   378 	else if(fsExt1Present) // untested !
   400 	TRequestStatus clientNotifies[KNumClients];
   379 		{
   401 	TRequestStatus clientDiskChanges[KNumClients];
   380 		r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo);
   402 	TRequestStatus clientComplete;
   381 		test(r==KErrNone);
   403 
   382 		}
   404 	#define LOG_AND_TEST(a, e) {if (a!=e) {test.Printf(_L("lvalue %d, rvalue%d\n\r"), a,e); test(EFalse);}}
   383 	else 
   405 	
   384 		{
   406 	//*******************************************************************************************************
   385 		r=TheFs.MountFileSystem(fsName,driveNo);
   407 	// Test unmounting with multiple registered clients which do not respond & close their sessions
   386 		test_KErrNone(r);
   408 	//*******************************************************************************************************
   387 		}
   409 	test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with multiple registered clients which do not respond & close their sessions"));
   388 
   410 
       
   411 	TheFs.NotifyChange(ENotifyDisk, diskChangeStatus);
       
   412 	test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int());
       
   413 
       
   414 	TInt i;
       
   415 	for (i=0; i< KNumClients; i++)
       
   416 		{
       
   417 		LOG_AND_TEST(KErrNone, clientFs[i].Connect());
       
   418    		clientFs[i].NotifyDismount(driveNo, clientNotifies[i]);
       
   419 		test(clientNotifies[i] == KRequestPending);
       
   420 		}
       
   421 
       
   422 	test.Next(_L("Close all but one client sessions with outstanding notifiers"));
       
   423 	for (i=0; i< KNumClients-1; i++)
       
   424 		clientFs[i].Close();
       
   425 
       
   426 	// Since all clients have NOT been closed, the next stage should not yet complete
       
   427 	test.Next(_L("Notify clients of pending media removal and check status - should not complete"));
       
   428 	TheFs.NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients);
       
   429 	test(clientComplete == KRequestPending);
       
   430 
       
   431 
       
   432 	test.Next(_L("Close the remaining sessions with an outstanding notifier"));
       
   433 	clientFs[KNumClients-1].Close();
       
   434 
       
   435 	// Check that the dismount completes now that all session have been closed
       
   436 	test.Next(_L("Check that the dismount completes"));
       
   437     User::WaitForRequest(clientComplete);
       
   438 	test_KErrNone(clientComplete.Int());
       
   439 
       
   440 	// wait for disk change notification following dismount
       
   441 	User::WaitForRequest(diskChangeStatus);
       
   442 	test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount
       
   443 	r = TheFs.Drive(driveInfo, driveNo);
       
   444 	test (r==KErrNone);
       
   445 	test (driveInfo.iType == EMediaNotPresent);
       
   446 
       
   447 	// re-register for disk change notifcation, so we can detect when remount has actually taken place
       
   448 	TheFs.NotifyChange(ENotifyDisk, diskChangeStatus);
       
   449 	test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int());
       
   450 	test(diskChangeStatus == KRequestPending); // no disk change yet
       
   451 	
       
   452 
       
   453 	// Re-mount the file system again
       
   454 	RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1);
       
   455 
       
   456 	// wait for disk change notification following remount
       
   457 	User::WaitForRequest(diskChangeStatus);
       
   458 	test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount
       
   459 	r = TheFs.Drive(driveInfo, driveNo);
       
   460 	test (r==KErrNone);
       
   461 	test (driveInfo.iType != EMediaNotPresent);
       
   462 
       
   463 	
       
   464 
       
   465 	//*******************************************************************************************************
       
   466 	// Issue a EFsDismountNotifyClients with multiple clients 
       
   467 	// Verify that the dismount completes if a client re-registers for dismount notifications BEFORE calling AllowDismount
       
   468 	//*******************************************************************************************************
       
   469 
       
   470 	test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with multiple registered clients & a re-registration"));
       
   471 
       
   472 	for(i=0; i< KNumClients; i++)
       
   473 		{
       
   474    		r=clientFs[i].Connect();
       
   475 		test(r==KErrNone);
       
   476 		}
       
   477 	// Cancel any deferred dismount in preparation for the next test
       
   478 	TheFs.NotifyDismountCancel();
       
   479 
       
   480 	// All clients register for dismount notification
       
   481 	for(i=0; i< KNumClients; i++)
       
   482 		{
       
   483 		clientNotifies[i] = KErrNone;
       
   484    		clientFs[i].NotifyDismount(driveNo, clientNotifies[i]);
       
   485 		test(clientNotifies[i] == KRequestPending);
       
   486 		}
       
   487 	
       
   488 	// Issue a EFsDismountNotifyClients & wait for clients to respond
       
   489 	clientDismount = KErrNone;
       
   490    	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients);
       
   491 	test(clientDismount == KRequestPending);
       
   492 
       
   493 	// Check all clients have received the notification
       
   494 	for(i=0; i< KNumClients; i++)
       
   495 		{
       
   496 		User::WaitForRequest(clientNotifies[i]);
       
   497 		test(clientNotifies[i] == KErrNone);
       
   498 		}
       
   499 	// All clients - except first one - invoke AllowDismount
       
   500 	for(i=1; i< KNumClients; i++)
       
   501 		{
       
   502 		r=clientFs[i].AllowDismount(driveNo);
       
   503 		test(r==KErrNone);
       
   504 		}
       
   505 
       
   506 
       
   507 	// verify dismount has not yet completed
       
   508 	test(clientDismount == KRequestPending);
       
   509 
       
   510 
       
   511 	// first client re-registers for dismount notifications
       
   512 	clientFs[0].NotifyDismount(driveNo, clientNotifies[0]);
       
   513 	test(clientNotifies[0] == KRequestPending);
       
   514 
       
   515 	// first client allows dismount
       
   516 	clientFs[0].AllowDismount(driveNo);
       
   517 	test(r==KErrNone);
       
   518 
       
   519 	// Wait for dismount
       
   520 	User::WaitForRequest(clientDismount);
       
   521 	test(clientDismount == KErrNone);
       
   522 
       
   523 
       
   524 	// verify the first client's re-issued dismount notification is still pending
       
   525 	test(clientNotifies[0] == KRequestPending);
       
   526 
       
   527 
       
   528 	// Re-mount the file system again
       
   529 	RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1);
       
   530 
       
   531 
       
   532 	// Issue a EFsDismountNotifyClients again & check previously re-registered notification completes
       
   533 	test(clientNotifies[0] == KRequestPending);
       
   534 	clientDismount = KErrNone;
       
   535    	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients);
       
   536 	test(clientDismount == KRequestPending);
       
   537 
       
   538 	// wait for notification
       
   539 	User::WaitForRequest(clientNotifies[0]);
       
   540 	
       
   541 	// first client allows dismount
       
   542 	clientFs[0].AllowDismount(driveNo);
       
   543 	test(r==KErrNone);
       
   544 
       
   545 	// Wait for dismount
       
   546 	User::WaitForRequest(clientDismount);
       
   547 	test(clientDismount == KErrNone);
       
   548 
       
   549 
       
   550 
       
   551 	// Re-mount the file system again
       
   552 	RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1);
       
   553 
       
   554 	
       
   555 
       
   556 	//*******************************************************************************************************
       
   557 	// Issue a EFsDismountNotifyClients again with a multiple clients & then call RFs::NotifyDismountCancel()
       
   558 	// Verify that all clients receive a disk change notification
       
   559 	//*******************************************************************************************************
       
   560 	test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with registered clients, a re-registration & a cancel"));
       
   561 	
       
   562 	// All clients register for dismount notification & disk change notification
       
   563 	for(i=0; i< KNumClients; i++)
       
   564 		{
       
   565 		clientNotifies[i] = KErrNone;
       
   566    		clientFs[i].NotifyDismount(driveNo, clientNotifies[i], EFsDismountRegisterClient);
       
   567 		test(clientNotifies[i] == KRequestPending);
       
   568 		
       
   569 		clientFs[i].NotifyChange(ENotifyDisk, clientDiskChanges[i]);
       
   570 		test.Printf(_L("diskChangeStatus %d"), clientDiskChanges[i].Int());
       
   571 		test(clientDiskChanges[i] == KRequestPending);
       
   572 		}
       
   573 	
       
   574 
       
   575 	// Issue a EFsDismountNotifyClients
       
   576    	TheFs.NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients);
       
   577 	test(clientComplete == KRequestPending);
       
   578 
       
   579 
       
   580 	// Check all clients have received the notification
       
   581 	for(i=0; i< KNumClients; i++)
       
   582 		{
       
   583 		User::WaitForRequest(clientNotifies[i]);
       
   584 		test(clientNotifies[i] == KErrNone);
       
   585 
       
   586 		test.Printf(_L("diskChangeStatus %d"), clientDiskChanges[i].Int());
       
   587 		test(clientDiskChanges[i] == KRequestPending);
       
   588 		}
       
   589 
       
   590 	// verify dismount has not yet completed
       
   591 	test(clientComplete == KRequestPending);
       
   592 
       
   593 
       
   594 	// first client re-registers for dismount notifications
       
   595 	clientFs[0].NotifyDismount(driveNo, clientNotifies[0]);
       
   596 	test(clientNotifies[0] == KRequestPending);
       
   597 
       
   598 	// first client acknowledges the dismount request
       
   599 	r = clientFs[0].AllowDismount(driveNo);
       
   600 	test(r == KErrNone);
       
   601 
       
   602 	
       
   603 	// cancel dismount
       
   604 //	TheFs.NotifyDismountCancel(clientComplete);
       
   605 	TheFs.NotifyDismountCancel();
       
   606 	test(clientComplete == KErrCancel);
       
   607 	User::WaitForRequest(clientComplete);
       
   608 
       
   609 	// Check all clients have received a disk change notification - 
       
   610 	// the file server should send a disk change notification when RFs::NotifyDismountCancel() is called
       
   611 	for(i=0; i< KNumClients; i++)
       
   612 		{
       
   613 		User::WaitForRequest(clientDiskChanges[i]);
       
   614 		test.Printf(_L("diskChangeStatus %d"), clientDiskChanges[i].Int());
       
   615 		test(clientDiskChanges[i] == KErrNone);
       
   616 		}
       
   617 
       
   618 
       
   619 	// cleanup
       
   620 	for(i=0; i< KNumClients; i++)
       
   621 		{
       
   622    		clientFs[i].Close();
       
   623 		test(r==KErrNone);
       
   624 		}
   389 	}
   625 	}
   390 
   626 
   391 
   627 
   392 
   628 
   393 LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName)
   629 LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName)