nfs-ganesha 1.4

9p_interpreter.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 
00047 
00048 #include "nfs_core.h"
00049 #include "9p.h"
00050 #include "cache_inode.h"
00051 #include "fsal.h"
00052 #include "nfs_exports.h"
00053 #include "nfs_creds.h"
00054 #include "nfs_proto_functions.h"
00055 #include "nfs_dupreq.h"
00056 #include "nfs_file_handle.h"
00057 #include "nfs_stat.h"
00058 #include "SemN.h"
00059 
00060 /* This array maps a 9P Tmessage type to the 
00061  * related position in _9pfuncdesc array 
00062  * position=32 is "unknown function" */
00063 const int _9ptabindex[] =
00064     {32, 
00065      32, 32, 32, 32, 32, 32, 32,
00066       0, 32, 32, 32,  1, 32,  2,
00067      32,  3, 32,  4, 32,  5, 32,
00068       6, 32,  7, 32,  8, 32, 32,
00069      32,  9, 32, 10, 32, 32, 32,
00070      32, 32, 32, 32, 11, 32, 32,
00071      32, 32, 32, 32, 32, 32, 32,
00072      12, 32, 13, 32, 14, 32, 32,
00073      32, 32, 32, 32, 32, 32, 32,
00074      32, 32, 32, 32, 32, 32, 15,
00075      32, 16, 32, 17, 32, 18, 32,
00076      32, 32, 32, 32, 32, 32, 32,
00077      32, 32, 32, 32, 32, 32, 32,
00078      32, 32, 32, 32, 32, 32, 32,
00079      32, 19, 32, 20, 32, 21, 32,
00080      32, 32, 22, 32, 23, 32, 24,
00081      32, 25, 32, 26, 32, 27, 32,
00082      28, 32, 29, 32, 30, 32, 31  
00083 };
00084 
00085 const _9p_function_desc_t _9pfuncdesc[] = {
00086         { _9p_statfs, "_9P_TSTATFS"  },
00087         { _9p_lopen, "_9P_TLOPEN" },
00088         { _9p_lcreate, "_9P_TLCREATE" },
00089         { _9p_symlink, "_9P_TSYMLINK" },
00090         { _9p_mknod, "_9P_TMKNOD" },
00091         { _9p_rename, "_9P_TRENAME" },
00092         { _9p_readlink, "_9P_TREADLINK" },
00093         { _9p_getattr, "_9P_TGETATTR"},
00094         { _9p_setattr, "_9P_TSETATTR" },
00095         { _9p_xattrwalk, "_9P_TXATTRWALK" },
00096         { _9p_xattrcreate, "_9P_TXATTRCREATE" },
00097         { _9p_readdir, "_9P_TREADDIR" },
00098         { _9p_fsync, "_9P_TFSYNC" },
00099         { _9p_lock, "_9P_TLOCK" },
00100         { _9p_getlock, "_9P_TGETLOCK" },
00101         { _9p_link, "_9P_TLINK" },
00102         { _9p_mkdir, "_9P_TMKDIR" },
00103         { _9p_renameat, "_9P_TRENAMEAT" },
00104         { _9p_unlinkat, "_9P_TUNLINKAT" },
00105         { _9p_version, "_9P_TVERSION" },
00106         { _9p_auth, "_9P_TAUTH" },
00107         { _9p_attach, "_9P_TATTACH" },
00108         { _9p_flush, "_9P_TFLUSH" },
00109         { _9p_walk, "_9P_TWALK" },
00110         { _9p_not_2000L, "_9P_TOPEN" },
00111         { _9p_not_2000L, "_9P_TCREATE" },
00112         { _9p_read, "_9P_TREAD" },
00113         { _9p_write, "_9P_TWRITE" },
00114         { _9p_clunk, "_9P_TCLUNK" },
00115         { _9p_remove, "_9P_TREMOVE" },
00116         { _9p_not_2000L, "_9P_TSTAT" },
00117         { _9p_not_2000L, "_9P_TWSTAT" },
00118         { _9p_not_2000L, "no function" }
00119 } ;
00120 
00121 int _9p_not_2000L( _9p_request_data_t * preq9p, 
00122                    void * pworker_data,
00123                    u32 * plenout, 
00124                    char * preply)
00125 {
00126   char * msgdata = preq9p->_9pmsg + _9P_HDR_SIZE ;
00127   u8 * pmsgtype = NULL ;
00128   u16 msgtag = 0 ;
00129 
00130   /* Get message's type */
00131   pmsgtype = (u8 *)msgdata ;
00132   LogEvent( COMPONENT_9P,  "(%u|%s) is not a 9P2000.L message, returning ENOTSUP", 
00133             *pmsgtype,  _9pfuncdesc[_9ptabindex[*pmsgtype]].funcname  ) ;
00134 
00135   _9p_rerror( preq9p, &msgtag, ENOTSUP, plenout, preply ) ;
00136 
00137   return -1 ;
00138 } /* _9p_not_2000L */
00139 
00140 void _9p_process_request( _9p_request_data_t * preq9p, nfs_worker_data_t * pworker_data)
00141 {
00142   char * msgdata ;
00143   u32 * pmsglen = NULL ;
00144   u8 * pmsgtype = NULL ;
00145   u32 outdatalen = 0 ;
00146   int rc = 0 ; 
00147 
00148   char replydata[_9P_MSG_SIZE] ;
00149 
00150   msgdata =  preq9p->_9pmsg;
00151 
00152   /* Get message's length */
00153   pmsglen = (u32 *)msgdata ;
00154   msgdata += _9P_HDR_SIZE;
00155 
00156   /* Get message's type */
00157   pmsgtype = (u8 *)msgdata ;
00158   msgdata += _9P_TYPE_SIZE ;
00159 
00160   /* Check boundaries */
00161   if( *pmsgtype < _9P_TSTATFS || *pmsgtype > _9P_TWSTAT )
00162    return ;
00163 
00164   outdatalen = _9P_MSG_SIZE  -  _9P_HDR_SIZE ;
00165 
00166   LogFullDebug( COMPONENT_9P, "9P msg: length=%u type (%u|%s)",  *pmsglen, (u32)*pmsgtype, _9pfuncdesc[_9ptabindex[*pmsgtype]].funcname ) ;
00167 
00168   /* Call the 9P service function */  
00169   if(  ( ( rc = _9pfuncdesc[_9ptabindex[*pmsgtype]].service_function( preq9p, 
00170                                                                       (void *)pworker_data,
00171                                                                       &outdatalen, 
00172                                                                       replydata ) ) < 0 )  ||
00173 
00174              ( send( preq9p->pconn->sockfd, replydata, outdatalen, 0 ) != outdatalen ) )
00175      LogDebug( COMPONENT_9P, "%s: Error", _9pfuncdesc[_9ptabindex[*pmsgtype]].funcname ) ;
00176 
00177   return ;
00178 } /* _9p_process_request */
00179