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 GPFSFSAL_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 */
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 glock glock_args;
00072   struct set_get_lock_arg gpfs_sg_arg;
00073   glock_args.lfd = ((gpfsfsal_file_t *)p_file_descriptor)->fd;
00074   gpfsfsal_op_context_t *gpfs_op_cxt = (gpfsfsal_op_context_t *)p_context;
00075   gpfsfsal_file_t * pfd = (gpfsfsal_file_t *) p_file_descriptor;
00076 
00077   if(p_file_descriptor == NULL)
00078     {
00079       LogDebug(COMPONENT_FSAL, "p_file_descriptor arg is NULL.");
00080       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00081     }
00082   if(p_filehandle == NULL)
00083     {
00084       LogDebug(COMPONENT_FSAL, "p_filehandle arg is NULL.");
00085       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00086     }
00087   if(p_context == NULL)
00088     {
00089         LogDebug(COMPONENT_FSAL, "p_context arg is NULL.");
00090         Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00091     }
00092   if(p_owner == NULL)
00093     {
00094         LogDebug(COMPONENT_FSAL, "p_owner arg is NULL.");
00095         Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00096     }
00097 
00098   if(conflicting_lock == NULL && lock_op == FSAL_OP_LOCKT)
00099     {
00100       LogDebug(COMPONENT_FSAL,
00101                "Conflicting_lock argument can't be NULL with lock_op  = LOCKT");
00102       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op);
00103     }
00104 
00105   LogFullDebug(COMPONENT_FSAL,
00106                "Locking: op:%d type:%d start:%llu length:%llu owner:%p",
00107                lock_op, request_lock.lock_type,
00108                (unsigned long long)request_lock.lock_start,
00109                (unsigned long long)request_lock.lock_length, p_owner);
00110 
00111   if(lock_op == FSAL_OP_LOCKT)
00112     glock_args.cmd = F_GETLK;
00113   else if(lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK)
00114     glock_args.cmd = F_SETLK;
00115   else if(lock_op == FSAL_OP_LOCKB)
00116     glock_args.cmd = F_SETLKW;
00117   else if(lock_op == FSAL_OP_CANCEL)
00118     glock_args.cmd = 1029; // TODO FSF: hack - replace with GPFS_F_CANCELLK;
00119   else
00120     {
00121       LogDebug(COMPONENT_FSAL,
00122                "ERROR: Lock operation requested was not TEST, GET, or SET.");
00123       Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op);      
00124     }
00125 
00126   if(request_lock.lock_type == FSAL_LOCK_R)
00127     glock_args.flock.l_type = F_RDLCK;
00128   else if(request_lock.lock_type == FSAL_LOCK_W)
00129     glock_args.flock.l_type = F_WRLCK;
00130   else
00131     {
00132       LogDebug(COMPONENT_FSAL,
00133                "ERROR: The requested lock type was not read or write.");
00134       Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op);
00135     }
00136 
00137   if(lock_op == FSAL_OP_UNLOCK)
00138     glock_args.flock.l_type = F_UNLCK;
00139 
00140   glock_args.flock.l_len = request_lock.lock_length;
00141   glock_args.flock.l_start = request_lock.lock_start;
00142   glock_args.flock.l_whence = SEEK_SET;
00143 
00144   glock_args.lfd = pfd->fd;
00145   glock_args.lock_owner = p_owner;
00146   gpfs_sg_arg.mountdirfd = gpfs_op_cxt->export_context->mount_root_fd;
00147   gpfs_sg_arg.lock = &glock_args;
00148 
00149   errno = 0;
00150 
00151   retval = gpfs_ganesha(lock_op == FSAL_OP_LOCKT ?
00152       OPENHANDLE_GET_LOCK : OPENHANDLE_SET_LOCK, &gpfs_sg_arg);
00153 
00154   if(retval)
00155     {
00156       int errsv = errno;
00157 
00158       if((conflicting_lock != NULL) &&
00159          (lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_LOCKB))
00160         {
00161           int retval2;
00162           glock_args.cmd = F_GETLK;
00163           retval2 = gpfs_ganesha(OPENHANDLE_GET_LOCK, &gpfs_sg_arg);
00164           if(retval2)
00165             {
00166               LogCrit(COMPONENT_FSAL,
00167                       "After failing a set lock request, An attempt to get the current owner details also failed.");
00168             }
00169           else
00170             {
00171               conflicting_lock->lock_length = glock_args.flock.l_len;
00172               conflicting_lock->lock_start  = glock_args.flock.l_start;
00173               conflicting_lock->lock_type   = glock_args.flock.l_type;
00174             }
00175         }
00176       if(retval == 1)
00177         {
00178           LogFullDebug(COMPONENT_FSAL,
00179                        "GPFS queued blocked lock");
00180           Return(ERR_FSAL_BLOCKED, 0, INDEX_FSAL_lock_op);
00181         }
00182       else
00183         {
00184           LogFullDebug(COMPONENT_FSAL,
00185                        "GPFS lock operation failed error %d %d (%s)",
00186                        retval, errsv, strerror(errsv));
00187           Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lock_op);
00188         }
00189     }
00190 
00191   /* F_UNLCK is returned then the tested operation would be possible. */
00192   if(conflicting_lock != NULL)
00193     {
00194       if(lock_op == FSAL_OP_LOCKT && glock_args.flock.l_type != F_UNLCK)
00195         {
00196           conflicting_lock->lock_length = glock_args.flock.l_len;
00197           conflicting_lock->lock_start  = glock_args.flock.l_start;
00198           conflicting_lock->lock_type   = glock_args.flock.l_type;
00199         }
00200       else
00201         {
00202           conflicting_lock->lock_length = 0;
00203           conflicting_lock->lock_start  = 0;
00204           conflicting_lock->lock_type   = FSAL_NO_LOCK;
00205         }
00206     }
00207 
00208   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lock_op);
00209 }