📄 os0file.c
字号:
return(TRUE);#endif}/***************************************************************************Gets a file size. */iboolos_file_get_size(/*=============*/ /* out: TRUE if success */ os_file_t file, /* in: handle to a file */ ulint* size, /* out: least significant 32 bits of file size */ ulint* size_high)/* out: most significant 32 bits of size */{#ifdef __WIN__ DWORD high; DWORD low; low = GetFileSize(file, &high); if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) { return(FALSE); } *size = low; *size_high = high; return(TRUE);#else off_t offs; offs = lseek(file, 0, SEEK_END); if (offs == ((off_t)-1)) { return(FALSE); } if (sizeof(off_t) > 4) { *size = (ulint)(offs & 0xFFFFFFFFUL); *size_high = (ulint)(offs >> 32); } else { *size = (ulint) offs; *size_high = 0; } return(TRUE); #endif}/***************************************************************************Gets file size as a 64-bit integer ib_longlong. */ib_longlongos_file_get_size_as_iblonglong(/*===========================*/ /* out: size in bytes, -1 if error */ os_file_t file) /* in: handle to a file */{ ulint size; ulint size_high; ibool success; success = os_file_get_size(file, &size, &size_high); if (!success) { return(-1); } return((((ib_longlong)size_high) << 32) + (ib_longlong)size);}/***************************************************************************Write the specified number of zeros to a newly created file. */iboolos_file_set_size(/*=============*/ /* out: TRUE if success */ const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ ulint size, /* in: least significant 32 bits of file size */ ulint size_high)/* in: most significant 32 bits of size */{ ib_longlong current_size; ib_longlong desired_size; ibool ret; byte* buf; byte* buf2; ulint buf_size; ut_a(size == (size & 0xFFFFFFFF)); current_size = 0; desired_size = (ib_longlong)size + (((ib_longlong)size_high) << 32); /* Write up to 1 megabyte at a time. */ buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE)) * UNIV_PAGE_SIZE; buf2 = ut_malloc(buf_size + UNIV_PAGE_SIZE); /* Align the buffer for possible raw i/o */ buf = ut_align(buf2, UNIV_PAGE_SIZE); /* Write buffer full of zeros */ memset(buf, 0, buf_size); if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) { fprintf(stderr, "InnoDB: Progress in MB:"); } while (current_size < desired_size) { ulint n_bytes; if (desired_size - current_size < (ib_longlong) buf_size) { n_bytes = (ulint) (desired_size - current_size); } else { n_bytes = buf_size; } ret = os_file_write(name, file, buf, (ulint)(current_size & 0xFFFFFFFF), (ulint)(current_size >> 32), n_bytes); if (!ret) { ut_free(buf2); goto error_handling; } /* Print about progress for each 100 MB written */ if ((current_size + n_bytes) / (ib_longlong)(100 * 1024 * 1024) != current_size / (ib_longlong)(100 * 1024 * 1024)) { fprintf(stderr, " %lu00", (ulong) ((current_size + n_bytes) / (ib_longlong)(100 * 1024 * 1024))); } current_size += n_bytes; } if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) { fprintf(stderr, "\n"); } ut_free(buf2); ret = os_file_flush(file); if (ret) { return(TRUE); }error_handling: return(FALSE);}/***************************************************************************Truncates a file at its current position. */iboolos_file_set_eof(/*============*/ /* out: TRUE if success */ FILE* file) /* in: file to be truncated */{#ifdef __WIN__ HANDLE h = (HANDLE) _get_osfhandle(fileno(file)); return(SetEndOfFile(h));#else /* __WIN__ */ return(!ftruncate(fileno(file), ftell(file)));#endif /* __WIN__ */}/***************************************************************************Flushes the write buffers of a given file to the disk. */iboolos_file_flush(/*==========*/ /* out: TRUE if success */ os_file_t file) /* in, own: handle to a file */{#ifdef __WIN__ BOOL ret; ut_a(file); os_n_fsyncs++; ret = FlushFileBuffers(file); if (ret) { return(TRUE); } /* Since Windows returns ERROR_INVALID_FUNCTION if the 'file' is actually a raw device, we choose to ignore that error if we are using raw disks */ if (srv_start_raw_disk_in_use && GetLastError() == ERROR_INVALID_FUNCTION) { return(TRUE); } os_file_handle_error(NULL, "flush"); /* It is a fatal error if a file flush does not succeed, because then the database can get corrupt on disk */ ut_error; return(FALSE);#else int ret;#if defined(HAVE_DARWIN_THREADS)# ifndef F_FULLFSYNC /* The following definition is from the Mac OS X 10.3 <sys/fcntl.h> */# define F_FULLFSYNC 51 /* fsync + ask the drive to flush to the media */# elif F_FULLFSYNC != 51# error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3"# endif /* Apple has disabled fsync() for internal disk drives in OS X. That caused corruption for a user when he tested a power outage. Let us in OS X use a nonstandard flush method recommended by an Apple engineer. */ if (!srv_have_fullfsync) { /* If we are not on an operating system that supports this, then fall back to a plain fsync. */ ret = fsync(file); } else { ret = fcntl(file, F_FULLFSYNC, NULL); if (ret) { /* If we are not on a file system that supports this, then fall back to a plain fsync. */ ret = fsync(file); } }#elif HAVE_FDATASYNC ret = fdatasync(file);#else/* fprintf(stderr, "Flushing to file %p\n", file); */ ret = fsync(file);#endif os_n_fsyncs++; if (ret == 0) { return(TRUE); } /* Since Linux returns EINVAL if the 'file' is actually a raw device, we choose to ignore that error if we are using raw disks */ if (srv_start_raw_disk_in_use && errno == EINVAL) { return(TRUE); } ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: the OS said file flush did not succeed\n"); os_file_handle_error(NULL, "flush"); /* It is a fatal error if a file flush does not succeed, because then the database can get corrupt on disk */ ut_error; return(FALSE);#endif}#ifndef __WIN__/***********************************************************************Does a synchronous read operation in Posix. */staticssize_tos_file_pread(/*==========*/ /* out: number of bytes read, -1 if error */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read */ ulint n, /* in: number of bytes to read */ ulint offset, /* in: least significant 32 bits of file offset from where to read */ ulint offset_high) /* in: most significant 32 bits of offset */{ off_t offs; ssize_t n_bytes; ut_a((offset & 0xFFFFFFFFUL) == offset); /* If off_t is > 4 bytes in size, then we assume we can pass a 64-bit address */ if (sizeof(off_t) > 4) { offs = (off_t)offset + (((off_t)offset_high) << 32); } else { offs = (off_t)offset; if (offset_high > 0) { fprintf(stderr, "InnoDB: Error: file read at offset > 4 GB\n"); } } os_n_file_reads++;#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD) os_mutex_enter(os_file_count_mutex); os_file_n_pending_preads++; os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); n_bytes = pread(file, buf, (ssize_t)n, offs); os_mutex_enter(os_file_count_mutex); os_file_n_pending_preads--; os_n_pending_reads--; os_mutex_exit(os_file_count_mutex); return(n_bytes);#else { off_t ret_offset; ssize_t ret; ulint i; os_mutex_enter(os_file_count_mutex); os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); /* Protect the seek / read operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); ret_offset = lseek(file, offs, SEEK_SET); if (ret_offset < 0) { ret = -1; } else { ret = read(file, buf, (ssize_t)n); } os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; os_mutex_exit(os_file_count_mutex); return(ret); }#endif}/***********************************************************************Does a synchronous write operation in Posix. */staticssize_tos_file_pwrite(/*===========*/ /* out: number of bytes written, -1 if error */ os_file_t file, /* in: handle to a file */ const void* buf, /* in: buffer from where to write */ ulint n, /* in: number of bytes to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ ulint offset_high) /* in: most significant 32 bits of offset */{ ssize_t ret; off_t offs; ut_a((offset & 0xFFFFFFFFUL) == offset); /* If off_t is > 4 bytes in size, then we assume we can pass a 64-bit address */ if (sizeof(off_t) > 4) { offs = (off_t)offset + (((off_t)offset_high) << 32); } else { offs = (off_t)offset; if (offset_high > 0) { fprintf(stderr, "InnoDB: Error: file write at offset > 4 GB\n"); } } os_n_file_writes++;#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD) os_mutex_enter(os_file_count_mutex); os_file_n_pending_pwrites++; os_n_pending_writes++; os_mutex_exit(os_file_count_mutex); ret = pwrite(file, buf, (ssize_t)n, offs); os_mutex_enter(os_file_count_mutex); os_file_n_pending_pwrites--; os_n_pending_writes--; os_mutex_exit(os_file_count_mutex);# ifdef UNIV_DO_FLUSH if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC && srv_unix_file_flush_method != SRV_UNIX_NOSYNC && !os_do_not_call_flush_at_each_write) { /* Always do fsync to reduce the probability that when the OS crashes, a database page is only partially physically written to disk. */ ut_a(TRUE == os_file_flush(file)); }# endif /* UNIV_DO_FLUSH */ return(ret);#else { off_t ret_offset; ulint i; os_mutex_enter(os_file_count_mutex); os_n_pending_writes++; os_mutex_exit(os_file_count_mutex); /* Protect the seek / write operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); ret_offset = lseek(file, offs, SEEK_SET); if (ret_offset < 0) { ret = -1; goto func_exit; } ret = write(file, buf, (ssize_t)n);# ifdef UNIV_DO_FLUSH if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC && srv_unix_file_flush_method != SRV_UNIX_NOSYNC && !os_do_not_call_flush_at_each_write) { /* Always do fsync to reduce the probability that when the OS crashes, a database page is only partially physically written to disk. */ ut_a(TRUE == os_file_flush(file)); }# endif /* UNIV_DO_FLUSH */func_exit: os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_writes--; os_mutex_exit(os_file_count_mutex); return(ret); }#endif}#endif/***********************************************************************Requests a synchronous positioned read operation. */iboolos_file_read(/*=========*/ /* out: TRUE if request was successful, FALSE if fail */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read */ ulint offset, /* in: least significant 32 bits of file offset where to read */ ulint offset_high, /* in: most significant 32 bits of offset */ ulint n) /* in: number of bytes to read */ {#ifdef __WIN__ BOOL ret; DWORD len; DWORD ret2; DWORD low; DWORD high; ibool retry; ulint i; ut_a((offset & 0xFFFFFFFFUL) == offset); os_n_file_reads++; os_bytes_read_since_printout += n;try_again: ut_ad(file); ut_ad(buf); ut_ad(n > 0); low = (DWORD) offset; high = (DWORD) offset_high; os_mutex_enter(os_file_count_mutex); os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); /* Protect the seek / read operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -