nfs-ganesha 1.4

nfs_filehandle_mgmt.c

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright CEA/DAM/DIF  (2008)
00004  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00005  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00006  *
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 3 of the License, or (at your option) any later version.
00012  * 
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021  * 
00022  * ---------------------------------------
00023  */
00024 
00084 #ifdef HAVE_CONFIG_H
00085 #include "config.h"
00086 #endif
00087 
00088 #ifdef _SOLARIS
00089 #include "solaris_port.h"
00090 #endif
00091 
00092 #include <stdio.h>
00093 #include <sys/types.h>
00094 #include <ctype.h>              /* for having isalnum */
00095 #include <stdlib.h>             /* for having atoi */
00096 #include <dirent.h>             /* for having MAXNAMLEN */
00097 #include <netdb.h>
00098 #include <netinet/in.h>
00099 #include <arpa/inet.h>
00100 #include <string.h>
00101 #include <pthread.h>
00102 #include <fcntl.h>
00103 #include <sys/file.h>           /* for having FNDELAY */
00104 #include <pwd.h>
00105 #include <grp.h>
00106 #include "log.h"
00107 #include "ganesha_rpc.h"
00108 #include "nfs_core.h"
00109 #include "nfs23.h"
00110 #include "nfs4.h"
00111 #include "fsal.h"
00112 #include "nfs_tools.h"
00113 #include "nfs_exports.h"
00114 #include "nfs_file_handle.h"
00115 
00128 int nfs4_FhandleToFSAL(nfs_fh4 *pfh4,
00129                        struct fsal_handle_desc *fh_desc,
00130                        fsal_op_context_t *pcontext)
00131 {
00132   fsal_status_t fsal_status;
00133   file_handle_v4_t *pfile_handle;
00134 
00135   BUILD_BUG_ON(sizeof(struct alloc_file_handle_v4) != NFS4_FHSIZE);
00136   print_fhandle4(COMPONENT_FILEHANDLE, pfh4);
00137 
00138   /* Cast the fh as a non opaque structure */
00139   pfile_handle = (file_handle_v4_t *) (pfh4->nfs_fh4_val);
00140 
00141   /* validate the filehandle  */
00142   if(pfh4->nfs_fh4_len != nfs4_sizeof_handle(pfile_handle) ||
00143      pfile_handle->fhversion != GANESHA_FH_VERSION ||
00144      pfile_handle->pseudofs_id != 0 ||
00145      pfile_handle->pseudofs_flag != FALSE)
00146     return 0;                   /* Bad FH */
00147 
00148   /* Fill in the fs opaque part */
00149   fh_desc->start = (caddr_t)&pfile_handle->fsopaque;
00150   fh_desc->len = pfile_handle->fs_len;
00151   fsal_status = FSAL_ExpandHandle(FSAL_GET_EXP_CTX(pcontext),
00152                                   FSAL_DIGEST_NFSV4,
00153                                   fh_desc);
00154   if(FSAL_IS_ERROR(fsal_status))
00155     return 0;                   /* Corrupted (or stale) FH */
00156   return 1;
00157 }                               /* nfs4_FhandleToFSAL */
00158 
00171 int nfs3_FhandleToFSAL(nfs_fh3 * pfh3,
00172                        struct fsal_handle_desc *fh_desc,
00173                        fsal_op_context_t * pcontext)
00174 {
00175   fsal_status_t fsal_status;
00176   file_handle_v3_t *pfile_handle;
00177 
00178   BUILD_BUG_ON(sizeof(struct alloc_file_handle_v3) != NFS3_FHSIZE);
00179   print_fhandle3(COMPONENT_FILEHANDLE, pfh3);
00180 
00181   /* Cast the fh as a non opaque structure */
00182   pfile_handle = (file_handle_v3_t *) (pfh3->data.data_val);
00183 
00184   /* validate the filehandle  */
00185   if(nfs3_Is_Fh_Invalid(pfh3) != NFS3_OK)
00186     return 0;                   /* Bad FH */
00187 
00188   /* Fill in the fs opaque part */
00189   fh_desc->start = (caddr_t) &pfile_handle->fsopaque;
00190   fh_desc->len = pfile_handle->fs_len;
00191   fsal_status = FSAL_ExpandHandle(FSAL_GET_EXP_CTX(pcontext),
00192                                   FSAL_DIGEST_NFSV3,
00193                                   fh_desc);
00194   if(FSAL_IS_ERROR(fsal_status))
00195     return 0;                   /* Corrupted FH */
00196 
00197   return 1;
00198 }                               /* nfs3_FhandleToFSAL */
00199 
00212 int nfs2_FhandleToFSAL(fhandle2 * pfh2,
00213                        struct fsal_handle_desc *fh_desc,
00214                        fsal_op_context_t * pcontext)
00215 {
00216   fsal_status_t fsal_status;
00217   file_handle_v2_t *pfile_handle;
00218 
00219   BUILD_BUG_ON(sizeof(struct alloc_file_handle_v2) != NFS2_FHSIZE);
00220   /* Cast the fh as a non opaque structure */
00221   pfile_handle = (file_handle_v2_t *) pfh2;
00222   print_fhandle2(COMPONENT_FILEHANDLE, pfh2);
00223 
00224   /* validate the filehandle  */
00225   if(pfile_handle->fhversion != GANESHA_FH_VERSION)
00226     return 0;                   /* Bad FH */
00227 
00228   /* Fill in the fs opaque part */
00229   fh_desc->start = (caddr_t) & (pfile_handle->fsopaque);
00230   fh_desc->len = sizeof(pfile_handle->fsopaque);
00231   fsal_status = FSAL_ExpandHandle(FSAL_GET_EXP_CTX(pcontext),
00232                                   FSAL_DIGEST_NFSV2,
00233                                   fh_desc);
00234   if(FSAL_IS_ERROR(fsal_status))
00235     return 0;                   /* Corrupted FH */
00236 
00237   print_buff(COMPONENT_FILEHANDLE, (char *)fh_desc->start, fh_desc->len);
00238 
00239   return 1;
00240 }                               /* nfs2_FhandleToFSAL */
00241 
00255 int nfs4_FSALToFhandle(nfs_fh4 *pfh4,
00256                        fsal_handle_t *pfsalhandle,
00257                        compound_data_t *data)
00258 {
00259   fsal_status_t fsal_status;
00260   file_handle_v4_t *file_handle;
00261   struct fsal_handle_desc fh_desc;
00262 
00263   /* reset the buffer to be used as handle */
00264   pfh4->nfs_fh4_len = sizeof(struct alloc_file_handle_v4);
00265   memset(pfh4->nfs_fh4_val, 0, pfh4->nfs_fh4_len);
00266   file_handle = (file_handle_v4_t *)pfh4->nfs_fh4_val;
00267 
00268   /* Fill in the fs opaque part */
00269   fh_desc.start = (caddr_t) &file_handle->fsopaque;
00270   fh_desc.len = pfh4->nfs_fh4_len - offsetof(file_handle_v4_t, fsopaque);
00271   fsal_status =
00272       FSAL_DigestHandle(&data->pexport->FS_export_context,
00273                         FSAL_DIGEST_NFSV4,
00274                         pfsalhandle,
00275                         &fh_desc);
00276   if(FSAL_IS_ERROR(fsal_status))
00277     return 0;
00278 
00279   file_handle->fhversion = GANESHA_FH_VERSION;
00280   file_handle->fs_len = fh_desc.len;   /* set the actual size */
00281   /* keep track of the export id */
00282   file_handle->exportid = data->pexport->id;
00283 
00284   /* if FH expires, set it there */
00285   if(nfs_param.nfsv4_param.fh_expire == TRUE)
00286     {
00287       LogFullDebug(COMPONENT_NFS_V4, "An expireable file handle was created.");
00288       file_handle->srvboot_time = ServerBootTime;
00289     }
00290 
00291   /* Set the len */
00292   pfh4->nfs_fh4_len = nfs4_sizeof_handle(file_handle); /* re-adjust to as built */
00293 
00294   return 1;
00295 }                               /* nfs4_FSALToFhandle */
00296 
00312 int nfs3_FSALToFhandle(nfs_fh3 *pfh3,
00313                        fsal_handle_t *pfsalhandle,
00314                        exportlist_t *pexport)
00315 {
00316   fsal_status_t fsal_status;
00317   file_handle_v3_t *file_handle;
00318   struct fsal_handle_desc fh_desc;
00319 
00320   print_buff(COMPONENT_FILEHANDLE, (char *)pfsalhandle, sizeof(fsal_handle_t));
00321 
00322   /* reset the buffer to be used as handle */
00323   pfh3->data.data_len = sizeof(struct alloc_file_handle_v3);
00324   memset(pfh3->data.data_val, 0, pfh3->data.data_len);
00325   file_handle = (file_handle_v3_t *)pfh3->data.data_val;
00326 
00327   /* Fill in the fs opaque part */
00328   fh_desc.start = (caddr_t) &file_handle->fsopaque;
00329   fh_desc.len = pfh3->data.data_len - offsetof(file_handle_v3_t, fsopaque);
00330   fsal_status =
00331       FSAL_DigestHandle(&pexport->FS_export_context, FSAL_DIGEST_NFSV3, pfsalhandle,
00332                         &fh_desc);
00333   if(FSAL_IS_ERROR(fsal_status))
00334     return 0;
00335 
00336   file_handle->fhversion = GANESHA_FH_VERSION;
00337   file_handle->fs_len = fh_desc.len;   /* set the actual size */
00338   /* keep track of the export id */
00339   file_handle->exportid = pexport->id;
00340 
00341   /* Set the len */
00342   pfh3->data.data_len = nfs3_sizeof_handle(file_handle); /* re-adjust to as built */
00343 
00344   print_fhandle3(COMPONENT_FILEHANDLE, pfh3);
00345 
00346   return 1;
00347 }                               /* nfs3_FSALToFhandle */
00348 
00362 int nfs2_FSALToFhandle(fhandle2 * pfh2, fsal_handle_t * pfsalhandle,
00363                        exportlist_t * pexport)
00364 {
00365   fsal_status_t fsal_status;
00366   file_handle_v2_t *file_handle;
00367   struct fsal_handle_desc fh_desc;
00368 
00369   print_buff(COMPONENT_FILEHANDLE, (char *)pfsalhandle, sizeof(fsal_handle_t));
00370 
00371   /* zero-ification of the buffer to be used as handle */
00372   memset(pfh2, 0, sizeof(struct alloc_file_handle_v2));
00373   file_handle = (file_handle_v2_t *)pfh2;
00374 
00375   /* Fill in the fs opaque part */
00376   fh_desc.start = (caddr_t) &file_handle->fsopaque;
00377   fh_desc.len = sizeof(file_handle->fsopaque);
00378   fsal_status =
00379       FSAL_DigestHandle(&pexport->FS_export_context, FSAL_DIGEST_NFSV2, pfsalhandle,
00380                         &fh_desc);
00381   if(FSAL_IS_ERROR(fsal_status))
00382    {
00383      if( fsal_status.major == ERR_FSAL_TOOSMALL )
00384       LogCrit( COMPONENT_FILEHANDLE, "NFSv2 file handle is too small to manage this fsal" ) ;
00385      else
00386       LogCrit( COMPONENT_FILEHANDLE, "FSAL_DigestHandle return (%u,%u) when called from %s", 
00387                fsal_status.major, fsal_status.minor, __func__ ) ;
00388     return 0;
00389    }
00390 
00391   file_handle->fhversion = GANESHA_FH_VERSION;
00392   /* keep track of the export id */
00393   file_handle->exportid = pexport->id;
00394 
00395   /* Set the last byte */
00396   file_handle->xattr_pos = 0;
00397 
00398 /*   /\* Set the data *\/ */
00399 /*   memcpy((caddr_t) pfh2, &file_handle, sizeof(file_handle_v2_t)); */
00400 
00401   print_fhandle2(COMPONENT_FILEHANDLE, pfh2);
00402 
00403   return 1;
00404 }                               /* nfs2_FSALToFhandle */
00405 
00417 short nfs4_FhandleToExportId(nfs_fh4 * pfh4)
00418 {
00419   file_handle_v4_t *pfile_handle = NULL;
00420 
00421   pfile_handle = (file_handle_v4_t *) (pfh4->nfs_fh4_val);
00422 
00423   if(pfile_handle == NULL)
00424     return -1;                  /* Badly formed arguments */
00425 
00426   return pfile_handle->exportid;
00427 }                               /* nfs4_FhandleToExportId */
00428 
00440 short nfs3_FhandleToExportId(nfs_fh3 * pfh3)
00441 {
00442   file_handle_v3_t *pfile_handle;
00443 
00444   pfile_handle = (file_handle_v3_t *) (pfh3->data.data_val);
00445 
00446   if(pfile_handle == NULL)
00447     return -1;                  /* Badly formed argument */
00448 
00449   print_buff(COMPONENT_FILEHANDLE, (char *)pfh3->data.data_val, pfh3->data.data_len);
00450 
00451   return pfile_handle->exportid;
00452 }                               /* nfs3_FhandleToExportId */
00453 
00454 #ifdef _USE_NLM
00455 short nlm4_FhandleToExportId(netobj * pfh3)
00456 {
00457   file_handle_v3_t *pfile_handle;
00458 
00459   if(pfh3->n_bytes == NULL || pfh3->n_len < sizeof(file_handle_v3_t))
00460     return -1;                  /* Badly formed argument */
00461 
00462   pfile_handle = (file_handle_v3_t *) (pfh3->n_bytes);
00463 
00464   print_buff(COMPONENT_FILEHANDLE, pfh3->n_bytes, pfh3->n_len);
00465 
00466   return pfile_handle->exportid;
00467 }
00468 #endif
00469 
00481 short nfs2_FhandleToExportId(fhandle2 * pfh2)
00482 {
00483   file_handle_v2_t *pfile_handle;
00484 
00485   pfile_handle = (file_handle_v2_t *) (*pfh2);
00486 
00487   if(pfile_handle == NULL)
00488     return -1;                  /* Badly formed argument */
00489 
00490   return pfile_handle->exportid;
00491 }                               /* nfs2_FhandleToExportId */
00492 
00504 int nfs3_Is_Fh_Xattr(nfs_fh3 * pfh)
00505 {
00506   file_handle_v3_t *pfhandle3;
00507 
00508   if(pfh == NULL)
00509     return 0;
00510 
00511   pfhandle3 = (file_handle_v3_t *) (pfh->data.data_val);
00512 
00513   return (pfhandle3->xattr_pos != 0) ? 1 : 0;
00514 }                               /* nfs4_Is_Fh_Xattr */
00515 
00527 int nfs4_Is_Fh_Empty(nfs_fh4 * pfh)
00528 {
00529   if(pfh == NULL)
00530     return NFS4ERR_NOFILEHANDLE;
00531 
00532   if(pfh->nfs_fh4_len == 0)
00533     return NFS4ERR_NOFILEHANDLE;
00534 
00535   return 0;
00536 }                               /* nfs4_Is_Fh_Empty */
00537 
00549 int nfs4_Is_Fh_Xattr(nfs_fh4 * pfh)
00550 {
00551   file_handle_v4_t *pfhandle4;
00552 
00553   if(pfh == NULL)
00554     return 0;
00555 
00556   pfhandle4 = (file_handle_v4_t *) (pfh->nfs_fh4_val);
00557 
00558   return (pfhandle4->xattr_pos != 0) ? 1 : 0;
00559 }                               /* nfs4_Is_Fh_Xattr */
00560 
00572 int nfs4_Is_Fh_Pseudo(nfs_fh4 * pfh)
00573 {
00574   file_handle_v4_t *pfhandle4;
00575 
00576   if(pfh == NULL)
00577     return 0;
00578 
00579   pfhandle4 = (file_handle_v4_t *) (pfh->nfs_fh4_val);
00580 
00581   return pfhandle4->pseudofs_flag;
00582 }                               /* nfs4_Is_Fh_Pseudo */
00583 
00595 int nfs4_Is_Fh_DSHandle(nfs_fh4 * pfh)
00596 {
00597   file_handle_v4_t *pfhandle4;
00598 
00599   if(pfh == NULL)
00600     return 0;
00601 
00602   pfhandle4 = (file_handle_v4_t *) (pfh->nfs_fh4_val);
00603 
00604   return pfhandle4->ds_flag;
00605 }                               /* nfs4_Is_Fh_DSHandle */
00606 
00618 int nfs4_Is_Fh_Expired(nfs_fh4 * pfh)
00619 {
00620   file_handle_v4_t *pfilehandle4;
00621 
00622   if(pfh == NULL)
00623     return NFS4ERR_BADHANDLE;
00624 
00625   pfilehandle4 = (file_handle_v4_t *) pfh;
00626 
00627   if((nfs_param.nfsv4_param.fh_expire == TRUE)
00628      && (pfilehandle4->srvboot_time != (unsigned int)ServerBootTime))
00629     {
00630       if(nfs_param.nfsv4_param.returns_err_fh_expired == TRUE)
00631         return NFS4ERR_FHEXPIRED;
00632     }
00633 
00634   return NFS4_OK;
00635 }                               /* nfs4_Is_Fh_Expired */
00636 
00648 int nfs4_Is_Fh_Invalid(nfs_fh4 * pfh)
00649 {
00650   file_handle_v4_t *pfilehandle4;
00651 
00652   if(pfh == NULL || pfh->nfs_fh4_val == NULL)
00653   {
00654     LogMajor(COMPONENT_FILEHANDLE,
00655              "Invalid (NULL) File handle: pfh=0x%p",
00656              pfh);
00657     return NFS4ERR_BADHANDLE;
00658   }
00659 
00660   pfilehandle4 = (file_handle_v4_t *) pfh->nfs_fh4_val;
00661   if(pfh->nfs_fh4_len > sizeof(struct alloc_file_handle_v4) ||
00662      pfh->nfs_fh4_len < nfs4_sizeof_handle(pfilehandle4) ||
00663      pfilehandle4->fhversion != GANESHA_FH_VERSION)
00664   {
00665     LogMajor(COMPONENT_FILEHANDLE,
00666              "Invalid File handle: len=%d, version=%x",
00667              pfh->nfs_fh4_len,
00668              pfilehandle4->fhversion);
00669     return NFS4ERR_BADHANDLE;
00670   }
00671 
00672   return NFS4_OK;
00673 }                               /* nfs4_Is_Fh_Invalid */
00674 
00686 int nfs3_Is_Fh_Invalid(nfs_fh3 *pfh3)
00687 {
00688   file_handle_v3_t *pfilehandle3;
00689 
00690   if(pfh3 == NULL || pfh3->data.data_val == NULL)
00691   {
00692     LogMajor(COMPONENT_FILEHANDLE,
00693              "Invalid (NULL) File handle: pfh3=0x%p",
00694              pfh3);
00695     return NFS3ERR_BADHANDLE;
00696   }
00697 
00698   pfilehandle3 = (file_handle_v3_t *) pfh3->data.data_val;
00699   if(pfh3->data.data_len > sizeof(struct alloc_file_handle_v3) ||
00700      pfh3->data.data_len < nfs3_sizeof_handle(pfilehandle3) ||
00701      pfilehandle3->fhversion != GANESHA_FH_VERSION)
00702   {
00703     LogMajor(COMPONENT_FILEHANDLE,
00704              "Invalid File handle: len=%d, version=%x",
00705              pfh3->data.data_len,
00706              pfilehandle3->fhversion);
00707     return NFS3ERR_BADHANDLE;
00708   }
00709 
00710   return NFS3_OK;
00711 }                               /* nfs4_Is_Fh_Invalid */
00712 
00724 int nfs4_Is_Fh_Referral(nfs_fh4 * pfh)
00725 {
00726   file_handle_v4_t *pfhandle4;
00727 
00728   if(pfh == NULL)
00729     return 0;
00730 
00731   pfhandle4 = (file_handle_v4_t *) (pfh->nfs_fh4_val);
00732 
00733   /* Referrals are fh whose pseudofs_id is set without pseudofs_flag set */
00734   if(pfhandle4->refid > 0)
00735     {
00736       return TRUE;
00737     }
00738 
00739   return FALSE;
00740 }                               /* nfs4_Is_Fh_Referral */
00741 
00753 void print_fhandle2(log_components_t component, fhandle2 *fh)
00754 {
00755   if(isFullDebug(component))
00756     {
00757       char str[LEN_FH_STR];
00758 
00759       sprint_fhandle2(str, fh);
00760       LogFullDebug(component, "%s", str);
00761     }
00762 }                               /* print_fhandle2 */
00763 
00764 void sprint_fhandle2(char *str, fhandle2 *fh)
00765 {
00766   char *tmp = str +  sprintf(str, "File Handle V2: ");
00767 
00768   sprint_mem(tmp, (char *) fh, 32);
00769 }                               /* sprint_fhandle2 */
00770 
00782 void print_fhandle3(log_components_t component, nfs_fh3 *fh)
00783 {
00784   if(isFullDebug(component))
00785     {
00786       char str[LEN_FH_STR];
00787 
00788       sprint_fhandle3(str, fh);
00789       LogFullDebug(component, "%s", str);
00790     }
00791 }                               /* print_fhandle3 */
00792 
00793 void sprint_fhandle3(char *str, nfs_fh3 *fh)
00794 {
00795   char *tmp = str + sprintf(str, "File Handle V3: Len=%u ", fh->data.data_len);
00796 
00797   sprint_mem(tmp, fh->data.data_val, fh->data.data_len);
00798 }                               /* sprint_fhandle3 */
00799 
00811 void print_fhandle4(log_components_t component, nfs_fh4 *fh)
00812 {
00813   if(isFullDebug(component))
00814     {
00815       char str[LEN_FH_STR];
00816 
00817       sprint_fhandle4(str, fh);
00818       LogFullDebug(component, "%s", str);
00819     }
00820 }                               /* print_fhandle4 */
00821 
00822 void sprint_fhandle4(char *str, nfs_fh4 *fh)
00823 {
00824   char *tmp = str + sprintf(str, "File Handle V4: Len=%u ", fh->nfs_fh4_len);
00825 
00826   sprint_mem(tmp, fh->nfs_fh4_val, fh->nfs_fh4_len);
00827 }                               /* sprint_fhandle4 */
00828 
00840 void print_fhandle_nlm(log_components_t component, netobj *fh)
00841 {
00842   if(isFullDebug(component))
00843     {
00844       char str[LEN_FH_STR];
00845 
00846       sprint_fhandle_nlm(str, fh);
00847       LogFullDebug(component, "%s", str);
00848     }
00849 }                               /* print_fhandle_nlm */
00850 
00851 void sprint_fhandle_nlm(char *str, netobj *fh)
00852 {
00853   char *tmp = str + sprintf(str, "File Handle V3: Len=%u ", fh->n_len);
00854 
00855   sprint_mem(tmp, fh->n_bytes, fh->n_len);
00856 }                               /* sprint_fhandle_nlm */
00857 
00870 void print_buff(log_components_t component, char *buff, int len)
00871 {
00872   if(isFullDebug(component))
00873     {
00874       char str[1024];
00875 
00876       sprint_buff(str, buff, len);
00877       LogFullDebug(component, "%s", str);
00878     }
00879 }                               /* print_buff */
00880 
00881 void sprint_buff(char *str, char *buff, int len)
00882 {
00883   char *tmp = str + sprintf(str, "  Len=%u Buff=%p Val: ", len, buff);
00884 
00885   sprint_mem(tmp, buff, len);
00886 }                               /* sprint_buff */
00887 
00888 void sprint_mem(char *str, char *buff, int len)
00889 {
00890   int i;
00891 
00892   if(buff == NULL)
00893     sprintf(str, "<null>");
00894   else for(i = 0; i < len; i++)
00895     sprintf(str + i * 2, "%02x", (unsigned char)buff[i]);
00896 }
00897 
00909 void LogCompoundFH(compound_data_t * data)
00910 {
00911   if(isFullDebug(COMPONENT_FILEHANDLE))
00912     {
00913       char str[LEN_FH_STR];
00914       
00915       sprint_fhandle4(str, &data->currentFH);
00916       LogFullDebug(COMPONENT_FILEHANDLE, "Current FH  %s", str);
00917       
00918       sprint_fhandle4(str, &data->savedFH);
00919       LogFullDebug(COMPONENT_FILEHANDLE, "Saved FH    %s", str);
00920       
00921       sprint_fhandle4(str, &data->publicFH);
00922       LogFullDebug(COMPONENT_FILEHANDLE, "Public FH   %s", str);
00923       
00924       sprint_fhandle4(str, &data->rootFH);
00925       LogFullDebug(COMPONENT_FILEHANDLE, "Root FH     %s", str);
00926     }
00927 }                               /* print_compoud_fh */
00928 
00941 void nfs4_sprint_fhandle(nfs_fh4 * fh4p, char *outstr)
00942 {
00943   char *tmp = outstr + sprintf(outstr, "File Handle V4: Len=%u ", fh4p->nfs_fh4_len);
00944 
00945   sprint_mem(tmp, (char *)fh4p->nfs_fh4_val, fh4p->nfs_fh4_len);
00946 }                               /* nfs4_sprint_fhandle */