Drizzled Public API Documentation

my_sync.cc
00001 /* Copyright (C) 2003 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 #include <config.h>
00017 #include <drizzled/internal/my_sys.h>
00018 
00019 #include <errno.h>
00020 #include <fcntl.h>
00021 
00022 #include <drizzled/error.h>
00023 
00024 namespace drizzled
00025 {
00026 namespace internal
00027 {
00028 
00029 /*
00030   Sync data in file to disk
00031 
00032   SYNOPSIS
00033     my_sync()
00034     fd      File descritor to sync
00035     my_flags    Flags (now only MY_WME is supported)
00036 
00037   NOTE
00038     If file system supports its, only file data is synced, not inode data.
00039 
00040     MY_IGNORE_BADFD is useful when fd is "volatile" - not protected by a
00041     mutex. In this case by the time of fsync(), fd may be already closed by
00042     another thread, or even reassigned to a different file. With this flag -
00043     MY_IGNORE_BADFD - such a situation will not be considered an error.
00044     (which is correct behaviour, if we know that the other thread synced the
00045     file before closing)
00046 
00047   RETURN
00048     0 ok
00049     -1 error
00050 */
00051 
00052 int my_sync(int fd, myf my_flags)
00053 {
00054   int res;
00055 
00056   do
00057   {
00058 #if defined(F_FULLFSYNC)
00059     /*
00060       In Mac OS X >= 10.3 this call is safer than fsync() (it forces the
00061       disk's cache and guarantees ordered writes).
00062     */
00063     if (!(res= fcntl(fd, F_FULLFSYNC, 0)))
00064       break; /* ok */
00065     /* Some file systems don't support F_FULLFSYNC and fail above: */
00066 #endif
00067 #if defined(HAVE_FDATASYNC)
00068     res= fdatasync(fd);
00069 #else
00070     res= fsync(fd);
00071 #endif
00072   } while (res == -1 && errno == EINTR);
00073 
00074   if (res)
00075   {
00076     int er= errno;
00077     if (!(errno= er))
00078       errno= -1;                             /* Unknown error */
00079     if ((my_flags & MY_IGNORE_BADFD) &&
00080         (er == EBADF || er == EINVAL || er == EROFS))
00081     {
00082       res= 0;
00083     }
00084     else if (my_flags & MY_WME)
00085       my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), "unknown", errno);
00086   }
00087   return(res);
00088 } /* my_sync */
00089 
00090 
00091 static const char cur_dir_name[]= {FN_CURLIB, 0};
00092 /*
00093   Force directory information to disk.
00094 
00095   SYNOPSIS
00096     my_sync_dir()
00097     dir_name             the name of the directory
00098     my_flags             flags (MY_WME etc)
00099 
00100   RETURN
00101     0 if ok, !=0 if error
00102 */
00103 #ifdef NEED_EXPLICIT_SYNC_DIR
00104 int my_sync_dir(const char *dir_name, myf my_flags)
00105 {
00106   int dir_fd;
00107   int res= 0;
00108   const char *correct_dir_name;
00109   /* Sometimes the path does not contain an explicit directory */
00110   correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name;
00111   /*
00112     Syncing a dir may give EINVAL on tmpfs on Linux, which is ok.
00113     EIO on the other hand is very important. Hence MY_IGNORE_BADFD.
00114   */
00115   if ((dir_fd= my_open(correct_dir_name, O_RDONLY, MYF(my_flags))) >= 0)
00116   {
00117     if (my_sync(dir_fd, MYF(my_flags | MY_IGNORE_BADFD)))
00118       res= 2;
00119     if (my_close(dir_fd, MYF(my_flags)))
00120       res= 3;
00121   }
00122   else
00123     res= 1;
00124   return(res);
00125 }
00126 #else
00127 int my_sync_dir(const char *, myf)
00128 {
00129   return 0;
00130 }
00131 #endif
00132 
00133 
00134 /*
00135   Force directory information to disk.
00136 
00137   SYNOPSIS
00138     my_sync_dir_by_file()
00139     file_name            the name of a file in the directory
00140     my_flags             flags (MY_WME etc)
00141 
00142   RETURN
00143     0 if ok, !=0 if error
00144 */
00145 #ifdef NEED_EXPLICIT_SYNC_DIR
00146 int my_sync_dir_by_file(const char *file_name, myf my_flags)
00147 {
00148   char dir_name[FN_REFLEN];
00149   size_t dir_name_length;
00150   dirname_part(dir_name, file_name, &dir_name_length);
00151   return my_sync_dir(dir_name, my_flags);
00152 }
00153 #else
00154 int my_sync_dir_by_file(const char *, myf)
00155 {
00156   return 0;
00157 }
00158 #endif
00159 
00160 } /* namespace internal */
00161 } /* namespace drizzled */