Drizzled Public API Documentation

my_sync.cc
1 /* Copyright (C) 2003 MySQL AB
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include <config.h>
17 #include <drizzled/internal/my_sys.h>
18 
19 #include <errno.h>
20 #include <fcntl.h>
21 
22 #include <drizzled/error.h>
23 
24 namespace drizzled
25 {
26 namespace internal
27 {
28 
29 /*
30  Sync data in file to disk
31 
32  SYNOPSIS
33  my_sync()
34  fd File descritor to sync
35  my_flags Flags (now only MY_WME is supported)
36 
37  NOTE
38  If file system supports its, only file data is synced, not inode data.
39 
40  MY_IGNORE_BADFD is useful when fd is "volatile" - not protected by a
41  mutex. In this case by the time of fsync(), fd may be already closed by
42  another thread, or even reassigned to a different file. With this flag -
43  MY_IGNORE_BADFD - such a situation will not be considered an error.
44  (which is correct behaviour, if we know that the other thread synced the
45  file before closing)
46 
47  RETURN
48  0 ok
49  -1 error
50 */
51 
52 int my_sync(int fd, myf my_flags)
53 {
54  int res;
55 
56  do
57  {
58 #if defined(F_FULLFSYNC)
59  /*
60  In Mac OS X >= 10.3 this call is safer than fsync() (it forces the
61  disk's cache and guarantees ordered writes).
62  */
63  if (!(res= fcntl(fd, F_FULLFSYNC, 0)))
64  break; /* ok */
65  /* Some file systems don't support F_FULLFSYNC and fail above: */
66 #endif
67 #if defined(HAVE_FDATASYNC)
68  res= fdatasync(fd);
69 #else
70  res= fsync(fd);
71 #endif
72  } while (res == -1 && errno == EINTR);
73 
74  if (res)
75  {
76  int er= errno;
77  if (!(errno= er))
78  errno= -1; /* Unknown error */
79  if ((my_flags & MY_IGNORE_BADFD) &&
80  (er == EBADF || er == EINVAL || er == EROFS))
81  {
82  res= 0;
83  }
84  else if (my_flags & MY_WME)
85  my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), "unknown", errno);
86  }
87  return res;
88 } /* my_sync */
89 
90 
91 static const char cur_dir_name[]= {FN_CURLIB, 0};
92 /*
93  Force directory information to disk.
94 
95  SYNOPSIS
96  my_sync_dir()
97  dir_name the name of the directory
98  my_flags flags (MY_WME etc)
99 
100  RETURN
101  0 if ok, !=0 if error
102 */
103 #ifdef NEED_EXPLICIT_SYNC_DIR
104 int my_sync_dir(const char *dir_name, myf my_flags)
105 {
106  int dir_fd;
107  int res= 0;
108  const char *correct_dir_name;
109  /* Sometimes the path does not contain an explicit directory */
110  correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name;
111  /*
112  Syncing a dir may give EINVAL on tmpfs on Linux, which is ok.
113  EIO on the other hand is very important. Hence MY_IGNORE_BADFD.
114  */
115  if ((dir_fd= my_open(correct_dir_name, O_RDONLY, MYF(my_flags))) >= 0)
116  {
117  if (my_sync(dir_fd, MYF(my_flags | MY_IGNORE_BADFD)))
118  res= 2;
119  if (my_close(dir_fd, MYF(my_flags)))
120  res= 3;
121  }
122  else
123  res= 1;
124  return res;
125 }
126 #else
127 int my_sync_dir(const char *, myf)
128 {
129  return 0;
130 }
131 #endif
132 
133 
134 /*
135  Force directory information to disk.
136 
137  SYNOPSIS
138  my_sync_dir_by_file()
139  file_name the name of a file in the directory
140  my_flags flags (MY_WME etc)
141 
142  RETURN
143  0 if ok, !=0 if error
144 */
145 #ifdef NEED_EXPLICIT_SYNC_DIR
146 int my_sync_dir_by_file(const char *file_name, myf my_flags)
147 {
148  char dir_name[FN_REFLEN];
149  size_t dir_name_length;
150  dirname_part(dir_name, file_name, &dir_name_length);
151  return my_sync_dir(dir_name, my_flags);
152 }
153 #else
154 int my_sync_dir_by_file(const char *, myf)
155 {
156  return 0;
157 }
158 #endif
159 
160 } /* namespace internal */
161 } /* namespace drizzled */