Fake volume serial number on filesystems not providing it
* mount.cc (fs_info::update): Fake a serial number on filesystems not providing one. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
		| @@ -1,3 +1,8 @@ | |||||||
|  | 2015-11-05  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* mount.cc (fs_info::update): Fake a serial number on filesystems not | ||||||
|  | 	providing one. | ||||||
|  |  | ||||||
| 2015-11-05  Corinna Vinschen  <corinna@vinschen.de> | 2015-11-05  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* fcntl.cc (fcntl64): Don't lock fd table when performing locking. | 	* fcntl.cc (fcntl64): Don't lock fd table when performing locking. | ||||||
|   | |||||||
| @@ -182,8 +182,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | |||||||
|  |  | ||||||
|   clear (); |   clear (); | ||||||
|   /* Always caseinsensitive.  We really just need access to the drive. */ |   /* Always caseinsensitive.  We really just need access to the drive. */ | ||||||
|   InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, |   InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, NULL); | ||||||
| 			      NULL); |  | ||||||
|   if (in_vol) |   if (in_vol) | ||||||
|     vol = in_vol; |     vol = in_vol; | ||||||
|   else |   else | ||||||
| @@ -232,6 +231,33 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | |||||||
|   uint32_t hash = 0; |   uint32_t hash = 0; | ||||||
|   if (NT_SUCCESS (status)) |   if (NT_SUCCESS (status)) | ||||||
|     { |     { | ||||||
|  |       /* If the FS doesn't return a valid serial number (PrlSF is a candidate), | ||||||
|  | 	 create reproducible serial number from path.  We need this to create | ||||||
|  | 	 a unique per-drive/share hash. */ | ||||||
|  |       if (ffvi_buf.ffvi.VolumeSerialNumber == 0) | ||||||
|  | 	{ | ||||||
|  | 	  UNICODE_STRING path_prefix; | ||||||
|  | 	  WCHAR *p; | ||||||
|  |  | ||||||
|  | 	  if (upath->Buffer[5] == L':' && upath->Buffer[6] == L'\\') | ||||||
|  | 	    p = upath->Buffer + 6; | ||||||
|  | 	  else | ||||||
|  | 	    { | ||||||
|  | 	      /* We're expecting an UNC path.  Move p to the backslash after | ||||||
|  | 	         "\??\UNC\server\share" or the trailing NUL. */ | ||||||
|  | 	      p = upath->Buffer + 7;  /* Skip "\??\UNC" */ | ||||||
|  | 	      int bs_cnt = 0; | ||||||
|  |  | ||||||
|  | 	      while (*++p) | ||||||
|  | 		if (*p == L'\\') | ||||||
|  | 		    if (++bs_cnt > 1) | ||||||
|  | 		      break; | ||||||
|  | 	    } | ||||||
|  | 	  RtlInitCountedUnicodeString (&path_prefix, upath->Buffer, | ||||||
|  | 				       (p - upath->Buffer) * sizeof (WCHAR)); | ||||||
|  | 	  ffvi_buf.ffvi.VolumeSerialNumber = hash_path_name ((ino_t) 0, | ||||||
|  | 							     &path_prefix); | ||||||
|  | 	} | ||||||
|       fs_info *fsi = fsi_cache.search (&ffvi_buf.ffvi, hash); |       fs_info *fsi = fsi_cache.search (&ffvi_buf.ffvi, hash); | ||||||
|       if (fsi) |       if (fsi) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user