@@ -4109,6 +4109,32 @@ os_file_readdir_next_file(
4109
4109
return (status);
4110
4110
}
4111
4111
4112
+ /* * Check that IO of specific size is possible for the file
4113
+ opened with FILE_FLAG_NO_BUFFERING.
4114
+
4115
+ The requirement is that IO is multiple of the disk sector size.
4116
+
4117
+ @param[in] file file handle
4118
+ @param[in] io_size expected io size
4119
+ @return true - unbuffered io of requested size is possible, false otherwise.
4120
+
4121
+ @note: this function only works correctly with Windows 8 or later,
4122
+ (GetFileInformationByHandleEx with FileStorageInfo is only supported there).
4123
+ It will return true on earlier Windows version.
4124
+ */
4125
+ static bool unbuffered_io_possible (HANDLE file, size_t io_size)
4126
+ {
4127
+ FILE_STORAGE_INFO info;
4128
+ if (GetFileInformationByHandleEx (
4129
+ file, FileStorageInfo, &info, sizeof (info))) {
4130
+ ULONG sector_size = info.LogicalBytesPerSector ;
4131
+ if (sector_size)
4132
+ return io_size % sector_size == 0 ;
4133
+ }
4134
+ return true ;
4135
+ }
4136
+
4137
+
4112
4138
/* * NOTE! Use the corresponding macro os_file_create(), not directly
4113
4139
this function!
4114
4140
Opens an existing file or creates a new.
@@ -4284,46 +4310,57 @@ os_file_create_func(
4284
4310
access |= GENERIC_WRITE;
4285
4311
}
4286
4312
4287
- do {
4313
+ for (;;) {
4314
+ const char *operation;
4315
+
4288
4316
/* Use default security attributes and no template file. */
4289
4317
file = CreateFile (
4290
- (LPCTSTR) name, access, share_mode, NULL ,
4318
+ name, access, share_mode, NULL ,
4291
4319
create_flag, attributes, NULL );
4292
4320
4293
- if (file == INVALID_HANDLE_VALUE) {
4294
- const char * operation;
4321
+ /* If FILE_FLAG_NO_BUFFERING was set, check if this can work at all,
4322
+ for expected IO sizes. Reopen without the unbuffered flag, if it is won't work*/
4323
+ if ((file != INVALID_HANDLE_VALUE)
4324
+ && (attributes & FILE_FLAG_NO_BUFFERING)
4325
+ && (type == OS_LOG_FILE)
4326
+ && !unbuffered_io_possible (file, OS_FILE_LOG_BLOCK_SIZE)) {
4327
+ ut_a (CloseHandle (file));
4328
+ attributes &= ~FILE_FLAG_NO_BUFFERING;
4329
+ continue ;
4330
+ }
4295
4331
4296
- operation = (create_mode == OS_FILE_CREATE
4297
- && !read_only)
4298
- ? " create" : " open" ;
4332
+ *success = (file != INVALID_HANDLE_VALUE);
4333
+ if (*success) {
4334
+ break ;
4335
+ }
4299
4336
4300
- *success = false ;
4337
+ operation = (create_mode == OS_FILE_CREATE && !read_only) ?
4338
+ " create" : " open" ;
4301
4339
4302
- if (on_error_no_exit) {
4303
- retry = os_file_handle_error_no_exit (
4304
- name, operation, on_error_silent);
4305
- } else {
4306
- retry = os_file_handle_error (name, operation);
4307
- }
4308
- } else {
4309
-
4310
- retry = false ;
4340
+ if (on_error_no_exit) {
4341
+ retry = os_file_handle_error_no_exit (
4342
+ name, operation, on_error_silent);
4343
+ }
4344
+ else {
4345
+ retry = os_file_handle_error (name, operation);
4346
+ }
4311
4347
4312
- *success = true ;
4348
+ if (!retry) {
4349
+ break ;
4350
+ }
4351
+ }
4313
4352
4314
- if (srv_use_native_aio && ((attributes & FILE_FLAG_OVERLAPPED) != 0 )) {
4315
- /* Bind the file handle to completion port. Completion port
4316
- might not be created yet, in some stages of backup, but
4317
- must always be there for the server.*/
4318
- HANDLE port =(type == OS_LOG_FILE)?
4319
- log_completion_port : data_completion_port;
4320
- ut_a (port || srv_operation != SRV_OPERATION_NORMAL);
4321
- if (port) {
4322
- ut_a (CreateIoCompletionPort (file, port, 0 , 0 ));
4323
- }
4324
- }
4353
+ if (*success && srv_use_native_aio && (attributes & FILE_FLAG_OVERLAPPED)) {
4354
+ /* Bind the file handle to completion port. Completion port
4355
+ might not be created yet, in some stages of backup, but
4356
+ must always be there for the server.*/
4357
+ HANDLE port = (type == OS_LOG_FILE) ?
4358
+ log_completion_port : data_completion_port;
4359
+ ut_a (port || srv_operation != SRV_OPERATION_NORMAL);
4360
+ if (port) {
4361
+ ut_a (CreateIoCompletionPort (file, port, 0 , 0 ));
4325
4362
}
4326
- } while (retry);
4363
+ }
4327
4364
4328
4365
return (file);
4329
4366
}
0 commit comments