nfs-ganesha 1.4

9p_lock.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2011)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
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 
00035 #ifdef HAVE_CONFIG_H
00036 #include "config.h"
00037 #endif
00038 
00039 #ifdef _SOLARIS
00040 #include "solaris_port.h"
00041 #endif
00042 
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <pthread.h>
00046 #include <sys/stat.h>
00047 #include <netdb.h>
00048 #include "nfs_core.h"
00049 #include "log.h"
00050 #include "cache_inode.h"
00051 #include "sal_functions.h"
00052 #include "fsal.h"
00053 #include "9p.h"
00054 
00055 extern int h_errno;
00056 
00057 int _9p_lock( _9p_request_data_t * preq9p, 
00058               void  * pworker_data,
00059               u32 * plenout, 
00060               char * preply)
00061 {
00062   char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ;
00063  
00064   u16  * msgtag        = NULL ;
00065   u32  * fid           = NULL ;
00066   u8   * type          = NULL ;
00067   u32  * flags         = NULL ;
00068   u64  * start         = NULL ;
00069   u64  * length        = NULL ;
00070   u32  * proc_id       = NULL ;
00071   u16  * client_id_len = NULL ;
00072   char * client_id_str = NULL ;
00073 
00074   u8 status = 0  ;
00075   state_status_t state_status = STATE_SUCCESS;
00076   state_owner_t      * holder ;
00077   state_owner_t      * powner ;
00078   state_t              state ;
00079   fsal_lock_param_t    lock ;
00080   fsal_lock_param_t    conflict;
00081 
00082   char name[MAXNAMLEN] ;
00083 
00084   struct hostent *hp ;
00085   struct sockaddr_storage client_addr ; 
00086 
00087   _9p_fid_t * pfid = NULL ;
00088 
00089   if ( !preq9p || !pworker_data || !plenout || !preply )
00090    return -1 ;
00091 
00092   /* Get data */
00093   _9p_getptr( cursor, msgtag, u16 ) ; 
00094   
00095   _9p_getptr( cursor, fid,     u32 ) ; 
00096   _9p_getptr( cursor, type,    u8 )  ;
00097   _9p_getptr( cursor, flags,   u32 ) ;
00098   _9p_getptr( cursor, start,   u64 ) ;
00099   _9p_getptr( cursor, length,  u64 ) ;
00100   _9p_getptr( cursor, proc_id, u32 ) ;
00101   _9p_getstr( cursor, client_id_len, client_id_str ) ;
00102 
00103   LogDebug( COMPONENT_9P, "TLOCK: tag=%u fid=%u type=%u flags=0x%x start=%llu length=%llu proc_id=%u client=%.*s",
00104             (u32)*msgtag, *fid, *type, *flags, (unsigned long long)*start, (unsigned long long)*length, 
00105             *proc_id, *client_id_len, client_id_str ) ;
00106 
00107   if( *fid >= _9P_FID_PER_CONN )
00108     return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ;
00109 
00110   pfid = &preq9p->pconn->fids[*fid] ;
00111 
00112   /* get the client's ip addr */
00113   snprintf( name, MAXNAMLEN, "%.*s",*client_id_len, client_id_str ) ;
00114 
00115   if( ( hp = gethostbyname( name ) ) == NULL )
00116     return _9p_rerror( preq9p, msgtag, EINVAL, plenout, preply ) ;
00117 
00118   memcpy( (char *)&client_addr, hp->h_addr, hp->h_length ) ;
00119 
00120   if( ( powner = get_9p_owner( &client_addr, *proc_id ) ) == NULL )
00121     return _9p_rerror( preq9p, msgtag, EINVAL, plenout, preply ) ;
00122 
00123   /* Do the job */
00124   switch( *type )
00125    {
00126       case _9P_LOCK_TYPE_RDLCK:
00127       case _9P_LOCK_TYPE_WRLCK:
00128         /* Fill in plock */
00129         lock.lock_type   = (*type == _9P_LOCK_TYPE_WRLCK) ? FSAL_LOCK_W : FSAL_LOCK_R;
00130         lock.lock_start  = *start ;
00131         lock.lock_length = *length ;
00132 
00133         if(nfs_in_grace())
00134          {
00135              status = _9P_LOCK_GRACE ;
00136              break ;
00137          }
00138 
00139         if( state_lock( pfid->pentry,
00140                         &pfid->fsal_op_context,
00141                         pfid->pexport,
00142                         powner,
00143                         &state,
00144                         STATE_NON_BLOCKING,
00145                         NULL,
00146                         &lock,
00147                         &holder,
00148                         &conflict,
00149                         &state_status) != STATE_SUCCESS)
00150            {
00151               if( state_status == STATE_LOCK_BLOCKED ) 
00152                 status = _9P_LOCK_BLOCKED ;
00153               else
00154                 status = _9P_LOCK_ERROR ;
00155            }
00156         else
00157           status = _9P_LOCK_SUCCESS ;
00158 
00159         break ;
00160 
00161       case _9P_LOCK_TYPE_UNLCK:
00162          if(state_unlock( pfid->pentry,
00163                           &pfid->fsal_op_context,
00164                           pfid->pexport,
00165                           powner,
00166                           NULL,
00167                           &lock,
00168                           &state_status) != STATE_SUCCESS)
00169              status = _9P_LOCK_ERROR ;
00170          else
00171              status = _9P_LOCK_SUCCESS ;
00172 
00173         break ;
00174 
00175       default:
00176         return _9p_rerror( preq9p, msgtag, EINVAL, plenout, preply ) ;
00177         break ;
00178    } /* switch( *type ) */ 
00179 
00180   /* Build the reply */
00181   _9p_setinitptr( cursor, preply, _9P_RLOCK ) ;
00182   _9p_setptr( cursor, msgtag, u16 ) ;
00183 
00184   _9p_setvalue( cursor, status, u8 ) ;
00185 
00186   _9p_setendptr( cursor, preply ) ;
00187   _9p_checkbound( cursor, preply, plenout ) ;
00188 
00189   LogDebug( COMPONENT_9P, "RLOCK: tag=%u fid=%u type=%u flags=0x%x start=%llu length=%llu proc_id=%u client=%.*s status=%u",
00190             (u32)*msgtag, *fid, *type, *flags, (unsigned long long)*start, (unsigned long long)*length, 
00191             *proc_id, *client_id_len, client_id_str, status ) ;
00192 
00193   return 1 ;
00194 }
00195