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 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