nfs-ganesha 1.4

fsal_lock.c

Go to the documentation of this file.
00001 /*
00002  * Copyright IBM Corporation, 2010
00003  *  Contributor: Aneesh Kumar K.v  <aneesh.kumar@linux.vnet.ibm.com>
00004  *
00005  *
00006  * This software is a server that implements the NFS protocol.
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  * 
00023  *
00024  */
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif
00028 
00029 #include "fsal.h"
00030 #include "fsal_internal.h"
00031 #include "fsal_convert.h"
00032 
00062 fsal_status_t LUSTREFSAL_lock_op( fsal_file_t       * p_file_descriptor,   /* IN */
00063                                   fsal_handle_t     * p_filehandle,        /* IN */
00064                                   fsal_op_context_t * p_context,           /* IN */
00065                                   void              * p_owner,             /* IN (opaque to FSAL) */
00066                                   fsal_lock_op_t      lock_op,             /* IN */
00067                                   fsal_lock_param_t   request_lock,        /* IN */
00068                                   fsal_lock_param_t * conflicting_lock)    /* OUT */
00069 {
00070   int retval;
00071   struct flock lock_args;
00072   int fcntl_comm;
00073   lustrefsal_file_t * pfd = (lustrefsal_file_t *) p_file_descriptor;
00074 
00075   if(p_file_descriptor == NULL || p_filehandle == NULL || p_context == NULL)
00076     {
00077       if(p_file_descriptor == NULL)
00078         LogDebug(COMPONENT_FSAL, "p_file_descriptor argument is NULL.");
00079       if(p_filehandle == NULL)
00080         LogDebug(COMPONENT_FSAL, "p_filehandle argument is NULL.");
00081       if(p_context == NULL)
00082         LogDebug(COMPONENT_FSAL, "p_context argument is NULL.");
00083       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00084     }
00085 
00086   if(p_owner != NULL)
00087     Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op);
00088 
00089   if(conflicting_lock == NULL && lock_op == FSAL_OP_LOCKT)
00090     {
00091       LogDebug(COMPONENT_FSAL, "conflicting_lock argument can't"
00092                " be NULL with lock_op  = LOCKT");
00093       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00094     }
00095 
00096   LogFullDebug(COMPONENT_FSAL, "Locking: op:%d type:%d start:%llu length:%llu ", lock_op,
00097                request_lock.lock_type, (unsigned long long)request_lock.lock_start,
00098               (unsigned long long)request_lock.lock_length);
00099 
00100   if(lock_op == FSAL_OP_LOCKT)
00101     fcntl_comm = F_GETLK;
00102   else if(lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK)
00103     fcntl_comm = F_SETLK;
00104   else
00105     {
00106       LogDebug(COMPONENT_FSAL, "ERROR: Lock operation requested was not TEST, READ, or WRITE.");
00107       Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op);      
00108     }
00109 
00110   if(request_lock.lock_type == FSAL_LOCK_R)
00111     lock_args.l_type = F_RDLCK;
00112   else if(request_lock.lock_type == FSAL_LOCK_W)
00113     lock_args.l_type = F_WRLCK;
00114   else
00115     {
00116       LogDebug(COMPONENT_FSAL, "ERROR: The requested lock type was not read or write.");
00117       Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op);
00118     }
00119 
00120   if(lock_op == FSAL_OP_UNLOCK)
00121     lock_args.l_type = F_UNLCK;
00122 
00123   lock_args.l_len = request_lock.lock_length;
00124   lock_args.l_start = request_lock.lock_start;
00125   lock_args.l_whence = SEEK_SET;
00126 
00127   errno = 0;
00128   retval = fcntl(pfd->fd, fcntl_comm, &lock_args);
00129   if(retval && lock_op == FSAL_OP_LOCK)
00130     {
00131       if(conflicting_lock != NULL)
00132         {
00133           fcntl_comm = F_GETLK;
00134           retval = fcntl(pfd->fd, fcntl_comm, &lock_args);
00135           if(retval)
00136             {
00137               LogCrit(COMPONENT_FSAL, "After failing a lock request, I couldn't even"
00138                       " get the details of who owns the lock.");
00139               Return(posix2fsal_error(errno), errno, INDEX_FSAL_lock_op);
00140             }
00141           if(conflicting_lock != NULL)
00142             {
00143               conflicting_lock->lock_length = lock_args.l_len;
00144               conflicting_lock->lock_start = lock_args.l_start;
00145               conflicting_lock->lock_type = lock_args.l_type;
00146             }
00147         }
00148       Return(posix2fsal_error(errno), errno, INDEX_FSAL_lock_op);
00149     }
00150 
00151   /* F_UNLCK is returned then the tested operation would be possible. */
00152   if(conflicting_lock != NULL)
00153     {
00154       if(lock_op == FSAL_OP_LOCKT && lock_args.l_type != F_UNLCK)
00155         {
00156           conflicting_lock->lock_length = lock_args.l_len;
00157           conflicting_lock->lock_start = lock_args.l_start;
00158           conflicting_lock->lock_type = lock_args.l_type;
00159         }
00160       else
00161         {
00162           conflicting_lock->lock_length = 0;
00163           conflicting_lock->lock_start = 0;
00164           conflicting_lock->lock_type = FSAL_NO_LOCK;
00165         }
00166     }
00167 
00168   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lock_op);
00169 }