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 00038 #ifdef HAVE_CONFIG_H 00039 #include "config.h" 00040 #endif 00041 00042 #ifdef _SOLARIS 00043 #include "solaris_port.h" 00044 #endif 00045 00046 #include <stdio.h> 00047 #include <string.h> 00048 #include <pthread.h> 00049 #include <fcntl.h> 00050 #include <sys/file.h> /* for having FNDELAY */ 00051 #include "HashData.h" 00052 #include "HashTable.h" 00053 #include "log.h" 00054 #include "ganesha_rpc.h" 00055 #include "nfs23.h" 00056 #include "nfs4.h" 00057 #include "mount.h" 00058 #include "nfs_core.h" 00059 #include "cache_inode.h" 00060 #include "nfs_exports.h" 00061 #include "nfs_creds.h" 00062 #include "nfs_proto_functions.h" 00063 #include "nfs_tools.h" 00064 #include "nfs_proto_tools.h" 00065 00085 int nfs_Getattr(nfs_arg_t *parg, 00086 exportlist_t *pexport, 00087 fsal_op_context_t *pcontext, 00088 nfs_worker_data_t *pworker, 00089 struct svc_req *preq, 00090 nfs_res_t *pres) 00091 { 00092 fsal_attrib_list_t attr; 00093 cache_entry_t *pentry = NULL; 00094 cache_inode_status_t cache_status; 00095 int rc = NFS_REQ_OK; 00096 00097 if(isDebug(COMPONENT_NFSPROTO)) 00098 { 00099 char str[LEN_FH_STR]; 00100 nfs_FhandleToStr(preq->rq_vers, 00101 &(parg->arg_getattr2), 00102 &(parg->arg_getattr3.object), 00103 NULL, 00104 str); 00105 LogDebug(COMPONENT_NFSPROTO, 00106 "REQUEST PROCESSING: Calling nfs_Getattr handle: %s", str); 00107 } 00108 00109 if((pentry = nfs_FhandleToCache(preq->rq_vers, 00110 &(parg->arg_getattr2), 00111 &(parg->arg_getattr3.object), 00112 NULL, 00113 &(pres->res_attr2.status), 00114 &(pres->res_getattr3.status), 00115 NULL, &attr, pcontext, &rc)) == NULL) 00116 { 00117 /* Stale NFS FH ? */ 00118 LogFullDebug(COMPONENT_NFSPROTO, 00119 "nfs_Getattr returning %d", rc); 00120 goto out; 00121 } 00122 00123 if((preq->rq_vers == NFS_V3) && (nfs3_Is_Fh_Xattr(&(parg->arg_getattr3.object)))) 00124 { 00125 rc = nfs3_Getattr_Xattr(parg, pexport, pcontext, preq, pres); 00126 LogFullDebug(COMPONENT_NFSPROTO, 00127 "nfs_Getattr returning %d from nfs3_Getattr_Xattr", rc); 00128 goto out; 00129 } 00130 00131 /* 00132 * Get attributes. Use NULL for the file name since we have the 00133 * vnode to define the file. 00134 */ 00135 if(cache_inode_getattr(pentry, 00136 &attr, 00137 pcontext, &cache_status) == CACHE_INODE_SUCCESS) 00138 { 00139 /* 00140 * Client API should be keeping us from crossing junctions, 00141 * but double check to be sure. 00142 */ 00143 00144 switch (preq->rq_vers) 00145 { 00146 00147 case NFS_V2: 00148 /* Copy data from vattr to Attributes */ 00149 if(nfs2_FSALattr_To_Fattr(pexport, &attr, 00150 &(pres->res_attr2.ATTR2res_u.attributes)) == 0) 00151 { 00152 nfs_SetFailedStatus(pcontext, pexport, 00153 preq->rq_vers, 00154 CACHE_INODE_INVALID_ARGUMENT, 00155 &pres->res_attr2.status, 00156 &pres->res_getattr3.status, 00157 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00158 LogFullDebug(COMPONENT_NFSPROTO, 00159 "nfs_Getattr set failed status v2"); 00160 rc = NFS_REQ_OK; 00161 goto out; 00162 } 00163 pres->res_attr2.status = NFS_OK; 00164 break; 00165 00166 case NFS_V3: 00167 if(nfs3_FSALattr_To_Fattr(pexport, &attr, 00168 &(pres->res_getattr3.GETATTR3res_u.resok. 00169 obj_attributes)) == 0) 00170 { 00171 nfs_SetFailedStatus(pcontext, pexport, 00172 preq->rq_vers, 00173 CACHE_INODE_INVALID_ARGUMENT, 00174 &pres->res_attr2.status, 00175 &pres->res_getattr3.status, 00176 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00177 00178 LogFullDebug(COMPONENT_NFSPROTO, 00179 "nfs_Getattr set failed status v3"); 00180 rc = NFS_REQ_OK; 00181 goto out; 00182 } 00183 pres->res_getattr3.status = NFS3_OK; 00184 break; 00185 } /* switch */ 00186 00187 LogFullDebug(COMPONENT_NFSPROTO, "nfs_Getattr succeeded"); 00188 rc = NFS_REQ_OK; 00189 goto out; 00190 } 00191 00192 LogFullDebug(COMPONENT_CACHE_INODE,"nfs_Getattr: cache_inode_get() " 00193 "returned cache status %d(%s)", 00194 cache_status, cache_inode_err_str(cache_status)); 00195 00196 if (cache_status != CACHE_INODE_FSAL_ESTALE) 00197 cache_status = CACHE_INODE_INVALID_ARGUMENT; 00198 00199 nfs_SetFailedStatus(pcontext, pexport, 00200 preq->rq_vers, 00201 cache_status, 00202 &pres->res_attr2.status, 00203 &pres->res_getattr3.status, 00204 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00205 00206 LogFullDebug(COMPONENT_NFSPROTO, "nfs_Getattr set failed status"); 00207 00208 rc = NFS_REQ_OK; 00209 00210 out: 00211 /* return references */ 00212 if (pentry) 00213 cache_inode_put(pentry); 00214 00215 return (rc); 00216 00217 } /* nfs_Getattr */ 00218 00227 void nfs_Getattr_Free(nfs_res_t * resp) 00228 { 00229 /* Nothing to do here */ 00230 return; 00231 } /* nfs_Getattr_Free */