nfs-ganesha 1.4
|
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