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_Fsstat(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 fsal_dynamicfsinfo_t dynamicinfo; 00092 cache_inode_status_t cache_status; 00093 cache_entry_t *pentry = NULL; 00094 fsal_attrib_list_t attr; 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_statfs2), 00102 &(parg->arg_fsstat3.fsroot), 00103 NULL, 00104 str); 00105 LogDebug(COMPONENT_NFSPROTO, 00106 "REQUEST PROCESSING: Calling nfs_Fsstat handle: %s", str); 00107 } 00108 00109 if(preq->rq_vers == NFS_V3) 00110 { 00111 /* to avoid setting it on each error case */ 00112 pres->res_fsstat3.FSSTAT3res_u.resfail.obj_attributes.attributes_follow = FALSE; 00113 } 00114 00115 /* convert file handle to vnode */ 00116 if((pentry = nfs_FhandleToCache(preq->rq_vers, 00117 &(parg->arg_statfs2), 00118 &(parg->arg_fsstat3.fsroot), 00119 NULL, 00120 &(pres->res_statfs2.status), 00121 &(pres->res_fsstat3.status), 00122 NULL, NULL, pcontext, &rc)) == NULL) 00123 { 00124 /* Stale NFS FH ? */ 00125 /* return NFS_REQ_DROP ; */ 00126 goto out; 00127 } 00128 00129 /* Get statistics and convert from cache */ 00130 00131 if((cache_status = cache_inode_statfs(pentry, 00132 &dynamicinfo, 00133 pcontext, &cache_status)) == CACHE_INODE_SUCCESS) 00134 { 00135 /* This call is costless, the pentry was cached during call to nfs_FhandleToCache */ 00136 if((cache_status = cache_inode_getattr(pentry, 00137 &attr, 00138 pcontext, 00139 &cache_status)) == CACHE_INODE_SUCCESS) 00140 { 00141 00142 LogFullDebug(COMPONENT_NFSPROTO, 00143 "nfs_Fsstat --> dynamicinfo.total_bytes = %zu dynamicinfo.free_bytes = %zu dynamicinfo.avail_bytes = %zu", 00144 dynamicinfo.total_bytes, 00145 dynamicinfo.free_bytes, 00146 dynamicinfo.avail_bytes); 00147 LogFullDebug(COMPONENT_NFSPROTO, 00148 "nfs_Fsstat --> dynamicinfo.total_files = %llu dynamicinfo.free_files = %llu dynamicinfo.avail_files = %llu", 00149 dynamicinfo.total_files, 00150 dynamicinfo.free_files, 00151 dynamicinfo.avail_files); 00152 00153 switch (preq->rq_vers) 00154 { 00155 case NFS_V2: 00156 pres->res_statfs2.STATFS2res_u.info.tsize = NFS2_MAXDATA; 00157 pres->res_statfs2.STATFS2res_u.info.bsize = DEV_BSIZE; 00158 pres->res_statfs2.STATFS2res_u.info.blocks = 00159 dynamicinfo.total_bytes / DEV_BSIZE; 00160 pres->res_statfs2.STATFS2res_u.info.bfree = 00161 dynamicinfo.free_bytes / DEV_BSIZE; 00162 pres->res_statfs2.STATFS2res_u.info.bavail = 00163 dynamicinfo.avail_bytes / DEV_BSIZE; 00164 pres->res_statfs2.status = NFS_OK; 00165 break; 00166 00167 case NFS_V3: 00168 nfs_SetPostOpAttr(pexport, 00169 &attr, 00170 &(pres->res_fsstat3.FSSTAT3res_u 00171 .resok.obj_attributes)); 00172 00173 pres->res_fsstat3.FSSTAT3res_u.resok.tbytes = dynamicinfo.total_bytes; 00174 pres->res_fsstat3.FSSTAT3res_u.resok.fbytes = dynamicinfo.free_bytes; 00175 pres->res_fsstat3.FSSTAT3res_u.resok.abytes = dynamicinfo.avail_bytes; 00176 pres->res_fsstat3.FSSTAT3res_u.resok.tfiles = dynamicinfo.total_files; 00177 pres->res_fsstat3.FSSTAT3res_u.resok.ffiles = dynamicinfo.free_files; 00178 pres->res_fsstat3.FSSTAT3res_u.resok.afiles = dynamicinfo.avail_files; 00179 pres->res_fsstat3.FSSTAT3res_u.resok.invarsec = 0; /* volatile FS */ 00180 pres->res_fsstat3.status = NFS3_OK; 00181 00182 LogFullDebug(COMPONENT_NFSPROTO, 00183 "nfs_Fsstat --> tbytes=%llu fbytes=%llu abytes=%llu", 00184 pres->res_fsstat3.FSSTAT3res_u.resok.tbytes, 00185 pres->res_fsstat3.FSSTAT3res_u.resok.fbytes, 00186 pres->res_fsstat3.FSSTAT3res_u.resok.abytes); 00187 00188 LogFullDebug(COMPONENT_NFSPROTO, 00189 "nfs_Fsstat --> tfiles=%llu fffiles=%llu afiles=%llu", 00190 pres->res_fsstat3.FSSTAT3res_u.resok.tfiles, 00191 pres->res_fsstat3.FSSTAT3res_u.resok.ffiles, 00192 pres->res_fsstat3.FSSTAT3res_u.resok.afiles); 00193 00194 break; 00195 00196 } 00197 rc = NFS_REQ_OK; 00198 goto out; 00199 } 00200 } 00201 00202 /* At this point we met an error */ 00203 if(nfs_RetryableError(cache_status)) { 00204 rc = NFS_REQ_DROP; 00205 goto out; 00206 } 00207 00208 nfs_SetFailedStatus(pcontext, pexport, 00209 preq->rq_vers, 00210 cache_status, 00211 &pres->res_statfs2.status, 00212 &pres->res_fsstat3.status, 00213 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00214 00215 rc = NFS_REQ_OK; 00216 00217 out: 00218 /* return references */ 00219 if (pentry) 00220 cache_inode_put(pentry); 00221 00222 return (rc); 00223 00224 } /* nfs_Fsstat */ 00225 00234 void nfs_Fsstat_Free(nfs_res_t * resp) 00235 { 00236 /* Nothing to do here */ 00237 return; 00238 } /* nfs_Fsstat_Free */