root/ompi/mca/io/romio321/romio/adio/common/lock.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_Set_lock
  2. ADIOI_Set_lock
  3. ADIOI_Set_lock64

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *
   4  *   Copyright (C) 1997 University of Chicago. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include "adio.h"
   9 
  10 #ifdef ROMIO_NTFS
  11 /* This assumes that lock will always remain in the common directory and 
  12  * that the ntfs directory will always be called ad_ntfs. */
  13 #include "..\ad_ntfs\ad_ntfs.h"
  14 int ADIOI_Set_lock(FDTYPE fd, int cmd, int type, ADIO_Offset offset, int whence,
  15              ADIO_Offset len) 
  16 {
  17     static char myname[] = "ADIOI_Set_lock";
  18     int ret_val, error_code = MPI_SUCCESS;
  19     OVERLAPPED Overlapped;
  20     DWORD dwFlags;
  21 
  22     ADIOI_UNREFERENCED_ARG(whence);
  23 
  24     if (len == 0) return MPI_SUCCESS;
  25 
  26     dwFlags = type;
  27 
  28     Overlapped.hEvent = /*0;*/CreateEvent(NULL, TRUE, FALSE, NULL);
  29 #ifdef HAVE_INT64
  30     Overlapped.Offset = ( (DWORD) ( offset & (__int64) 0xFFFFFFFF ) );
  31     Overlapped.OffsetHigh = ( (DWORD) ( (offset >> 32) & (__int64) 0xFFFFFFFF ) );
  32 
  33     if (cmd == ADIOI_LOCK_CMD)
  34     {
  35         /*printf("locking %d\n", (int)fd);fflush(stdout);*/
  36         ret_val = LockFileEx(fd, dwFlags, 0, 
  37         ( (DWORD) ( len & (__int64) 0xFFFFFFFF ) ), 
  38         ( (DWORD) ( (len >> 32) & (__int64) 0xFFFFFFFF ) ), 
  39         &Overlapped);
  40     }
  41     else
  42     {
  43         /*printf("unlocking %d\n", (int)fd);fflush(stdout);*/
  44         ret_val = UnlockFileEx(fd, 0, 
  45         ( (DWORD) ( len & (__int64) 0xFFFFFFFF ) ), 
  46         ( (DWORD) ( (len >> 32) & (__int64) 0xFFFFFFFF ) ), 
  47         &Overlapped);
  48     }
  49 #else
  50     Overlapped.Offset = offset;
  51     Overlapped.OffsetHigh = 0;
  52 
  53     if (cmd == ADIOI_LOCK_CMD)
  54     {
  55         /*printf("locking %d\n", (int)fd);fflush(stdout);*/
  56         ret_val = LockFileEx(fd, dwFlags, 0, len, 0, &Overlapped);
  57     }
  58     else
  59     {
  60         /*printf("unlocking %d\n", (int)fd);fflush(stdout);*/
  61         ret_val = UnlockFileEx(fd, 0, len, 0, &Overlapped);
  62     }
  63 #endif
  64 
  65     if (!ret_val)
  66     {
  67     char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
  68         /*
  69         FPRINTF(stderr, "File locking failed in ADIOI_Set_lock.\n");
  70         MPI_Abort(MPI_COMM_WORLD, 1);
  71         */
  72         ret_val = GetLastError();
  73         if (ret_val == ERROR_IO_PENDING)
  74         {
  75             DWORD dummy;
  76             ret_val = GetOverlappedResult(fd, &Overlapped, &dummy, TRUE);
  77             if (ret_val)
  78             {
  79                 CloseHandle(Overlapped.hEvent);
  80                 return MPI_SUCCESS;
  81             }
  82             ret_val = GetLastError();
  83         }
  84     ADIOI_NTFS_Strerror(ret_val, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
  85         error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__,
  86             MPI_ERR_IO, "**io", "**io %s", errMsg);
  87     }
  88     CloseHandle(Overlapped.hEvent);
  89 
  90     return error_code;
  91 }
  92 #else
  93 int ADIOI_Set_lock(FDTYPE fd, int cmd, int type, ADIO_Offset offset, int whence,
  94              ADIO_Offset len) 
  95 {
  96     int err, error_code, err_count = 0, sav_errno;
  97     struct flock lock;
  98 
  99     if (len == 0) return MPI_SUCCESS;
 100 
 101 
 102     /* Depending on the compiler flags and options, struct flock 
 103        may not be defined with types that are the same size as
 104        ADIO_Offsets.  */
 105 /* FIXME: This is a temporary hack until we use flock64 where
 106    available. It also doesn't fix the broken Solaris header sys/types.h
 107    header file, which declars off_t as a UNION ! Configure tests to
 108    see if the off64_t is a union if large file support is requested; 
 109    if so, it does not select large file support.
 110 */
 111 #ifdef NEEDS_INT_CAST_WITH_FLOCK
 112     lock.l_type   = type;
 113     lock.l_start  = (int)offset;
 114     lock.l_whence = whence;
 115     lock.l_len    = (int)len;
 116 #else
 117     lock.l_type   = type;
 118     lock.l_whence = whence;
 119     lock.l_start  = offset;
 120     lock.l_len    = len;
 121 #endif
 122 
 123     sav_errno = errno; /* save previous errno in case we recover from retryable errors */
 124     errno = 0;
 125     do {
 126         err = fcntl(fd, cmd, &lock);
 127 #ifdef USE_DBG_LOGGING
 128 /*      if (MPIU_DBG_SELECTED(ROMIO,TERSE)) */
 129       {
 130         if (err && ((errno == EINTR) || (errno == EINPROGRESS)))
 131         {
 132           if((err_count < 5) || (err_count > 9995))
 133           {
 134             fprintf(stderr, "File locking failed in ADIOI_Set_lock(fd %#X,cmd %s/%#X,type %s/%#X,whence %#X) with return value %#X and errno %#X.  Retry (%d).\n",                    
 135                     fd,
 136                     ((cmd == F_GETLK   )? "F_GETLK" :
 137                     ((cmd == F_SETLK   )? "F_SETLK" :
 138                     ((cmd == F_SETLKW  )? "F_SETLKW" : "UNEXPECTED"))),
 139                     cmd, 
 140                     ((type == F_RDLCK   )? "F_RDLCK" :
 141                     ((type == F_WRLCK   )? "F_WRLCK" :
 142                     ((type == F_UNLCK   )? "F_UNLOCK" : "UNEXPECTED"))),
 143                     type, 
 144                     whence, err, errno, err_count);
 145           perror("ADIOI_Set_lock:");
 146           fprintf(stderr,"ADIOI_Set_lock:offset %#llx, length %#llx\n",(unsigned long long)offset, (unsigned long long)len);
 147           }
 148         }
 149       }
 150 #endif
 151     } while (err && ((errno == EINTR) || ((errno == EINPROGRESS) && (++err_count < 10000))));
 152 
 153     if (err && (errno != EBADF)) {
 154         /* FIXME: This should use the error message system, 
 155            especially for MPICH */
 156         FPRINTF(stderr, "This requires fcntl(2) to be implemented. As of 8/25/2011 it is not. Generic MPICH Message: File locking failed in ADIOI_Set_lock(fd %X,cmd %s/%X,type %s/%X,whence %X) with return value %X and errno %X.\n"
 157                   "- If the file system is NFS, you need to use NFS version 3, ensure that the lockd daemon is running on all the machines, and mount the directory with the 'noac' option (no attribute caching).\n"
 158                   "- If the file system is LUSTRE, ensure that the directory is mounted with the 'flock' option.\n",
 159           fd,
 160           ((cmd == F_GETLK   )? "F_GETLK" :
 161           ((cmd == F_SETLK   )? "F_SETLK" :
 162           ((cmd == F_SETLKW  )? "F_SETLKW" : "UNEXPECTED"))),
 163           cmd, 
 164           ((type == F_RDLCK   )? "F_RDLCK" :
 165           ((type == F_WRLCK   )? "F_WRLCK" :
 166           ((type == F_UNLCK   )? "F_UNLOCK" : "UNEXPECTED"))),
 167           type, 
 168           whence, err, errno);
 169   perror("ADIOI_Set_lock:");
 170   FPRINTF(stderr,"ADIOI_Set_lock:offset %llu, length %llu\n",(unsigned long long)offset, (unsigned long long)len);
 171         MPI_Abort(MPI_COMM_WORLD, 1);
 172     }
 173 
 174     if(!err)             /* report fcntl failure errno's (EBADF), otherwise */
 175       errno = sav_errno; /* restore previous errno in case we recovered from retryable errors */
 176 
 177     error_code = (err == 0) ? MPI_SUCCESS : MPI_ERR_UNKNOWN;
 178     return error_code;
 179 }
 180 #endif
 181 
 182 #if (defined(ROMIO_HFS) || defined(ROMIO_XFS))
 183 int ADIOI_Set_lock64(FDTYPE fd, int cmd, int type, ADIO_Offset offset,
 184                      int whence,
 185                      ADIO_Offset len) 
 186 {
 187     int err, error_code;
 188     struct flock64 lock;
 189 
 190     if (len == 0) return MPI_SUCCESS;
 191 
 192     lock.l_type = type;
 193     lock.l_start = offset;
 194     lock.l_whence = whence;
 195     lock.l_len = len;
 196 
 197     do {
 198         err = fcntl(fd, cmd, &lock);
 199     } while (err && (errno == EINTR));
 200 
 201     if (err && (errno != EBADF)) {
 202         FPRINTF(stderr, "File locking failed in ADIOI_Set_lock64(fd %X,cmd %s/%X,type %s/%X,whence %X) with return value %X and errno %X.\n"
 203                   "If the file system is NFS, you need to use NFS version 3, ensure that the lockd daemon is running on all the machines, and mount the directory with the 'noac' option (no attribute caching).\n",
 204           fd,
 205           ((cmd == F_GETLK   )? "F_GETLK" :
 206           ((cmd == F_SETLK   )? "F_SETLK" :
 207           ((cmd == F_SETLKW  )? "F_SETLKW" :
 208           ((cmd == F_GETLK64 )? "F_GETLK64" :
 209           ((cmd == F_SETLK64 )? "F_SETLK64" :
 210           ((cmd == F_SETLKW64)? "F_SETLKW64" : "UNEXPECTED")))))),
 211           cmd, 
 212           ((type == F_RDLCK   )? "F_RDLCK" :
 213           ((type == F_WRLCK   )? "F_WRLCK" :
 214           ((type == F_UNLCK   )? "F_UNLOCK" : "UNEXPECTED"))),
 215           type, 
 216           whence, err, errno);
 217   perror("ADIOI_Set_lock64:");
 218   FPRINTF(stderr,"ADIOI_Set_lock:offset %llu, length %llu\n",(unsigned long long)offset, (unsigned long long)len);
 219         MPI_Abort(MPI_COMM_WORLD, 1);
 220     }
 221 
 222     error_code = (err == 0) ? MPI_SUCCESS : MPI_ERR_UNKNOWN;
 223     return error_code;
 224 }
 225 #endif

/* [<][>][^][v][top][bottom][index][help] */