nfs-ganesha 1.4

nfs_Fsstat.c

Go to the documentation of this file.
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 */