nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 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 00037 #ifdef HAVE_CONFIG_H 00038 #include "config.h" 00039 #endif 00040 00041 #ifdef _SOLARIS 00042 #include "solaris_port.h" 00043 #endif 00044 00045 #include <stdio.h> 00046 #include <string.h> 00047 #include <pthread.h> 00048 #include <fcntl.h> 00049 #include <sys/file.h> /* for having FNDELAY */ 00050 #include "HashData.h" 00051 #include "HashTable.h" 00052 #include "log.h" 00053 #include "ganesha_rpc.h" 00054 #include "nfs23.h" 00055 #include "nfs4.h" 00056 #include "mount.h" 00057 #include "nfs_core.h" 00058 #include "cache_inode.h" 00059 #include "nfs_exports.h" 00060 #include "nfs_creds.h" 00061 #include "nfs_proto_functions.h" 00062 #include "nfs_tools.h" 00063 #include "nfs_proto_tools.h" 00064 00084 int nfs_Lookup(nfs_arg_t *parg, 00085 exportlist_t *pexport, 00086 fsal_op_context_t *pcontext, 00087 nfs_worker_data_t *pworker, 00088 struct svc_req *preq, 00089 nfs_res_t * pres) 00090 { 00091 cache_entry_t *pentry_dir = NULL; 00092 cache_entry_t *pentry_file = NULL; 00093 cache_inode_status_t cache_status; 00094 fsal_attrib_list_t attr; 00095 fsal_attrib_list_t attrdir; 00096 char *strpath = NULL; 00097 char strname[MAXNAMLEN]; 00098 unsigned int xattr_found = FALSE; 00099 fsal_name_t name; 00100 fsal_handle_t *pfsal_handle; 00101 int rc = NFS_REQ_OK; 00102 00103 if(isDebug(COMPONENT_NFSPROTO)) 00104 { 00105 char str[LEN_FH_STR]; 00106 00107 switch (preq->rq_vers) 00108 { 00109 case NFS_V2: 00110 strpath = parg->arg_lookup2.name; 00111 break; 00112 00113 case NFS_V3: 00114 strpath = parg->arg_lookup3.what.name; 00115 break; 00116 } 00117 00118 nfs_FhandleToStr(preq->rq_vers, 00119 &(parg->arg_lookup2.dir), 00120 &(parg->arg_lookup3.what.dir), 00121 NULL, 00122 str); 00123 LogDebug(COMPONENT_NFSPROTO, 00124 "REQUEST PROCESSING: Calling nfs_Lookup handle: %s name: %s", 00125 str, strpath); 00126 } 00127 00128 if(preq->rq_vers == NFS_V3) 00129 { 00130 /* to avoid setting it on each error case */ 00131 pres->res_lookup3.LOOKUP3res_u.resfail.dir_attributes.attributes_follow = FALSE; 00132 } 00133 00134 if((pentry_dir = nfs_FhandleToCache(preq->rq_vers, 00135 &(parg->arg_lookup2.dir), 00136 &(parg->arg_lookup3.what.dir), 00137 NULL, 00138 &(pres->res_dirop2.status), 00139 &(pres->res_lookup3.status), 00140 NULL, 00141 &attrdir, pcontext, &rc)) == NULL) 00142 { 00143 /* Stale NFS FH ? */ 00144 goto out; 00145 } 00146 00147 switch (preq->rq_vers) 00148 { 00149 case NFS_V2: 00150 strpath = parg->arg_lookup2.name; 00151 break; 00152 00153 case NFS_V3: 00154 strpath = parg->arg_lookup3.what.name; 00155 break; 00156 } 00157 00158 /* Do the lookup */ 00159 00160 #ifndef _NO_XATTRD 00161 /* Is this a .xattr.d.<object> name ? */ 00162 if(nfs_XattrD_Name(strpath, strname)) 00163 { 00164 strpath = strname; 00165 xattr_found = TRUE; 00166 } 00167 #endif 00168 00169 if((preq->rq_vers == NFS_V3) && 00170 (nfs3_Is_Fh_Xattr(&(parg->arg_lookup3.what.dir)))) { 00171 rc = nfs3_Lookup_Xattr(parg, pexport, pcontext, preq, pres); 00172 goto out; 00173 } 00174 00175 if((cache_status = cache_inode_error_convert(FSAL_str2name(strpath, 00176 FSAL_MAX_NAME_LEN, 00177 &name))) == 00178 CACHE_INODE_SUCCESS) 00179 { 00180 /* BUGAZOMEU: Faire la gestion des cross junction traverse */ 00181 if((pentry_file 00182 = cache_inode_lookup(pentry_dir, 00183 &name, 00184 &attr, 00185 pcontext, 00186 &cache_status)) != NULL) 00187 { 00188 /* Do not forget cross junction management */ 00189 pfsal_handle = &pentry_file->handle; 00190 if(cache_status == CACHE_INODE_SUCCESS) 00191 { 00192 switch (preq->rq_vers) 00193 { 00194 case NFS_V2: 00195 /* Build file handle */ 00196 if(nfs2_FSALToFhandle 00197 (&(pres->res_dirop2.DIROP2res_u.diropok.file), pfsal_handle, 00198 pexport)) 00199 { 00200 if(nfs2_FSALattr_To_Fattr(pexport, &attr, 00201 &(pres->res_dirop2.DIROP2res_u.diropok. 00202 attributes))) 00203 { 00204 pres->res_dirop2.status = NFS_OK; 00205 } 00206 } 00207 break; 00208 00209 case NFS_V3: 00210 /* Build FH */ 00211 if((pres->res_lookup3.LOOKUP3res_u.resok.object.data.data_val = 00212 gsh_malloc(sizeof(struct alloc_file_handle_v3))) == NULL) 00213 pres->res_lookup3.status = NFS3ERR_INVAL; 00214 else 00215 { 00216 if(nfs3_FSALToFhandle 00217 ((nfs_fh3 *) & 00218 (pres->res_lookup3.LOOKUP3res_u.resok.object.data), 00219 pfsal_handle, pexport)) 00220 { 00221 00222 #ifndef _NO_XATTRD 00223 /* If this is a xattr ghost directory name, update the FH */ 00224 if(xattr_found == TRUE) 00225 { 00226 pres->res_lookup3.status = 00227 nfs3_fh_to_xattrfh((nfs_fh3 *) & 00228 (pres->res_lookup3.LOOKUP3res_u. 00229 resok.object.data), 00230 (nfs_fh3 *) & (pres->res_lookup3. 00231 LOOKUP3res_u.resok. 00232 object.data)); 00233 /* Build entry attributes */ 00234 nfs_SetPostOpXAttrDir(pcontext, pexport, 00235 &attr, 00236 &(pres->res_lookup3.LOOKUP3res_u. 00237 resok.obj_attributes)); 00238 00239 } 00240 else 00241 #endif 00242 /* Build entry attributes */ 00243 nfs_SetPostOpAttr(pexport, 00244 &attr, 00245 &(pres->res_lookup3 00246 .LOOKUP3res_u.resok 00247 .obj_attributes)); 00248 00249 /* Build directory attributes */ 00250 nfs_SetPostOpAttr(pexport, 00251 &attrdir, 00252 &(pres->res_lookup3 00253 .LOOKUP3res_u.resok 00254 .dir_attributes)); 00255 00256 pres->res_lookup3.status = NFS3_OK; 00257 } /* if */ 00258 } /* else */ 00259 break; 00260 } /* case */ 00261 } /* if( cache_status == CACHE_INODE_SUCCESS ) */ 00262 } /* if( ( pentry_file = cache_inode_lookup... */ 00263 } 00264 00265 if(cache_status != CACHE_INODE_SUCCESS) 00266 { 00267 /* If we are here, there was an error */ 00268 if(nfs_RetryableError(cache_status)) { 00269 rc =NFS_REQ_DROP; 00270 goto out; 00271 } 00272 00273 nfs_SetFailedStatus(pcontext, pexport, 00274 preq->rq_vers, 00275 cache_status, 00276 &pres->res_dirop2.status, 00277 &pres->res_lookup3.status, 00278 pentry_dir, 00279 &(pres->res_lookup3.LOOKUP3res_u.resfail.dir_attributes), 00280 NULL, NULL, NULL, NULL, NULL, NULL); 00281 } 00282 00283 rc = NFS_REQ_OK; 00284 00285 out: 00286 /* return references */ 00287 if (pentry_dir) 00288 cache_inode_put(pentry_dir); 00289 00290 if (pentry_file) 00291 cache_inode_put(pentry_file); 00292 00293 return (rc); 00294 00295 } /* nfs_Lookup */ 00296 00305 void nfs3_Lookup_Free(nfs_res_t * resp) 00306 { 00307 if(resp->res_lookup3.status == NFS3_OK) 00308 gsh_free(resp->res_lookup3.LOOKUP3res_u.resok.object.data.data_val); 00309 } /* nfs_Lookup_Free */ 00310 00319 void nfs2_Lookup_Free(nfs_res_t * resp) 00320 { 00321 /* nothing to do */ 00322 return; 00323 } /* nfs_Lookup_Free */