nfs-ganesha 1.4
|
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 */