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 <pwd.h> 00051 #include <grp.h> 00052 #include <stdint.h> 00053 #include "HashData.h" 00054 #include "HashTable.h" 00055 #include "log.h" 00056 #include "ganesha_rpc.h" 00057 #include "nfs23.h" 00058 #include "nfs4.h" 00059 #include "mount.h" 00060 #include "nfs_core.h" 00061 #include "cache_inode.h" 00062 #include "nfs_exports.h" 00063 #include "nfs_creds.h" 00064 #include "nfs_proto_functions.h" 00065 #include "nfs_tools.h" 00066 #include "nfs_file_handle.h" 00067 #include "nfs_proto_tools.h" 00068 #include "nfs4_acls.h" 00069 #ifdef _PNFS_MDS 00070 #include "sal_data.h" 00071 #include "sal_functions.h" 00072 #include "fsal.h" 00073 #include "fsal_pnfs.h" 00074 #include "pnfs_common.h" 00075 #endif /* _PNFS_MDS */ 00076 00077 #ifdef _USE_NFS4_ACL 00078 /* Define mapping of NFS4 who name and type. */ 00079 static struct { 00080 char *string; 00081 int stringlen; 00082 int type; 00083 } whostr_2_type_map[] = { 00084 { 00085 .string = "OWNER@", 00086 .stringlen = sizeof("OWNER@") - 1, 00087 .type = FSAL_ACE_SPECIAL_OWNER, 00088 }, 00089 { 00090 .string = "GROUP@", 00091 .stringlen = sizeof("GROUP@") - 1, 00092 .type = FSAL_ACE_SPECIAL_GROUP, 00093 }, 00094 { 00095 .string = "EVERYONE@", 00096 .stringlen = sizeof("EVERYONE@") - 1, 00097 .type = FSAL_ACE_SPECIAL_EVERYONE, 00098 }, 00099 }; 00100 #endif /* _USE_NFS4_ACL */ 00101 00102 /* 00103 * String representations of NFS protocol operations. 00104 */ 00105 char *nfsv2_function_names[] = { 00106 "NFSv2_null", "NFSv2_getattr", "NFSv2_setattr", "NFSv2_root", 00107 "NFSv2_lookup", "NFSv2_readlink", "NFSv2_read", "NFSv2_writecache", 00108 "NFSv2_write", "NFSv2_create", "NFSv2_remove", "NFSv2_rename", 00109 "NFSv2_link", "NFSv2_symlink", "NFSv2_mkdir", "NFSv2_rmdir", 00110 "NFSv2_readdir", "NFSv2_statfs" 00111 }; 00112 00113 char *nfsv3_function_names[] = { 00114 "NFSv3_null", "NFSv3_getattr", "NFSv3_setattr", "NFSv3_lookup", 00115 "NFSv3_access", "NFSv3_readlink", "NFSv3_read", "NFSv3_write", 00116 "NFSv3_create", "NFSv3_mkdir", "NFSv3_symlink", "NFSv3_mknod", 00117 "NFSv3_remove", "NFSv3_rmdir", "NFSv3_rename", "NFSv3_link", 00118 "NFSv3_readdir", "NFSv3_readdirplus", "NFSv3_fsstat", 00119 "NFSv3_fsinfo", "NFSv3_pathconf", "NFSv3_commit" 00120 }; 00121 00122 char *nfsv4_function_names[] = { 00123 "NFSv4_null", "NFSv4_compound" 00124 }; 00125 00126 char *mnt_function_names[] = { 00127 "MNT_null", "MNT_mount", "MNT_dump", "MNT_umount", "MNT_umountall", "MNT_export" 00128 }; 00129 00130 char *rquota_functions_names[] = { 00131 "rquota_Null", "rquota_getquota", "rquota_getquotaspecific", "rquota_setquota", 00132 "rquota_setquotaspecific" 00133 }; 00134 00148 void nfs_FhandleToStr(u_long rq_vers, 00149 fhandle2 *pfh2, 00150 nfs_fh3 *pfh3, 00151 nfs_fh4 *pfh4, 00152 char *str) 00153 { 00154 00155 switch (rq_vers) 00156 { 00157 case NFS_V4: 00158 sprint_fhandle4(str, pfh4); 00159 break; 00160 00161 case NFS_V3: 00162 sprint_fhandle3(str, pfh3); 00163 break; 00164 00165 case NFS_V2: 00166 sprint_fhandle2(str, pfh2); 00167 break; 00168 } 00169 } /* nfs_FhandleToStr */ 00170 00194 cache_entry_t *nfs_FhandleToCache(u_long rq_vers, 00195 fhandle2 * pfh2, 00196 nfs_fh3 * pfh3, 00197 nfs_fh4 * pfh4, 00198 nfsstat2 * pstatus2, 00199 nfsstat3 * pstatus3, 00200 nfsstat4 * pstatus4, 00201 fsal_attrib_list_t * pattr, 00202 fsal_op_context_t * pcontext, 00203 int *prc) 00204 { 00205 cache_inode_fsal_data_t fsal_data; 00206 cache_inode_status_t cache_status; 00207 cache_entry_t *pentry = NULL; 00208 fsal_attrib_list_t attr; 00209 exportlist_t *pexport = NULL; 00210 short exportid = 0; 00211 00212 /* Default behaviour */ 00213 *prc = NFS_REQ_OK; 00214 00215 memset(&fsal_data, 0, sizeof(fsal_data)); 00216 switch (rq_vers) 00217 { 00218 case NFS_V4: 00219 if(!nfs4_FhandleToFSAL(pfh4, &fsal_data.fh_desc, pcontext)) 00220 { 00221 *prc = NFS_REQ_DROP; 00222 *pstatus4 = NFS4ERR_BADHANDLE; 00223 return NULL; 00224 } 00225 exportid = nfs4_FhandleToExportId(pfh4); 00226 break; 00227 00228 case NFS_V3: 00229 if(!nfs3_FhandleToFSAL(pfh3, &fsal_data.fh_desc, pcontext)) 00230 { 00231 *prc = NFS_REQ_DROP; 00232 *pstatus3 = NFS3ERR_BADHANDLE; 00233 return NULL; 00234 } 00235 exportid = nfs3_FhandleToExportId(pfh3); 00236 break; 00237 00238 case NFS_V2: 00239 if(!nfs2_FhandleToFSAL(pfh2, &fsal_data.fh_desc, pcontext)) 00240 { 00241 *prc = NFS_REQ_DROP; 00242 *pstatus2 = NFSERR_STALE; 00243 return NULL; 00244 } 00245 exportid = nfs2_FhandleToExportId(pfh2); 00246 break; 00247 } 00248 00249 print_buff(COMPONENT_FILEHANDLE, 00250 fsal_data.fh_desc.start, 00251 fsal_data.fh_desc.len); 00252 00253 if((pexport = nfs_Get_export_by_id(nfs_param.pexportlist, exportid)) == NULL) 00254 { 00255 /* invalid handle */ 00256 switch (rq_vers) 00257 { 00258 case NFS_V4: 00259 *pstatus4 = NFS4ERR_STALE; 00260 break; 00261 00262 case NFS_V3: 00263 *pstatus3 = NFS3ERR_STALE; 00264 break; 00265 00266 case NFS_V2: 00267 *pstatus2 = NFSERR_STALE; 00268 break; 00269 } 00270 *prc = NFS_REQ_DROP; 00271 00272 LogFullDebug(COMPONENT_NFSPROTO, 00273 "Invalid file handle passed to nfsFhandleToCache "); 00274 return NULL; 00275 } 00276 00277 if((pentry = cache_inode_get(&fsal_data, &attr, pcontext, 00278 NULL, &cache_status)) == NULL) 00279 { 00280 switch (rq_vers) 00281 { 00282 case NFS_V4: 00283 *pstatus4 = NFS4ERR_STALE; 00284 break; 00285 00286 case NFS_V3: 00287 *pstatus3 = NFS3ERR_STALE; 00288 break; 00289 00290 case NFS_V2: 00291 *pstatus2 = NFSERR_STALE; 00292 break; 00293 } 00294 *prc = NFS_REQ_OK; 00295 return NULL; 00296 } 00297 00298 if(pattr != NULL) 00299 *pattr = attr; 00300 00301 return pentry; 00302 } /* nfs_FhandleToCache */ 00303 00315 int nfs_SetPostOpAttr(exportlist_t *pexport, 00316 const fsal_attrib_list_t *pfsal_attr, 00317 post_op_attr *presult) 00318 { 00319 if(pfsal_attr == NULL) 00320 { 00321 presult->attributes_follow 00322 = nfs3_FSALattr_To_Fattr(pexport, 00323 pfsal_attr, 00324 &(presult->post_op_attr_u.attributes)); 00325 } 00326 00327 if(nfs3_FSALattr_To_Fattr(pexport, 00328 pfsal_attr, 00329 &(presult->post_op_attr_u.attributes)) 00330 == 0) 00331 presult->attributes_follow = FALSE; 00332 else 00333 presult->attributes_follow = TRUE; 00334 00335 return 0; 00336 } /* nfs_SetPostOpAttr */ 00337 00350 void nfs_SetPreOpAttr(fsal_attrib_list_t * pfsal_attr, pre_op_attr * pattr) 00351 { 00352 if(pfsal_attr == NULL) 00353 { 00354 pattr->attributes_follow = FALSE; 00355 } 00356 else 00357 { 00358 pattr->pre_op_attr_u.attributes.size = pfsal_attr->filesize; 00359 pattr->pre_op_attr_u.attributes.mtime.seconds = pfsal_attr->mtime.seconds; 00360 pattr->pre_op_attr_u.attributes.mtime.nseconds = 0 ; 00361 00362 pattr->pre_op_attr_u.attributes.ctime.seconds = pfsal_attr->ctime.seconds; 00363 pattr->pre_op_attr_u.attributes.ctime.nseconds = 0; 00364 00365 pattr->attributes_follow = TRUE; 00366 } 00367 } /* nfs_SetPreOpAttr */ 00368 00384 void nfs_SetWccData(exportlist_t * pexport, 00385 fsal_attrib_list_t * pbefore_attr, 00386 fsal_attrib_list_t * pafter_attr, wcc_data * pwcc_data) 00387 { 00388 /* Build directory pre operation attributes */ 00389 nfs_SetPreOpAttr(pbefore_attr, &(pwcc_data->before)); 00390 00391 /* Build directory post operation attributes */ 00392 nfs_SetPostOpAttr(pexport, pafter_attr, &(pwcc_data->after)); 00393 } /* nfs_SetWccData */ 00394 00408 int nfs_RetryableError(cache_inode_status_t cache_status) 00409 { 00410 switch (cache_status) 00411 { 00412 case CACHE_INODE_IO_ERROR: 00413 if(nfs_param.core_param.drop_io_errors) 00414 { 00415 /* Drop the request */ 00416 return TRUE; 00417 } 00418 else 00419 { 00420 /* Propagate error to the client */ 00421 return FALSE; 00422 } 00423 break; 00424 00425 case CACHE_INODE_INVALID_ARGUMENT: 00426 if(nfs_param.core_param.drop_inval_errors) 00427 { 00428 /* Drop the request */ 00429 return TRUE; 00430 } 00431 else 00432 { 00433 /* Propagate error to the client */ 00434 return FALSE; 00435 } 00436 break; 00437 00438 case CACHE_INODE_DELAY: 00439 if(nfs_param.core_param.drop_delay_errors) 00440 { 00441 /* Drop the request */ 00442 return TRUE; 00443 } 00444 else 00445 { 00446 /* Propagate error to the client */ 00447 return FALSE; 00448 } 00449 break; 00450 00451 case CACHE_INODE_SUCCESS: 00452 LogCrit(COMPONENT_NFSPROTO, 00453 "Possible implementation error: CACHE_INODE_SUCCESS managed as an error"); 00454 return FALSE; 00455 break; 00456 00457 case CACHE_INODE_MALLOC_ERROR: 00458 case CACHE_INODE_POOL_MUTEX_INIT_ERROR: 00459 case CACHE_INODE_GET_NEW_LRU_ENTRY: 00460 case CACHE_INODE_UNAPPROPRIATED_KEY: 00461 case CACHE_INODE_INIT_ENTRY_FAILED: 00462 case CACHE_INODE_FSAL_ERROR: 00463 case CACHE_INODE_LRU_ERROR: 00464 case CACHE_INODE_HASH_SET_ERROR: 00465 case CACHE_INODE_INCONSISTENT_ENTRY: 00466 case CACHE_INODE_HASH_TABLE_ERROR: 00467 case CACHE_INODE_INSERT_ERROR: 00468 /* Internal error, should be dropped and retryed */ 00469 return TRUE; 00470 break; 00471 00472 case CACHE_INODE_NOT_A_DIRECTORY: 00473 case CACHE_INODE_BAD_TYPE: 00474 case CACHE_INODE_ENTRY_EXISTS: 00475 case CACHE_INODE_DIR_NOT_EMPTY: 00476 case CACHE_INODE_NOT_FOUND: 00477 case CACHE_INODE_FSAL_EACCESS: 00478 case CACHE_INODE_IS_A_DIRECTORY: 00479 case CACHE_INODE_FSAL_EPERM: 00480 case CACHE_INODE_NO_SPACE_LEFT: 00481 case CACHE_INODE_CACHE_CONTENT_ERROR: 00482 case CACHE_INODE_CACHE_CONTENT_EXISTS: 00483 case CACHE_INODE_CACHE_CONTENT_EMPTY: 00484 case CACHE_INODE_READ_ONLY_FS: 00485 case CACHE_INODE_KILLED: 00486 case CACHE_INODE_FSAL_ESTALE: 00487 case CACHE_INODE_FSAL_ERR_SEC: 00488 case CACHE_INODE_QUOTA_EXCEEDED: 00489 case CACHE_INODE_NOT_SUPPORTED: 00490 case CACHE_INODE_NAME_TOO_LONG: 00491 case CACHE_INODE_STATE_CONFLICT: 00492 case CACHE_INODE_DEAD_ENTRY: 00493 case CACHE_INODE_ASYNC_POST_ERROR: 00494 case CACHE_INODE_STATE_ERROR: 00495 case CACHE_INODE_BAD_COOKIE: 00496 case CACHE_INODE_FILE_BIG: 00497 case CACHE_INODE_FILE_OPEN: 00498 /* Non retryable error, return error to client */ 00499 return FALSE; 00500 break; 00501 } 00502 00503 /* Should never reach this */ 00504 LogDebug(COMPONENT_NFSPROTO, 00505 "cache_inode_status=%u not managed properly in nfs_RetryableError, line %u should never be reached", 00506 cache_status, __LINE__); 00507 return FALSE; 00508 } 00509 00510 void nfs_SetFailedStatus(fsal_op_context_t * pcontext, 00511 exportlist_t * pexport, 00512 int version, 00513 cache_inode_status_t status, 00514 nfsstat2 * pstatus2, 00515 nfsstat3 * pstatus3, 00516 cache_entry_t * pentry0, 00517 post_op_attr * ppost_op_attr, 00518 cache_entry_t * pentry1, 00519 fsal_attrib_list_t * ppre_vattr1, 00520 wcc_data * pwcc_data1, 00521 cache_entry_t * pentry2, 00522 fsal_attrib_list_t * ppre_vattr2, wcc_data * pwcc_data2) 00523 { 00524 switch (version) 00525 { 00526 case NFS_V2: 00527 if(status != CACHE_INODE_SUCCESS) /* Should not use success to address a failed status */ 00528 *pstatus2 = nfs2_Errno(status); 00529 break; 00530 00531 case NFS_V3: 00532 if(status != CACHE_INODE_SUCCESS) /* Should not use success to address a failed status */ 00533 *pstatus3 = nfs3_Errno(status); 00534 00535 if(ppost_op_attr != NULL) 00536 nfs_SetPostOpAttr(pexport, NULL, ppost_op_attr); 00537 00538 if(pwcc_data1 != NULL) 00539 nfs_SetWccData(pexport, ppre_vattr1, NULL, pwcc_data1); 00540 00541 if(pwcc_data2 != NULL) 00542 nfs_SetWccData(pexport, ppre_vattr2, NULL, pwcc_data2); 00543 break; 00544 00545 } 00546 } 00547 00548 #ifdef _USE_NFS4_ACL 00549 /* Following idmapper function conventions, return 1 if successful, 0 otherwise. */ 00550 static int nfs4_encode_acl_special_user(int who, char *attrvalsBuffer, 00551 u_int *LastOffset) 00552 { 00553 int rc = 0; 00554 int i; 00555 u_int utf8len = 0; 00556 u_int deltalen = 0; 00557 00558 for (i = 0; i < FSAL_ACE_SPECIAL_EVERYONE; i++) 00559 { 00560 if (whostr_2_type_map[i].type == who) 00561 { 00562 if(whostr_2_type_map[i].stringlen % 4 == 0) 00563 deltalen = 0; 00564 else 00565 deltalen = 4 - whostr_2_type_map[i].stringlen % 4; 00566 00567 utf8len = htonl(whostr_2_type_map[i].stringlen + deltalen); 00568 memcpy((char *)(attrvalsBuffer + *LastOffset), &utf8len, sizeof(int)); 00569 *LastOffset += sizeof(int); 00570 00571 memcpy((char *)(attrvalsBuffer + *LastOffset), whostr_2_type_map[i].string, 00572 whostr_2_type_map[i].stringlen); 00573 *LastOffset += whostr_2_type_map[i].stringlen; 00574 00575 /* Pad with zero to keep xdr alignement */ 00576 if(deltalen != 0) 00577 memset((char *)(attrvalsBuffer + *LastOffset), 0, deltalen); 00578 *LastOffset += deltalen; 00579 00580 /* Found a matched one. */ 00581 rc = 1; 00582 break; 00583 } 00584 } 00585 00586 return rc; 00587 } 00588 00589 /* Following idmapper function conventions, return 1 if successful, 0 otherwise. */ 00590 static int nfs4_encode_acl_group_name(fsal_gid_t gid, char *attrvalsBuffer, 00591 u_int *LastOffset) 00592 { 00593 int rc = 0; 00594 char name[MAXNAMLEN]; 00595 u_int utf8len = 0; 00596 u_int stringlen = 0; 00597 u_int deltalen = 0; 00598 00599 rc = gid2name(name, &gid); 00600 LogFullDebug(COMPONENT_NFS_V4, 00601 "encode gid2name = %s, strlen = %llu", 00602 name, (long long unsigned int)strlen(name)); 00603 if(rc == 0) /* Failure. */ 00604 { 00605 /* Encode gid itself without @. */ 00606 sprintf(name, "%u", gid); 00607 } 00608 00609 stringlen = strlen(name); 00610 if(stringlen % 4 == 0) 00611 deltalen = 0; 00612 else 00613 deltalen = 4 - (stringlen % 4); 00614 00615 utf8len = htonl(stringlen + deltalen); 00616 memcpy((char *)(attrvalsBuffer + *LastOffset), &utf8len, sizeof(int)); 00617 *LastOffset += sizeof(int); 00618 00619 memcpy((char *)(attrvalsBuffer + *LastOffset), name, stringlen); 00620 *LastOffset += stringlen; 00621 00622 /* Pad with zero to keep xdr alignement */ 00623 if(deltalen != 0) 00624 memset((char *)(attrvalsBuffer + *LastOffset), 0, deltalen); 00625 *LastOffset += deltalen; 00626 00627 return rc; 00628 } 00629 00630 /* Following idmapper function conventions, return 1 if successful, 0 otherwise. */ 00631 static int nfs4_encode_acl_user_name(int whotype, fsal_uid_t uid, 00632 char *attrvalsBuffer, u_int *LastOffset) 00633 { 00634 int rc = 0; 00635 char name[MAXNAMLEN]; 00636 u_int utf8len = 0; 00637 u_int stringlen = 0; 00638 u_int deltalen = 0; 00639 00640 /* Encode special user first. */ 00641 if (whotype != FSAL_ACE_NORMAL_WHO) 00642 { 00643 rc = nfs4_encode_acl_special_user(uid, attrvalsBuffer, LastOffset); 00644 if(rc == 1) /* Success. */ 00645 return rc; 00646 } 00647 00648 /* Encode normal user or previous user we failed to encode as special user. */ 00649 rc = uid2name(name, &uid); 00650 LogFullDebug(COMPONENT_NFS_V4, 00651 "econde uid2name = %s, strlen = %llu", 00652 name, (long long unsigned int)strlen(name)); 00653 if(rc == 0) /* Failure. */ 00654 { 00655 /* Encode uid itself without @. */ 00656 sprintf(name, "%u", uid); 00657 } 00658 00659 stringlen = strlen(name); 00660 if(stringlen % 4 == 0) 00661 deltalen = 0; 00662 else 00663 deltalen = 4 - (stringlen % 4); 00664 00665 utf8len = htonl(stringlen + deltalen); 00666 memcpy((char *)(attrvalsBuffer + *LastOffset), &utf8len, sizeof(int)); 00667 *LastOffset += sizeof(int); 00668 00669 memcpy((char *)(attrvalsBuffer + *LastOffset), name, stringlen); 00670 *LastOffset += stringlen; 00671 00672 /* Pad with zero to keep xdr alignement */ 00673 if(deltalen != 0) 00674 memset((char *)(attrvalsBuffer + *LastOffset), 0, deltalen); 00675 *LastOffset += deltalen; 00676 00677 return rc; 00678 } 00679 00680 /* Following idmapper function conventions, return 1 if successful, 0 otherwise. */ 00681 static int nfs4_encode_acl(fsal_attrib_list_t * pattr, char *attrvalsBuffer, u_int *LastOffset) 00682 { 00683 int rc = 0; 00684 uint32_t naces, type, flag, access_mask, whotype; 00685 fsal_ace_t *pace; 00686 00687 if(pattr->acl) 00688 { 00689 LogFullDebug(COMPONENT_NFS_V4, 00690 "GATTR: Number of ACEs = %u", 00691 pattr->acl->naces); 00692 00693 /* Encode number of ACEs. */ 00694 naces = htonl(pattr->acl->naces); 00695 memcpy((char *)(attrvalsBuffer + *LastOffset), &naces, sizeof(uint32_t)); 00696 *LastOffset += sizeof(uint32_t); 00697 00698 /* Encode ACEs. */ 00699 for(pace = pattr->acl->aces; pace < pattr->acl->aces + pattr->acl->naces; pace++) 00700 { 00701 LogFullDebug(COMPONENT_NFS_V4, 00702 "GATTR: type=0X%x, flag=0X%x, perm=0X%x", 00703 pace->type, pace->flag, pace->perm); 00704 00705 type = htonl(pace->type); 00706 flag = htonl(pace->flag); 00707 access_mask = htonl(pace->perm); 00708 00709 memcpy((char *)(attrvalsBuffer + *LastOffset), &type, sizeof(uint32_t)); 00710 *LastOffset += sizeof(uint32_t); 00711 00712 memcpy((char *)(attrvalsBuffer + *LastOffset), &flag, sizeof(uint32_t)); 00713 *LastOffset += sizeof(uint32_t); 00714 00715 memcpy((char *)(attrvalsBuffer + *LastOffset), &access_mask, sizeof(uint32_t)); 00716 *LastOffset += sizeof(uint32_t); 00717 00718 if(IS_FSAL_ACE_GROUP_ID(*pace)) /* Encode group name. */ 00719 { 00720 rc = nfs4_encode_acl_group_name(pace->who.gid, attrvalsBuffer, LastOffset); 00721 } 00722 else 00723 { 00724 if(!IS_FSAL_ACE_SPECIAL_ID(*pace)) 00725 { 00726 whotype = FSAL_ACE_NORMAL_WHO; 00727 } 00728 else 00729 whotype = pace->who.uid; 00730 00731 /* Encode special or normal user name. */ 00732 rc = nfs4_encode_acl_user_name(whotype, pace->who.uid, attrvalsBuffer, LastOffset); 00733 } 00734 00735 LogFullDebug(COMPONENT_NFS_V4, 00736 "GATTR: special = %u, %s = %u", 00737 IS_FSAL_ACE_SPECIAL_ID(*pace), 00738 IS_FSAL_ACE_GROUP_ID(*pace) ? "gid" : "uid", 00739 IS_FSAL_ACE_GROUP_ID(*pace) ? pace->who.gid : pace->who.uid); 00740 00741 } 00742 } 00743 else 00744 { 00745 LogFullDebug(COMPONENT_NFS_V4, 00746 "nfs4_encode_acl: no acl available"); 00747 00748 fattr4_acl acl; 00749 acl.fattr4_acl_len = htonl(0); 00750 memcpy((char *)(attrvalsBuffer + *LastOffset), &acl, sizeof(fattr4_acl)); 00751 *LastOffset += fattr4tab[FATTR4_ACL].size_fattr4; 00752 } 00753 00754 return rc; 00755 } 00756 #endif /* _USE_NFS4_ACL */ 00757 00758 static uint_t 00759 nfs_tools_xdr_utf8(utf8str_mixed *utf8, char *attrvalsBuffer) 00760 { 00761 u_int utf8len = 0; 00762 u_int deltalen = utf8->utf8string_len % 4; 00763 u_int LastOffset = 0; 00764 00765 utf8len = htonl(utf8->utf8string_len); 00766 memcpy(attrvalsBuffer, &utf8len, sizeof(u_int)); 00767 LastOffset += sizeof(u_int); 00768 00769 memcpy(attrvalsBuffer + LastOffset, 00770 utf8->utf8string_val, utf8->utf8string_len); 00771 LastOffset += utf8->utf8string_len; 00772 00773 /* Free what was allocated by uid2utf8 */ 00774 gsh_free(utf8->utf8string_val); 00775 00776 /* Pad with zero to keep xdr alignement */ 00777 if(deltalen) 00778 { 00779 deltalen = 4 - deltalen; 00780 memset(attrvalsBuffer + LastOffset, 0, deltalen); 00781 LastOffset += deltalen; 00782 } 00783 return LastOffset; 00784 } 00785 00786 void nfs4_Fattr_Free(fattr4 *fattr) 00787 { 00788 if(fattr->attrmask.bitmap4_val != NULL) 00789 { 00790 gsh_free(fattr->attrmask.bitmap4_val); 00791 fattr->attrmask.bitmap4_val = NULL; 00792 } 00793 00794 if(fattr->attr_vals.attrlist4_val != NULL) 00795 { 00796 gsh_free(fattr->attr_vals.attrlist4_val); 00797 fattr->attr_vals.attrlist4_val = NULL; 00798 } 00799 } 00800 00801 static int fsal_time_to_settime4(const fsal_time_t *ts, char *attrval) 00802 { 00803 time_how4 how = htonl(SET_TO_CLIENT_TIME4); 00804 int64_t sec = nfs_htonl64((int64_t)ts->seconds); 00805 uint32_t nsec = htonl(ts->nseconds); 00806 int LastOffset = 0; 00807 00808 memcpy(attrval + LastOffset, &how, sizeof(how)); 00809 LastOffset += sizeof(how); 00810 memcpy(attrval + LastOffset, &sec, sizeof(sec)); 00811 LastOffset += sizeof(sec); 00812 memcpy(attrval + LastOffset, &nsec, sizeof(nsec)); 00813 LastOffset += sizeof(uint32_t); 00814 00815 return LastOffset; 00816 } 00817 00818 int nfs4_supported_attrs_to_fattr(char *attrvalsBuffer) 00819 { 00820 #ifdef _USE_NFS4_1 00821 int lastbit = FATTR4_FS_CHARSET_CAP; 00822 unsigned int attrvalslist_supported[FATTR4_FS_CHARSET_CAP]; 00823 uint32_t bitmap_val[3]; 00824 #else 00825 int lastbit = FATTR4_MOUNTED_ON_FILEID; 00826 unsigned int attrvalslist_supported[FATTR4_MOUNTED_ON_FILEID]; 00827 uint32_t bitmap_val[2]; 00828 #endif 00829 int LastOffset = 0; 00830 fattr4_supported_attrs supported_attrs; 00831 uint32_t supported_attrs_len; 00832 uint32_t supported_attrs_val; 00833 00834 /* The supported attributes have field ',supported' set in tab fattr4tab, I will proceed in 2 pass 00835 * 1st: compute the number of supported attributes 00836 * 2nd: allocate the replyed bitmap and fill it 00837 * 00838 * I do not set a #define to keep the number of supported attributes because I want this parameter 00839 * to be a consequence of fattr4tab and avoid incoherency */ 00840 00841 /* How many supported attributes ? Compute the result in variable named c */ 00842 int k, c = 0; 00843 for(k = FATTR4_SUPPORTED_ATTRS; k <= lastbit; k++) 00844 { 00845 if(fattr4tab[k].supported) 00846 attrvalslist_supported[c++] = k; 00847 } 00848 00849 supported_attrs.bitmap4_val = bitmap_val; 00850 supported_attrs.bitmap4_len = sizeof(bitmap_val)/sizeof(bitmap_val[0]); 00851 nfs4_list_to_bitmap4(&supported_attrs, c, attrvalslist_supported); 00852 00853 LogFullDebug(COMPONENT_NFS_V4, 00854 "Fattr (regular) supported_attrs(len)=%u -> %u|%u", 00855 supported_attrs.bitmap4_len, supported_attrs.bitmap4_val[0], 00856 supported_attrs.bitmap4_val[1]); 00857 00858 /* we store the index */ 00859 supported_attrs_len = htonl(supported_attrs.bitmap4_len); 00860 memcpy((char *)(attrvalsBuffer + LastOffset), &supported_attrs_len, 00861 sizeof(uint32_t)); 00862 LastOffset += sizeof(uint32_t); 00863 00864 /* And then the data */ 00865 for(k = 0; k < supported_attrs.bitmap4_len; k++) 00866 { 00867 supported_attrs_val = htonl(supported_attrs.bitmap4_val[k]); 00868 memcpy((char *)(attrvalsBuffer + LastOffset), &supported_attrs_val, 00869 sizeof(uint32_t)); 00870 LastOffset += sizeof(uint32_t); 00871 } 00872 00873 return LastOffset; 00874 } 00875 00876 int nfs4_Fattr_Fill(fattr4 *Fattr, int cnt, uint32_t *attrvalslist, 00877 int LastOffset, char *attrvalsBuffer) 00878 { 00879 /* Set the bitmap for result */ 00880 memset(Fattr, 0, sizeof(*Fattr)); 00881 if((Fattr->attrmask.bitmap4_val = gsh_calloc(3, sizeof(uint32_t))) == NULL) 00882 return -1; 00883 Fattr->attrmask.bitmap4_len = 3; 00884 nfs4_list_to_bitmap4(&(Fattr->attrmask), cnt, attrvalslist); 00885 00886 /* Set the attrlist4 */ 00887 /* LastOffset contains the length of the attrvalsBuffer usefull data */ 00888 Fattr->attr_vals.attrlist4_len = LastOffset; 00889 if(LastOffset != 0) /* No need to allocate an empty buffer */ 00890 { 00891 Fattr->attr_vals.attrlist4_val = gsh_malloc(LastOffset); 00892 if(Fattr->attr_vals.attrlist4_val == NULL) 00893 { 00894 gsh_free(Fattr->attrmask.bitmap4_val); 00895 return -1; 00896 } 00897 memcpy(Fattr->attr_vals.attrlist4_val, attrvalsBuffer, 00898 Fattr->attr_vals.attrlist4_len); 00899 } 00900 return 0; 00901 } 00922 int nfs4_FSALattr_To_Fattr(exportlist_t *pexport, 00923 fsal_attrib_list_t *pattr, 00924 fattr4 *Fattr, 00925 compound_data_t *data, 00926 nfs_fh4 *objFH, 00927 bitmap4 *Bitmap) 00928 { 00929 fattr4_type file_type = 0; 00930 fattr4_link_support link_support; 00931 fattr4_symlink_support symlink_support; 00932 fattr4_fh_expire_type expire_type; 00933 fattr4_named_attr named_attr; 00934 fattr4_unique_handles unique_handles; 00935 fattr4_archive archive; 00936 fattr4_cansettime cansettime; 00937 fattr4_case_insensitive case_insensitive; 00938 fattr4_case_preserving case_preserving; 00939 fattr4_chown_restricted chown_restricted; 00940 fattr4_hidden hidden; 00941 fattr4_mode file_mode; 00942 fattr4_no_trunc no_trunc; 00943 fattr4_numlinks file_numlinks; 00944 fattr4_rawdev rawdev; 00945 fattr4_system system; 00946 fattr4_size file_size; 00947 fattr4_space_used file_space_used; 00948 fattr4_fsid fsid; 00949 fattr4_time_access time_access; 00950 fattr4_time_modify time_modify; 00951 fattr4_time_metadata time_metadata; 00952 fattr4_time_delta time_delta; 00953 fattr4_change file_change; 00954 fattr4_fileid file_id; 00955 fattr4_owner file_owner; 00956 fattr4_owner_group file_owner_group; 00957 fattr4_space_avail space_avail; 00958 fattr4_space_free space_free; 00959 fattr4_space_total space_total; 00960 fattr4_files_avail files_avail; 00961 fattr4_files_free files_free; 00962 fattr4_files_total files_total; 00963 fattr4_lease_time lease_time; 00964 fattr4_time_create time_create; 00965 fattr4_maxfilesize max_filesize; 00966 fattr4_maxread maxread; 00967 fattr4_maxwrite maxwrite; 00968 fattr4_maxname maxname; 00969 fattr4_maxlink maxlink; 00970 fattr4_homogeneous homogeneous; 00971 fattr4_aclsupport aclsupport; 00972 #ifndef _USE_NFS4_ACL 00973 fattr4_acl acl; 00974 #endif 00975 fattr4_rdattr_error rdattr_error; 00976 fattr4_quota_avail_hard quota_avail_hard; 00977 fattr4_quota_avail_soft quota_avail_soft; 00978 fattr4_quota_used quota_used; 00979 #ifdef _PNFS_MDS 00980 fattr4_layout_blksize layout_blksize; 00981 #endif /* _PNFS_MDS */ 00982 00983 u_int tmp_int; 00984 char tmp_buff[1024]; 00985 00986 uint32_t attribute_to_set = 0; 00987 00988 u_int fhandle_len = 0; 00989 u_int LastOffset; 00990 u_int len = 0, off = 0; /* Use for XDR alignment */ 00991 int op_attr_success = 0; 00992 00993 #ifdef _USE_NFS4_1 00994 uint32_t attrmasklist[FATTR4_FS_CHARSET_CAP]; /* List cannot be longer than FATTR4_FS_CHARSET_CAP */ 00995 uint32_t attrvalslist[FATTR4_FS_CHARSET_CAP]; /* List cannot be longer than FATTR4_FS_CHARSET_CAP */ 00996 #else 00997 uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 00998 uint32_t attrvalslist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 00999 #endif 01000 uint32_t attrmasklen = 0; 01001 char attrvalsBuffer[ATTRVALS_BUFFLEN]; 01002 01003 uint_t i = 0; 01004 uint_t j = 0; 01005 01006 cache_inode_status_t cache_status; 01007 01008 int statfscalled = 0; 01009 fsal_staticfsinfo_t * pstaticinfo = NULL ; 01010 fsal_dynamicfsinfo_t dynamicinfo; 01011 01012 if( data != NULL ) 01013 pstaticinfo = data->pcontext->export_context->fe_static_fs_info; 01014 01015 #ifdef _USE_NFS4_ACL 01016 int rc; 01017 #endif 01018 01019 /* basic init */ 01020 memset(attrvalsBuffer, 0, NFS4_ATTRVALS_BUFFLEN); 01021 #ifdef _USE_NFS4_1 01022 memset((uint32_t *) attrmasklist, 0, FATTR4_FS_CHARSET_CAP * sizeof(uint32_t)); 01023 memset((uint32_t *) attrvalslist, 0, FATTR4_FS_CHARSET_CAP * sizeof(uint32_t)); 01024 #else 01025 memset((uint32_t *) attrmasklist, 0, FATTR4_MOUNTED_ON_FILEID * sizeof(uint32_t)); 01026 memset((uint32_t *) attrvalslist, 0, FATTR4_MOUNTED_ON_FILEID * sizeof(uint32_t)); 01027 #endif 01028 01029 /* Convert the attribute bitmap to an attribute list */ 01030 nfs4_bitmap4_to_list(Bitmap, &attrmasklen, attrmasklist); 01031 01032 /* Once the bitmap has been converted to a list of attribute, manage each attribute */ 01033 LastOffset = 0; 01034 j = 0; 01035 01036 for(i = 0; i < attrmasklen; i++) 01037 { 01038 attribute_to_set = attrmasklist[i]; 01039 01040 #ifdef _USE_NFS4_1 01041 if(attrmasklist[i] > FATTR4_FS_CHARSET_CAP) 01042 #else 01043 if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID) 01044 #endif 01045 { 01046 /* Erroneous value... skip */ 01047 continue; 01048 } 01049 LogFullDebug(COMPONENT_NFS_V4, 01050 "Flag for Operation (Regular) = %d|%d is ON, name = %s reply_size = %d", 01051 attrmasklist[i], 01052 fattr4tab[attribute_to_set].val, 01053 fattr4tab[attribute_to_set].name, 01054 fattr4tab[attribute_to_set].size_fattr4); 01055 01056 op_attr_success = 0; 01057 01058 /* compute the new size for the fattr4 reply */ 01059 /* This space is to be filled below in the big switch/case statement */ 01060 switch (attribute_to_set) 01061 { 01062 case FATTR4_SUPPORTED_ATTRS: 01063 LastOffset += nfs4_supported_attrs_to_fattr(attrvalsBuffer + LastOffset); 01064 01065 /* This kind of operation is always a success */ 01066 op_attr_success = 1; 01067 break; 01068 01069 case FATTR4_TYPE: 01070 switch (pattr->type) 01071 { 01072 case FSAL_TYPE_FILE: 01073 case FSAL_TYPE_XATTR: 01074 file_type = htonl(NF4REG); /* Regular file */ 01075 break; 01076 01077 case FSAL_TYPE_DIR: 01078 file_type = htonl(NF4DIR); /* Directory */ 01079 break; 01080 01081 case FSAL_TYPE_BLK: 01082 file_type = htonl(NF4BLK); /* Special File - block device */ 01083 break; 01084 01085 case FSAL_TYPE_CHR: 01086 file_type = htonl(NF4CHR); /* Special File - character device */ 01087 break; 01088 01089 case FSAL_TYPE_LNK: 01090 file_type = htonl(NF4LNK); /* Symbolic Link */ 01091 break; 01092 01093 case FSAL_TYPE_SOCK: 01094 file_type = htonl(NF4SOCK); /* Special File - socket */ 01095 break; 01096 01097 case FSAL_TYPE_FIFO: 01098 file_type = htonl(NF4FIFO); /* Special File - fifo */ 01099 break; 01100 01101 case FSAL_TYPE_JUNCTION: 01102 /* For wanting of a better solution */ 01103 file_type = 0; 01104 op_attr_success = 0; /* This was no success */ 01105 break; 01106 } /* switch( pattr->type ) */ 01107 01108 memcpy((char *)(attrvalsBuffer + LastOffset), &file_type, sizeof(fattr4_type)); 01109 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01110 op_attr_success = 1; 01111 break; 01112 01113 case FATTR4_FH_EXPIRE_TYPE: 01114 /* For the moment, we handle only the persistent filehandle */ 01115 if(nfs_param.nfsv4_param.fh_expire == TRUE) 01116 expire_type = htonl(FH4_VOLATILE_ANY); 01117 else 01118 expire_type = htonl(FH4_PERSISTENT); 01119 memcpy((char *)(attrvalsBuffer + LastOffset), &expire_type, 01120 sizeof(expire_type)); 01121 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01122 op_attr_success = 1; 01123 break; 01124 01125 case FATTR4_CHANGE: 01126 /* a value that change when the object change. I use the file's mtime */ 01127 memset(&file_change, 0, sizeof(changeid4)); 01128 file_change = nfs_htonl64((changeid4) pattr->change); 01129 01130 memcpy((char *)(attrvalsBuffer + LastOffset), &file_change, 01131 sizeof(fattr4_change)); 01132 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01133 op_attr_success = 1; 01134 break; 01135 01136 case FATTR4_SIZE: 01137 file_size = nfs_htonl64((fattr4_size) pattr->filesize); 01138 memcpy((char *)(attrvalsBuffer + LastOffset), &file_size, sizeof(fattr4_size)); 01139 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01140 op_attr_success = 1; 01141 break; 01142 01143 case FATTR4_LINK_SUPPORT: 01144 /* HPSS NameSpace support hard link */ 01145 link_support = htonl(TRUE); 01146 memcpy((char *)(attrvalsBuffer + LastOffset), &link_support, 01147 sizeof(fattr4_link_support)); 01148 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01149 op_attr_success = 1; 01150 break; 01151 01152 case FATTR4_SYMLINK_SUPPORT: 01153 /* HPSS NameSpace support symbolic link */ 01154 symlink_support = htonl(TRUE); 01155 memcpy((char *)(attrvalsBuffer + LastOffset), &symlink_support, 01156 sizeof(fattr4_symlink_support)); 01157 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01158 op_attr_success = 1; 01159 break; 01160 01161 case FATTR4_NAMED_ATTR: 01162 /* For this version of the binary, named attributes is not supported */ 01163 named_attr = htonl(FALSE); 01164 memcpy((char *)(attrvalsBuffer + LastOffset), &named_attr, 01165 sizeof(fattr4_named_attr)); 01166 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01167 op_attr_success = 1; 01168 break; 01169 01170 case FATTR4_FSID: 01171 /* The file system id (taken from the configuration file) */ 01172 fsid.major = nfs_htonl64((uint64_t) pexport->filesystem_id.major); 01173 fsid.minor = nfs_htonl64((uint64_t) pexport->filesystem_id.minor); 01174 01175 /* If object is a directory attached to a referral, then a different fsid is to be returned 01176 * to tell the client that a different fs is being crossed */ 01177 if(nfs4_Is_Fh_Referral(objFH)) 01178 { 01179 fsid.major = ~(nfs_htonl64((uint64_t) pexport->filesystem_id.major)); 01180 fsid.minor = ~(nfs_htonl64((uint64_t) pexport->filesystem_id.minor)); 01181 } 01182 01183 memcpy((char *)(attrvalsBuffer + LastOffset), &fsid, sizeof(fattr4_fsid)); 01184 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01185 op_attr_success = 1; 01186 break; 01187 01188 case FATTR4_UNIQUE_HANDLES: 01189 /* Filehandles are unique */ 01190 unique_handles = htonl(TRUE); 01191 memcpy((char *)(attrvalsBuffer + LastOffset), &unique_handles, 01192 sizeof(fattr4_unique_handles)); 01193 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01194 op_attr_success = 1; 01195 break; 01196 01197 case FATTR4_LEASE_TIME: 01198 /* lease_time = htonl( (fattr4_lease_time)pstaticinfo->lease_time.seconds ) ; */ 01199 lease_time = htonl(nfs_param.nfsv4_param.lease_lifetime); 01200 memcpy((char *)(attrvalsBuffer + LastOffset), &lease_time, 01201 sizeof(fattr4_lease_time)); 01202 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01203 op_attr_success = 1; 01204 break; 01205 01206 case FATTR4_RDATTR_ERROR: 01207 rdattr_error = htonl(NFS4_OK); /* By default, READDIR call may use a different value */ 01208 memcpy((char *)(attrvalsBuffer + LastOffset), &rdattr_error, 01209 sizeof(fattr4_rdattr_error)); 01210 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01211 op_attr_success = 1; 01212 break; 01213 01214 case FATTR4_ACL: 01215 #ifdef _USE_NFS4_ACL 01216 rc = nfs4_encode_acl(pattr, attrvalsBuffer, &LastOffset); 01217 if(rc == 0) /* uid/gid mapping to a string failure */ 01218 LogEvent(COMPONENT_NFS_V4, "Failed to map uid/gid to a string."); 01219 #else 01220 memset(&acl, 0, sizeof(acl)); 01221 memcpy((char *)(attrvalsBuffer + LastOffset), &acl, sizeof(fattr4_acl)); 01222 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01223 #endif 01224 op_attr_success = 1; 01225 break; 01226 01227 case FATTR4_ACLSUPPORT: 01228 #ifdef _USE_NFS4_ACL 01229 aclsupport = htonl(ACL4_SUPPORT_ALLOW_ACL | ACL4_SUPPORT_DENY_ACL); 01230 #else 01231 aclsupport = htonl(0); 01232 #endif 01233 memcpy((char *)(attrvalsBuffer + LastOffset), &aclsupport, 01234 sizeof(fattr4_aclsupport)); 01235 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01236 op_attr_success = 1; 01237 break; 01238 01239 case FATTR4_ARCHIVE: 01240 /* Archive flag is not supported */ 01241 archive = htonl(FALSE); 01242 memcpy((char *)(attrvalsBuffer + LastOffset), &archive, sizeof(fattr4_archive)); 01243 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01244 op_attr_success = 1; 01245 break; 01246 01247 case FATTR4_CANSETTIME: 01248 /* The time can be set on files */ 01249 cansettime = htonl(TRUE); 01250 memcpy((char *)(attrvalsBuffer + LastOffset), &cansettime, 01251 sizeof(fattr4_cansettime)); 01252 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01253 op_attr_success = 1; 01254 break; 01255 01256 case FATTR4_CASE_INSENSITIVE: 01257 case_insensitive = htonl(pstaticinfo->case_insensitive); 01258 memcpy((char *)(attrvalsBuffer + LastOffset), &case_insensitive, 01259 sizeof(fattr4_case_insensitive)); 01260 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01261 op_attr_success = 1; 01262 break; 01263 01264 case FATTR4_CASE_PRESERVING: 01265 case_preserving = htonl(pstaticinfo->case_preserving); 01266 memcpy((char *)(attrvalsBuffer + LastOffset), &case_preserving, 01267 sizeof(fattr4_case_preserving)); 01268 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01269 op_attr_success = 1; 01270 break; 01271 01272 case FATTR4_CHOWN_RESTRICTED: 01273 /* chown is restricted to root */ 01274 chown_restricted = htonl(pstaticinfo->chown_restricted); 01275 memcpy((char *)(attrvalsBuffer + LastOffset), &chown_restricted, 01276 sizeof(fattr4_chown_restricted)); 01277 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01278 op_attr_success = 1; 01279 break; 01280 01281 case FATTR4_FILEHANDLE: 01282 /* Return the file handle */ 01283 fhandle_len = htonl(objFH->nfs_fh4_len); 01284 memcpy((char *)(attrvalsBuffer + LastOffset), &fhandle_len, sizeof(u_int)); 01285 LastOffset += sizeof(u_int); 01286 01287 memcpy((char *)(attrvalsBuffer + LastOffset), 01288 objFH->nfs_fh4_val, objFH->nfs_fh4_len); 01289 LastOffset += objFH->nfs_fh4_len; 01290 01291 /* XDR's special stuff for 32-bit alignment */ 01292 len = objFH->nfs_fh4_len; 01293 off = 0; 01294 while((len + off) % 4 != 0) 01295 { 01296 char c = '\0'; 01297 01298 off += 1; 01299 memset((char *)(attrvalsBuffer + LastOffset), (int)c, 1); 01300 LastOffset += 1; 01301 } 01302 01303 op_attr_success = 1; 01304 break; 01305 01306 case FATTR4_FILEID: 01307 /* The analog to the inode number. RFC3530 says "a number uniquely identifying the file within the filesystem" 01308 * I use hpss_GetObjId to extract this information from the Name Server's handle */ 01309 file_id = nfs_htonl64(pattr->fileid); 01310 memcpy((char *)(attrvalsBuffer + LastOffset), &file_id, sizeof(fattr4_fileid)); 01311 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01312 op_attr_success = 1; 01313 break; 01314 01315 case FATTR4_FILES_AVAIL: 01316 if(!statfscalled) 01317 { 01318 if((cache_status = cache_inode_statfs(data->current_entry, 01319 &dynamicinfo, 01320 data->pcontext, 01321 &cache_status)) != 01322 CACHE_INODE_SUCCESS) 01323 { 01324 op_attr_success = 0; 01325 break; 01326 } 01327 else 01328 statfscalled = 1; 01329 } 01330 files_avail = nfs_htonl64((fattr4_files_avail) dynamicinfo.avail_files); 01331 memcpy((char *)(attrvalsBuffer + LastOffset), &files_avail, 01332 sizeof(fattr4_files_avail)); 01333 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01334 op_attr_success = 1; 01335 break; 01336 01337 case FATTR4_FILES_FREE: 01338 if(!statfscalled) 01339 { 01340 if((cache_status = cache_inode_statfs(data->current_entry, 01341 &dynamicinfo, 01342 data->pcontext, 01343 &cache_status)) != 01344 CACHE_INODE_SUCCESS) 01345 { 01346 op_attr_success = 0; 01347 break; 01348 } 01349 else 01350 statfscalled = 1; 01351 } 01352 files_free = nfs_htonl64((fattr4_files_avail) dynamicinfo.free_files); 01353 memcpy((char *)(attrvalsBuffer + LastOffset), &files_free, 01354 sizeof(fattr4_files_free)); 01355 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01356 op_attr_success = 1; 01357 break; 01358 01359 case FATTR4_FILES_TOTAL: 01360 if(!statfscalled) 01361 { 01362 if((cache_status = cache_inode_statfs(data->current_entry, 01363 &dynamicinfo, 01364 data->pcontext, 01365 &cache_status)) != 01366 CACHE_INODE_SUCCESS) 01367 { 01368 op_attr_success = 0; 01369 break; 01370 } 01371 else 01372 statfscalled = 1; 01373 } 01374 files_total = nfs_htonl64((fattr4_files_avail) dynamicinfo.total_files); 01375 memcpy((char *)(attrvalsBuffer + LastOffset), &files_total, 01376 sizeof(fattr4_files_total)); 01377 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01378 op_attr_success = 1; 01379 break; 01380 01381 case FATTR4_FS_LOCATIONS: 01382 if(data->current_entry->type != DIRECTORY) 01383 { 01384 op_attr_success = 0; 01385 break; 01386 } 01387 01388 if(!nfs4_referral_str_To_Fattr_fs_location 01389 (data->current_entry->object.dir.referral, tmp_buff, &tmp_int)) 01390 { 01391 op_attr_success = 0; 01392 break; 01393 } 01394 01395 memcpy((char *)(attrvalsBuffer + LastOffset), tmp_buff, tmp_int); 01396 LastOffset += tmp_int; 01397 op_attr_success = 1; 01398 break; 01399 01400 case FATTR4_HIDDEN: 01401 /* There are no hidden file in HPSS */ 01402 hidden = htonl(FALSE); 01403 memcpy((char *)(attrvalsBuffer + LastOffset), &hidden, sizeof(fattr4_hidden)); 01404 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01405 op_attr_success = 1; 01406 break; 01407 01408 case FATTR4_HOMOGENEOUS: 01409 /* Unix semantic is homogeneous (all objects have the same kind of attributes) */ 01410 homogeneous = htonl(TRUE); 01411 memcpy((char *)(attrvalsBuffer + LastOffset), &homogeneous, 01412 sizeof(fattr4_homogeneous)); 01413 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01414 op_attr_success = 1; 01415 break; 01416 01417 case FATTR4_MAXFILESIZE: 01418 max_filesize = nfs_htonl64((fattr4_maxfilesize) FSINFO_MAX_FILESIZE); 01419 memcpy((char *)(attrvalsBuffer + LastOffset), &max_filesize, 01420 sizeof(fattr4_maxfilesize)); 01421 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01422 op_attr_success = 1; 01423 break; 01424 01425 case FATTR4_MAXLINK: 01426 maxlink = htonl(pstaticinfo->maxlink); 01427 memcpy((char *)(attrvalsBuffer + LastOffset), &maxlink, sizeof(fattr4_maxlink)); 01428 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01429 op_attr_success = 1; 01430 break; 01431 01432 case FATTR4_MAXNAME: 01433 maxname = htonl((fattr4_maxname) pstaticinfo->maxnamelen); 01434 memcpy((char *)(attrvalsBuffer + LastOffset), &maxname, sizeof(fattr4_maxname)); 01435 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01436 op_attr_success = 1; 01437 break; 01438 01439 case FATTR4_MAXREAD: 01440 /* The exports.c MAXREAD-MAXWRITE code establishes these semantics: 01441 * a. If you set the MaxWrite and MaxRead defaults in an export file 01442 * they apply. 01443 * b. If you set the MaxWrite and MaxRead defaults in the main.conf 01444 * file they apply unless overwritten by an export file setting. 01445 * c. If no settings are present in the export file or the main.conf 01446 * file then the defaults values in the FSAL apply. 01447 */ 01448 01449 maxread = nfs_htonl64((fattr4_maxread) pexport->MaxRead ); 01450 memcpy((char *)(attrvalsBuffer + LastOffset), &maxread, sizeof(fattr4_maxread)); 01451 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01452 op_attr_success = 1; 01453 break; 01454 01455 case FATTR4_MAXWRITE: 01456 maxwrite = nfs_htonl64((fattr4_maxwrite) pexport->MaxWrite ); 01457 memcpy((char *)(attrvalsBuffer + LastOffset), &maxwrite, 01458 sizeof(fattr4_maxwrite)); 01459 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01460 op_attr_success = 1; 01461 break; 01462 01463 case FATTR4_MIMETYPE: 01464 memset((char *)(attrvalsBuffer + LastOffset), 0, 01465 sizeof(fattr4_mimetype)); 01466 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01467 op_attr_success = 0; /* No supported for the moment */ 01468 break; 01469 01470 case FATTR4_MODE: 01471 /* file_mode = (fattr4_mode) htonl(fsal2unix_mode(pattr->mode)) ; */ 01472 file_mode = htonl((fattr4_mode) fsal2unix_mode(pattr->mode)); 01473 memcpy((char *)(attrvalsBuffer + LastOffset), &file_mode, sizeof(fattr4_mode)); 01474 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01475 op_attr_success = 1; 01476 break; 01477 01478 case FATTR4_NO_TRUNC: 01479 /* File's names are not truncated, an error is returned is name is too long */ 01480 no_trunc = htonl(pstaticinfo->no_trunc); 01481 memcpy((char *)(attrvalsBuffer + LastOffset), &no_trunc, 01482 sizeof(fattr4_no_trunc)); 01483 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01484 op_attr_success = 1; 01485 break; 01486 01487 case FATTR4_NUMLINKS: 01488 /* Reply the number of links found in vattr structure */ 01489 file_numlinks = htonl((fattr4_numlinks) pattr->numlinks); 01490 memcpy((char *)(attrvalsBuffer + LastOffset), &file_numlinks, 01491 sizeof(fattr4_numlinks)); 01492 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01493 op_attr_success = 1; 01494 break; 01495 01496 case FATTR4_OWNER: 01497 /* Return the uid as a human readable utf8 string */ 01498 if(uid2utf8(pattr->owner, &file_owner) == 0) 01499 { 01500 LastOffset += nfs_tools_xdr_utf8(&file_owner, 01501 (char *)(attrvalsBuffer + LastOffset)); 01502 op_attr_success = 1; 01503 } 01504 else 01505 op_attr_success = 0; 01506 break; 01507 01508 case FATTR4_OWNER_GROUP: 01509 /* Return the gid as a human-readable utf8 string */ 01510 if(gid2utf8(pattr->group, &file_owner_group) == 0) 01511 { 01512 LastOffset += nfs_tools_xdr_utf8(&file_owner_group, 01513 (char *)(attrvalsBuffer + LastOffset)); 01514 op_attr_success = 1; 01515 } 01516 else 01517 op_attr_success = 0; 01518 break; 01519 01520 case FATTR4_QUOTA_AVAIL_HARD: 01521 quota_avail_hard = nfs_htonl64((fattr4_quota_avail_hard) NFS_V4_MAX_QUOTA_HARD); 01522 memcpy((char *)(attrvalsBuffer + LastOffset), "a_avail_hard, 01523 sizeof(fattr4_quota_avail_hard)); 01524 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01525 op_attr_success = 0; 01526 break; 01527 01528 case FATTR4_QUOTA_AVAIL_SOFT: 01529 quota_avail_soft = nfs_htonl64((fattr4_quota_avail_soft) NFS_V4_MAX_QUOTA_SOFT); 01530 memcpy((char *)(attrvalsBuffer + LastOffset), "a_avail_soft, 01531 sizeof(fattr4_quota_avail_soft)); 01532 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01533 op_attr_success = 0; 01534 break; 01535 01536 case FATTR4_QUOTA_USED: 01537 quota_used = nfs_htonl64((fattr4_quota_used) pattr->filesize); 01538 memcpy((char *)(attrvalsBuffer + LastOffset), "a_used, 01539 sizeof(fattr4_quota_used)); 01540 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01541 op_attr_success = 0; 01542 break; 01543 01544 case FATTR4_RAWDEV: 01545 rawdev.specdata1 = htonl(pattr->rawdev.major); 01546 rawdev.specdata2 = htonl(pattr->rawdev.minor); 01547 memcpy((char *)(attrvalsBuffer + LastOffset), &rawdev, sizeof(fattr4_rawdev)); 01548 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01549 op_attr_success = 1; 01550 break; 01551 01552 case FATTR4_SPACE_AVAIL: 01553 if(!statfscalled) 01554 { 01555 if((cache_status = cache_inode_statfs(data->current_entry, 01556 &dynamicinfo, 01557 data->pcontext, 01558 &cache_status)) != 01559 CACHE_INODE_SUCCESS) 01560 { 01561 op_attr_success = 0; 01562 break; 01563 } 01564 else 01565 statfscalled = 1; 01566 } 01567 space_avail = nfs_htonl64((fattr4_space_avail) dynamicinfo.avail_bytes); 01568 memcpy((char *)(attrvalsBuffer + LastOffset), &space_avail, 01569 sizeof(fattr4_space_avail)); 01570 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01571 op_attr_success = 1; 01572 break; 01573 01574 case FATTR4_SPACE_FREE: 01575 if(!statfscalled) 01576 { 01577 if((cache_status = cache_inode_statfs(data->current_entry, 01578 &dynamicinfo, 01579 data->pcontext, 01580 &cache_status)) != 01581 CACHE_INODE_SUCCESS) 01582 { 01583 op_attr_success = 0; 01584 break; 01585 } 01586 else 01587 statfscalled = 1; 01588 } 01589 space_free = nfs_htonl64((fattr4_space_free) dynamicinfo.free_bytes); 01590 memcpy((char *)(attrvalsBuffer + LastOffset), &space_free, 01591 sizeof(fattr4_space_free)); 01592 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01593 op_attr_success = 1; 01594 break; 01595 01596 case FATTR4_SPACE_TOTAL: 01597 if(!statfscalled) 01598 { 01599 if((cache_status = cache_inode_statfs(data->current_entry, 01600 &dynamicinfo, 01601 data->pcontext, 01602 &cache_status)) != 01603 CACHE_INODE_SUCCESS) 01604 { 01605 op_attr_success = 0; 01606 break; 01607 } 01608 else 01609 statfscalled = 1; 01610 } 01611 space_total = nfs_htonl64((fattr4_space_total) dynamicinfo.total_bytes); 01612 memcpy((char *)(attrvalsBuffer + LastOffset), &space_total, 01613 sizeof(fattr4_space_total)); 01614 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01615 op_attr_success = 1; 01616 break; 01617 01618 case FATTR4_SPACE_USED: 01619 /* the number of bytes on the filesystem used by the object, which is slightly different 01620 * from the file's size (there can be hole in the file) */ 01621 file_space_used = nfs_htonl64((fattr4_space_used) pattr->spaceused); 01622 memcpy((char *)(attrvalsBuffer + LastOffset), &file_space_used, 01623 sizeof(fattr4_space_used)); 01624 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01625 op_attr_success = 1; 01626 break; 01627 01628 case FATTR4_SYSTEM: 01629 /* This is not a windows system File-System with respect to the regarding API */ 01630 system = htonl(FALSE); 01631 memcpy((char *)(attrvalsBuffer + LastOffset), &system, sizeof(fattr4_system)); 01632 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01633 op_attr_success = 1; 01634 break; 01635 01636 case FATTR4_TIME_ACCESS: 01637 /* This will contain the object's time os last access, the 'atime' in the Unix semantic */ 01638 memset(&(time_access.seconds), 0, sizeof(int64_t)); 01639 time_access.seconds = nfs_htonl64((int64_t) pattr->atime.seconds); 01640 time_access.nseconds = htonl((uint32_t) pattr->atime.nseconds); 01641 memcpy((char *)(attrvalsBuffer + LastOffset), &time_access, 01642 fattr4tab[attribute_to_set].size_fattr4); 01643 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01644 op_attr_success = 1; 01645 break; 01646 01647 case FATTR4_TIME_ACCESS_SET: 01648 LastOffset += fsal_time_to_settime4(&pattr->atime, 01649 attrvalsBuffer + LastOffset); 01650 op_attr_success = 1; 01651 break; 01652 01653 case FATTR4_TIME_BACKUP: 01654 /* No time backup, return unix's beginning of time */ 01655 case FATTR4_TIME_CREATE: 01656 /* No time create, return unix's beginning of time */ 01657 time_create.seconds = nfs_htonl64(0LL); 01658 time_create.nseconds = htonl(0); 01659 memcpy((char *)(attrvalsBuffer + LastOffset), &time_create, 01660 fattr4tab[attribute_to_set].size_fattr4); 01661 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01662 op_attr_success = 1; 01663 break; 01664 01665 case FATTR4_TIME_DELTA: 01666 /* According to RFC3530, this is "the smallest usefull server time granularity", I set this to 1s */ 01667 time_delta.seconds = nfs_htonl64(1LL); 01668 time_delta.nseconds = htonl(0); 01669 memcpy((char *)(attrvalsBuffer + LastOffset), &time_delta, 01670 fattr4tab[attribute_to_set].size_fattr4); 01671 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01672 op_attr_success = 1; 01673 break; 01674 01675 case FATTR4_TIME_METADATA: 01676 /* The time for the last metadata operation, the ctime in the unix's semantic */ 01677 memset(&(time_metadata.seconds), 0, sizeof(int64_t)); 01678 time_metadata.seconds = nfs_htonl64((int64_t) pattr->ctime.seconds); 01679 time_metadata.nseconds = htonl(pattr->ctime.nseconds); 01680 memcpy((char *)(attrvalsBuffer + LastOffset), &time_metadata, 01681 fattr4tab[attribute_to_set].size_fattr4); 01682 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01683 op_attr_success = 1; 01684 break; 01685 01686 case FATTR4_TIME_MODIFY: 01687 /* The time for the last modify operation, the mtime in the unix's semantic */ 01688 memset(&(time_modify.seconds), 0, sizeof(int64_t)); 01689 time_modify.seconds = nfs_htonl64((int64_t) pattr->mtime.seconds); 01690 time_modify.nseconds = htonl(pattr->mtime.nseconds); 01691 01692 memcpy((char *)(attrvalsBuffer + LastOffset), &time_modify, 01693 fattr4tab[attribute_to_set].size_fattr4); 01694 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01695 op_attr_success = 1; 01696 break; 01697 01698 case FATTR4_TIME_MODIFY_SET: 01699 LastOffset += fsal_time_to_settime4(&pattr->mtime, 01700 attrvalsBuffer + LastOffset); 01701 op_attr_success = 1; 01702 break; 01703 01704 case FATTR4_MOUNTED_ON_FILEID: 01705 file_id = nfs_htonl64(pattr->fileid); 01706 memcpy((char *)(attrvalsBuffer + LastOffset), &file_id, sizeof(fattr4_fileid)); 01707 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01708 op_attr_success = 1; 01709 break; 01710 01711 #ifdef _USE_NFS4_1 01712 case FATTR4_FS_LAYOUT_TYPES: 01713 #ifdef _PNFS_MDS 01714 *((uint32_t*)(attrvalsBuffer+LastOffset)) 01715 = htonl(pstaticinfo->fs_layout_types 01716 .fattr4_fs_layout_types_len); 01717 01718 LastOffset += sizeof(uint32_t); 01719 for (k = 0; k < (pstaticinfo->fs_layout_types 01720 .fattr4_fs_layout_types_len); k++) 01721 { 01722 *((layouttype4*)(attrvalsBuffer+LastOffset)) 01723 = htonl((pstaticinfo->fs_layout_types 01724 .fattr4_fs_layout_types_val[k])); 01725 LastOffset += sizeof(layouttype4); 01726 } 01727 01728 op_attr_success = 1; 01729 break; 01730 #endif /* _PNFS_MDS */ 01731 01732 #ifdef _PNFS_MDS 01733 case FATTR4_LAYOUT_BLKSIZE: 01734 layout_blksize 01735 = htonl((fattr4_layout_blksize) pstaticinfo->layout_blksize); 01736 memcpy((char *)(attrvalsBuffer + LastOffset), 01737 &layout_blksize, sizeof(fattr4_layout_blksize)); 01738 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 01739 01740 op_attr_success = 1; 01741 break; 01742 #endif /* _PNFS_MDS */ 01743 #endif /* _USE_NFS4_1 */ 01744 01745 default: 01746 LogFullDebug(COMPONENT_NFS_V4, 01747 " unsupported value for attributes bitmap = %u", attribute_to_set); 01748 01749 op_attr_success = 0; 01750 break; 01751 } /* switch( attribute_to_set ) */ 01752 01753 /* Increase the Offset for the next operation if this was a success */ 01754 if(op_attr_success) 01755 { 01756 /* Set the returned bitmask */ 01757 attrvalslist[j] = attribute_to_set; 01758 j += 1; 01759 01760 /* Be carefull not to get out of attrvalsBuffer */ 01761 if(LastOffset > ATTRVALS_BUFFLEN) 01762 return -1; 01763 } 01764 01765 } /* for i */ 01766 01767 return nfs4_Fattr_Fill(Fattr, j, attrvalslist, LastOffset, attrvalsBuffer); 01768 } /* nfs4_FSALattr_To_Fattr */ 01769 01782 int nfs3_Sattr_To_FSALattr(fsal_attrib_list_t * pFSAL_attr, /* Out: file attributes */ 01783 sattr3 * psattr) /* In: file attributes */ 01784 { 01785 struct timeval t; 01786 01787 if(pFSAL_attr == NULL || psattr == NULL) 01788 return 0; 01789 01790 pFSAL_attr->asked_attributes = 0; 01791 01792 if(psattr->mode.set_it == TRUE) 01793 { 01794 LogFullDebug(COMPONENT_NFSPROTO, 01795 "nfs3_Sattr_To_FSALattr: mode = %o", 01796 psattr->mode.set_mode3_u.mode); 01797 pFSAL_attr->mode = unix2fsal_mode(psattr->mode.set_mode3_u.mode); 01798 pFSAL_attr->asked_attributes |= FSAL_ATTR_MODE; 01799 } 01800 01801 if(psattr->uid.set_it == TRUE) 01802 { 01803 LogFullDebug(COMPONENT_NFSPROTO, 01804 "nfs3_Sattr_To_FSALattr: uid = %d", 01805 psattr->uid.set_uid3_u.uid); 01806 pFSAL_attr->owner = psattr->uid.set_uid3_u.uid; 01807 pFSAL_attr->asked_attributes |= FSAL_ATTR_OWNER; 01808 } 01809 01810 if(psattr->gid.set_it == TRUE) 01811 { 01812 LogFullDebug(COMPONENT_NFSPROTO, 01813 "nfs3_Sattr_To_FSALattr: gid = %d", 01814 psattr->gid.set_gid3_u.gid); 01815 pFSAL_attr->group = psattr->gid.set_gid3_u.gid; 01816 pFSAL_attr->asked_attributes |= FSAL_ATTR_GROUP; 01817 } 01818 01819 if(psattr->size.set_it == TRUE) 01820 { 01821 LogFullDebug(COMPONENT_NFSPROTO, 01822 "nfs3_Sattr_To_FSALattr: size = %lld", 01823 psattr->size.set_size3_u.size); 01824 pFSAL_attr->filesize = (fsal_size_t) psattr->size.set_size3_u.size; 01825 pFSAL_attr->spaceused = (fsal_size_t) psattr->size.set_size3_u.size; 01826 /* Both FSAL_ATTR_SIZE and FSAL_ATTR_SPACEUSED are to be managed */ 01827 pFSAL_attr->asked_attributes |= FSAL_ATTR_SIZE; 01828 pFSAL_attr->asked_attributes |= FSAL_ATTR_SPACEUSED; 01829 } 01830 01831 if(psattr->atime.set_it != DONT_CHANGE) 01832 { 01833 LogFullDebug(COMPONENT_NFSPROTO, 01834 "nfs3_Sattr_To_FSALattr: set=%d atime = %d,%d", 01835 psattr->atime.set_it, psattr->atime.set_atime_u.atime.seconds, 01836 psattr->atime.set_atime_u.atime.nseconds); 01837 if(psattr->atime.set_it == SET_TO_CLIENT_TIME) 01838 { 01839 pFSAL_attr->atime.seconds = psattr->atime.set_atime_u.atime.seconds; 01840 pFSAL_attr->atime.nseconds = 0; 01841 } 01842 else 01843 { 01844 /* Use the server's current time */ 01845 gettimeofday(&t, NULL); 01846 01847 pFSAL_attr->atime.seconds = t.tv_sec; 01848 pFSAL_attr->atime.nseconds = 0; 01849 } 01850 pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME; 01851 } 01852 01853 if(psattr->mtime.set_it != DONT_CHANGE) 01854 { 01855 LogFullDebug(COMPONENT_NFSPROTO, 01856 "nfs3_Sattr_To_FSALattr: set=%d mtime = %d", 01857 psattr->atime.set_it, psattr->mtime.set_mtime_u.mtime.seconds ) ; 01858 if(psattr->mtime.set_it == SET_TO_CLIENT_TIME) 01859 { 01860 pFSAL_attr->mtime.seconds = psattr->mtime.set_mtime_u.mtime.seconds; 01861 pFSAL_attr->mtime.nseconds = 0 ; 01862 } 01863 else 01864 { 01865 /* Use the server's current time */ 01866 gettimeofday(&t, NULL); 01867 pFSAL_attr->mtime.seconds = t.tv_sec; 01868 pFSAL_attr->mtime.nseconds = 0 ; 01869 } 01870 pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME; 01871 } 01872 01873 return 1; 01874 } /* nfs3_Sattr_To_FSALattr */ 01875 01889 int nfs2_FSALattr_To_Fattr(exportlist_t * pexport, /* In: the related export entry */ 01890 fsal_attrib_list_t * pFSAL_attr, /* In: file attributes */ 01891 fattr2 * pFattr) /* Out: file attributes */ 01892 { 01893 /* Badly formed arguments */ 01894 if(pFSAL_attr == NULL || pFattr == NULL) 01895 return 0; 01896 01897 /* @todo BUGAZOMEU: sanity check on attribute mask (does the FSAL support the attributes required to support NFSv2 ? */ 01898 01899 /* initialize mode */ 01900 pFattr->mode = 0; 01901 01902 switch (pFSAL_attr->type) 01903 { 01904 case FSAL_TYPE_FILE: 01905 pFattr->type = NFREG; 01906 pFattr->mode = NFS2_MODE_NFREG; 01907 break; 01908 01909 case FSAL_TYPE_DIR: 01910 pFattr->type = NFDIR; 01911 pFattr->mode = NFS2_MODE_NFDIR; 01912 break; 01913 01914 case FSAL_TYPE_BLK: 01915 pFattr->type = NFBLK; 01916 pFattr->mode = NFS2_MODE_NFBLK; 01917 break; 01918 01919 case FSAL_TYPE_CHR: 01920 pFattr->type = NFCHR; 01921 pFattr->mode = NFS2_MODE_NFCHR; 01922 break; 01923 01924 case FSAL_TYPE_FIFO: 01925 pFattr->type = NFFIFO; 01927 break; 01928 01929 case FSAL_TYPE_LNK: 01930 pFattr->type = NFLNK; 01931 pFattr->mode = NFS2_MODE_NFLNK; 01932 break; 01933 01934 case FSAL_TYPE_SOCK: 01935 pFattr->type = NFSOCK; 01937 break; 01938 01939 case FSAL_TYPE_XATTR: 01940 case FSAL_TYPE_JUNCTION: 01941 pFattr->type = NFBAD; 01942 } 01943 01944 pFattr->mode |= fsal2unix_mode(pFSAL_attr->mode); 01945 pFattr->nlink = pFSAL_attr->numlinks; 01946 pFattr->uid = pFSAL_attr->owner; 01947 pFattr->gid = pFSAL_attr->group; 01948 01949 /* in NFSv2, it only keeps fsid.major, casted into an into an int32 */ 01950 pFattr->fsid = (u_int) (pexport->filesystem_id.major & 0xFFFFFFFFLL); 01951 01952 LogFullDebug(COMPONENT_NFSPROTO, 01953 "nfs2_FSALattr_To_Fattr: fsid.major = %#llX (%llu), fsid.minor = %#llX (%llu), nfs2_fsid = %#X (%u)", 01954 pexport->filesystem_id.major, pexport->filesystem_id.major, 01955 pexport->filesystem_id.minor, pexport->filesystem_id.minor, pFattr->fsid, 01956 pFattr->fsid); 01957 01958 if(pFSAL_attr->filesize > NFS2_MAX_FILESIZE) 01959 pFattr->size = NFS2_MAX_FILESIZE; 01960 else 01961 pFattr->size = pFSAL_attr->filesize; 01962 01963 pFattr->blocksize = DEV_BSIZE; 01964 01965 pFattr->blocks = pFattr->size >> 9; /* dividing by 512 */ 01966 if(pFattr->size % DEV_BSIZE != 0) 01967 pFattr->blocks += 1; 01968 01969 if(pFSAL_attr->type == FSAL_TYPE_CHR || pFSAL_attr->type == FSAL_TYPE_BLK) 01970 pFattr->rdev = pFSAL_attr->rawdev.major; 01971 else 01972 pFattr->rdev = 0; 01973 01974 pFattr->atime.seconds = pFSAL_attr->atime.seconds; 01975 pFattr->atime.useconds = pFSAL_attr->atime.nseconds / 1000; 01976 pFattr->mtime.seconds = pFSAL_attr->mtime.seconds; 01977 pFattr->mtime.useconds = pFSAL_attr->mtime.nseconds / 1000; 01978 pFattr->ctime.seconds = pFSAL_attr->ctime.seconds; 01979 pFattr->ctime.useconds = pFSAL_attr->ctime.nseconds / 1000; 01980 pFattr->fileid = pFSAL_attr->fileid; 01981 01982 return 1; 01983 } /* nfs2_FSALattr_To_Fattr */ 01984 01997 int nfs4_SetCompoundExport(compound_data_t * data) 01998 { 01999 short exportid; 02000 02001 /* This routine is not related to pseudo fs file handle, do not handle them */ 02002 if(nfs4_Is_Fh_Pseudo(&(data->currentFH))) 02003 return NFS4_OK; 02004 02005 /* Get the export id */ 02006 if((exportid = nfs4_FhandleToExportId(&(data->currentFH))) == 0) 02007 return NFS4ERR_BADHANDLE; 02008 02009 if((data->pexport = nfs_Get_export_by_id(data->pfullexportlist, exportid)) == NULL) 02010 return NFS4ERR_BADHANDLE; 02011 02012 if((data->pexport->options & EXPORT_OPTION_NFSV4) == 0) 02013 return NFS4ERR_ACCESS; 02014 02015 if(nfs4_MakeCred(data) != NFS4_OK) 02016 return NFS4ERR_WRONGSEC; 02017 02018 return NFS4_OK; 02019 } /* nfs4_SetCompoundExport */ 02020 02033 int nfs4_FhandleToExId(nfs_fh4 * fh4p, unsigned short *ExIdp) 02034 { 02035 file_handle_v4_t *pfhandle4; 02036 02037 /* Map the filehandle to the correct structure */ 02038 pfhandle4 = (file_handle_v4_t *) (fh4p->nfs_fh4_val); 02039 02040 /* The function should not be used on a pseudo fhandle */ 02041 if(pfhandle4->pseudofs_flag == TRUE) 02042 return FALSE; 02043 02044 *ExIdp = pfhandle4->exportid; 02045 return TRUE; 02046 } /* nfs4_FhandleToExId */ 02047 02048 /**** Glue related functions ****/ 02049 02063 void nfs4_stringid_split(char *buff, char *uidname, char *domainname) 02064 { 02065 char *c = NULL; 02066 unsigned int i = 0; 02067 02068 for(c = buff, i = 0; *c != '\0'; c++, i++) 02069 if(*c == '@') 02070 break; 02071 02072 strncpy(uidname, buff, i); 02073 uidname[i] = '\0'; 02074 strcpy(domainname, c); 02075 02076 LogFullDebug(COMPONENT_NFS_V4, 02077 "buff = #%s# uid = #%s# domain = #%s#", 02078 buff, uidname, domainname); 02079 } /* nfs4_stringid_split */ 02080 02088 void free_utf8(utf8string * utf8str) 02089 { 02090 if(utf8str != NULL) 02091 { 02092 if(utf8str->utf8string_val != NULL) 02093 gsh_free(utf8str->utf8string_val); 02094 utf8str->utf8string_val = 0; 02095 utf8str->utf8string_len = 0; 02096 } 02097 } 02098 02109 int utf8dup(utf8string * newstr, utf8string * oldstr) 02110 { 02111 if(newstr == NULL) 02112 return -1; 02113 02114 newstr->utf8string_len = oldstr->utf8string_len; 02115 newstr->utf8string_val = NULL; 02116 02117 if(oldstr->utf8string_len == 0 || oldstr->utf8string_val == NULL) 02118 return 0; 02119 02120 newstr->utf8string_val = gsh_malloc(oldstr->utf8string_len); 02121 if(newstr->utf8string_val == NULL) 02122 return -1; 02123 02124 strncpy(newstr->utf8string_val, oldstr->utf8string_val, oldstr->utf8string_len); 02125 02126 return 0; 02127 } /* uft82str */ 02128 02141 int utf82str(char *str, int size, utf8string * utf8str) 02142 { 02143 int copy; 02144 02145 if(str == NULL) 02146 return -1; 02147 02148 if(utf8str == NULL || utf8str->utf8string_len == 0) 02149 { 02150 str[0] = '\0'; 02151 return -1; 02152 } 02153 02154 if(utf8str->utf8string_len >= size) 02155 copy = size - 1; 02156 else 02157 copy = utf8str->utf8string_len; 02158 02159 strncpy(str, utf8str->utf8string_val, copy); 02160 str[copy] = '\0'; 02161 02162 if(copy < utf8str->utf8string_len) 02163 return -1; 02164 02165 return 0; 02166 } /* uft82str */ 02167 02180 int str2utf8(char *str, utf8string * utf8str) 02181 { 02182 uint_t len; 02183 char buff[MAXNAMLEN]; 02184 02185 /* The uft8 will probably be sent over XDR, for this reason, its size MUST be a multiple of 32 bits = 4 bytes */ 02186 strcpy(buff, str); 02187 len = strlen(buff); 02188 02189 /* BUGAZOMEU: TO BE DONE: use STUFF ALLOCATOR here */ 02190 if(utf8str->utf8string_val == NULL) 02191 return -1; 02192 02193 utf8str->utf8string_len = len; 02194 memcpy(utf8str->utf8string_val, buff, utf8str->utf8string_len); 02195 return 0; 02196 } /* str2utf8 */ 02197 02210 seqid4 nfs4_NextSeqId(seqid4 seqid) 02211 { 02212 return ((seqid + 1) % 0xFFFFFFFF); 02213 } /* nfs4_NextSeqId */ 02214 02229 /* 02230 * bitmap is usually 2 x uint32_t which makes a uint64_t 02231 * 02232 * Structure of the bitmap is as follow 02233 * 02234 * 0 1 02235 * +-------+---------+----------+- 02236 * | count | 31 .. 0 | 63 .. 32 | 02237 * +-------+---------+----------+- 02238 * 02239 * One bit is set for every possible attributes. The bits are packed together in a uint32_T (XDR alignment reason probably) 02240 * As said in the RFC3530, the n-th bit is with the uint32_t #(n/32), and its position with the uint32_t is n % 32 02241 * Example 02242 * 1st bit = FATTR4_TYPE = 1 02243 * 2nd bit = FATTR4_LINK_SUPPORT = 5 02244 * 3rd bit = FATTR4_SYMLINK_SUPPORT = 6 02245 * 02246 * Juste one uint32_t is necessay: 2**1 + 2**5 + 2**6 = 2 + 32 + 64 = 98 02247 * +---+----+ 02248 * | 1 | 98 | 02249 * +---+----+ 02250 * 02251 * Other Example 02252 * 02253 * 1st bit = FATTR4_LINK_SUPPORT = 5 02254 * 2nd bit = FATTR4_SYMLINK_SUPPORT = 6 02255 * 3rd bit = FATTR4_MODE = 33 02256 * 4th bit = FATTR4_OWNER = 36 02257 * 02258 * Two uint32_t will be necessary there: 02259 * #1 = 2**5 + 2**6 = 32 + 64 = 96 02260 # #2 = 2**(33-32) + 2**(36-32) = 2**1 + 2**4 = 2 + 16 = 18 02261 * +---+----+----+ 02262 * | 2 | 98 | 18 | 02263 * +---+----+----+ 02264 * 02265 */ 02266 02267 void nfs4_bitmap4_to_list(bitmap4 * b, uint_t * plen, uint32_t * pval) 02268 { 02269 uint_t i = 0; 02270 uint_t val = 0; 02271 uint_t index = 0; 02272 uint_t offset = 0; 02273 uint_t fattr4tabidx=0; 02274 if(b->bitmap4_len > 0) 02275 LogFullDebug(COMPONENT_NFS_V4, "Bitmap: Len = %u Val = %u|%u", 02276 b->bitmap4_len, b->bitmap4_val[0], b->bitmap4_val[1]); 02277 else 02278 LogFullDebug(COMPONENT_NFS_V4, "Bitmap: Len = %u ... ", b->bitmap4_len); 02279 02280 for(offset = 0; offset < b->bitmap4_len; offset++) 02281 { 02282 for(i = 0; i < 32; i++) 02283 { 02284 fattr4tabidx = i+32*offset; 02285 #ifdef _USE_NFS4_1 02286 if (fattr4tabidx > FATTR4_FS_CHARSET_CAP) 02287 #else 02288 if (fattr4tabidx > FATTR4_MOUNTED_ON_FILEID) 02289 #endif 02290 goto exit; 02291 02292 val = 1 << i; /* Compute 2**i */ 02293 if(b->bitmap4_val[offset] & val) 02294 pval[index++] = fattr4tabidx; 02295 } 02296 } 02297 exit: 02298 *plen = index; 02299 02300 } /* nfs4_bitmap4_to_list */ 02301 02316 /* bitmap is usually 2 x uint32_t which makes a uint64_t 02317 * bitmap4_len is the number of uint32_t required to keep the bitmap value 02318 * 02319 * Structure of the bitmap is as follow 02320 * 02321 * 0 1 02322 * +-------+---------+----------+- 02323 * | count | 31 .. 0 | 63 .. 32 | 02324 * +-------+---------+----------+- 02325 * 02326 * One bit is set for every possible attributes. The bits are packed together in a uint32_T (XDR alignment reason probably) 02327 * As said in the RFC3530, the n-th bit is with the uint32_t #(n/32), and its position with the uint32_t is n % 32 02328 * Example 02329 * 1st bit = FATTR4_TYPE = 1 02330 * 2nd bit = FATTR4_LINK_SUPPORT = 5 02331 * 3rd bit = FATTR4_SYMLINK_SUPPORT = 6 02332 * 02333 * Juste one uint32_t is necessay: 2**1 + 2**5 + 2**6 = 2 + 32 + 64 = 98 02334 * +---+----+ 02335 * | 1 | 98 | 02336 * +---+----+ 02337 * 02338 * Other Example 02339 * 02340 * 1st bit = FATTR4_LINK_SUPPORT = 5 02341 * 2nd bit = FATTR4_SYMLINK_SUPPORT = 6 02342 * 3rd bit = FATTR4_MODE = 33 02343 * 4th bit = FATTR4_OWNER = 36 02344 * 02345 * Two uint32_t will be necessary there: 02346 * #1 = 2**5 + 2**6 = 32 + 64 = 96 02347 # #2 = 2**(33-32) + 2**(36-32) = 2**1 + 2**4 = 2 + 16 = 18 02348 * +---+----+----+ 02349 * | 2 | 98 | 18 | 02350 * +---+----+----+ 02351 * 02352 */ 02353 02354 /* This function converts a list of attributes to a bitmap4 structure */ 02355 void nfs4_list_to_bitmap4(bitmap4 * b, uint_t plen, uint32_t * pval) 02356 { 02357 uint_t i; 02358 int maxpos = -1; 02359 02360 memset(b->bitmap4_val, 0, sizeof(uint32_t)*b->bitmap4_len); 02361 02362 for(i = 0; i < plen; i++) 02363 { 02364 int intpos = pval[i] / 32; 02365 int bitpos = pval[i] % 32; 02366 02367 if(intpos >= b->bitmap4_len) 02368 { 02369 LogCrit(COMPONENT_NFS_V4, 02370 "Mismatch between bitmap len and the list: " 02371 "got %d, need %d to accomodate attribute %d", 02372 b->bitmap4_len, intpos+1, pval[i]); 02373 continue; 02374 } 02375 b->bitmap4_val[intpos] |= (1U << bitpos); 02376 if(intpos > maxpos) 02377 maxpos = intpos; 02378 } 02379 02380 b->bitmap4_len = maxpos + 1; 02381 LogFullDebug(COMPONENT_NFS_V4, "Bitmap: Len = %u Val = %u|%u|%u", 02382 b->bitmap4_len, 02383 b->bitmap4_len >= 1 ? b->bitmap4_val[0] : 0, 02384 b->bitmap4_len >= 2 ? b->bitmap4_val[1] : 0, 02385 b->bitmap4_len >= 3 ? b->bitmap4_val[2] : 0); 02386 } /* nfs4_list_to_bitmap4 */ 02387 02388 /* 02389 * Conversion of attributes 02390 */ 02391 02407 int 02408 nfs3_FSALattr_To_PartialFattr(const fsal_attrib_list_t * FSAL_attr, 02409 fsal_attrib_mask_t want, 02410 fattr3 * Fattr) 02411 { 02412 if(FSAL_attr == NULL || Fattr == NULL) 02413 { 02414 LogFullDebug(COMPONENT_NFSPROTO, 02415 "%s: FSAL_attr=%p, Fattr=%p", 02416 __func__, FSAL_attr, Fattr); 02417 return 0; 02418 } 02419 02420 if((FSAL_attr->asked_attributes & want) != want) 02421 { 02422 LogEvent(COMPONENT_NFSPROTO, 02423 "%s: Caller wants 0x%llx, we only have 0x%llx - missing 0x%llx", 02424 __func__, want, FSAL_attr->asked_attributes, 02425 (FSAL_attr->asked_attributes & want) ^ want); 02426 return 0; 02427 } 02428 02429 if(FSAL_attr->asked_attributes & FSAL_ATTR_TYPE) 02430 { 02431 switch (FSAL_attr->type) 02432 { 02433 case FSAL_TYPE_FIFO: 02434 Fattr->type = NF3FIFO; 02435 break; 02436 02437 case FSAL_TYPE_CHR: 02438 Fattr->type = NF3CHR; 02439 break; 02440 02441 case FSAL_TYPE_DIR: 02442 Fattr->type = NF3DIR; 02443 break; 02444 02445 case FSAL_TYPE_BLK: 02446 Fattr->type = NF3BLK; 02447 break; 02448 02449 case FSAL_TYPE_FILE: 02450 case FSAL_TYPE_XATTR: 02451 Fattr->type = NF3REG; 02452 break; 02453 02454 case FSAL_TYPE_LNK: 02455 Fattr->type = NF3LNK; 02456 break; 02457 02458 case FSAL_TYPE_SOCK: 02459 Fattr->type = NF3SOCK; 02460 break; 02461 02462 case FSAL_TYPE_JUNCTION: 02463 /* Should not occur */ 02464 LogFullDebug(COMPONENT_NFSPROTO, 02465 "nfs3_FSALattr_To_Fattr: FSAL_attr->type = %d", 02466 FSAL_attr->type); 02467 Fattr->type = 0; 02468 return 0; 02469 02470 default: 02471 LogEvent(COMPONENT_NFSPROTO, 02472 "nfs3_FSALattr_To_Fattr: Bogus type = %d", 02473 FSAL_attr->type); 02474 return 0; 02475 } 02476 } 02477 02478 if(FSAL_attr->asked_attributes & FSAL_ATTR_MODE) 02479 Fattr->mode = fsal2unix_mode(FSAL_attr->mode); 02480 if(FSAL_attr->asked_attributes & FSAL_ATTR_NUMLINKS) 02481 Fattr->nlink = FSAL_attr->numlinks; 02482 if(FSAL_attr->asked_attributes & FSAL_ATTR_OWNER) 02483 Fattr->uid = FSAL_attr->owner; 02484 if(FSAL_attr->asked_attributes & FSAL_ATTR_GROUP) 02485 Fattr->gid = FSAL_attr->group; 02486 if(FSAL_attr->asked_attributes & FSAL_ATTR_SIZE) 02487 Fattr->size = FSAL_attr->filesize; 02488 if(FSAL_attr->asked_attributes & FSAL_ATTR_SPACEUSED) 02489 Fattr->used = FSAL_attr->spaceused; 02490 if(FSAL_attr->asked_attributes & FSAL_ATTR_RAWDEV) 02491 { 02492 Fattr->rdev.specdata1 = FSAL_attr->rawdev.major; 02493 Fattr->rdev.specdata2 = FSAL_attr->rawdev.minor; 02494 } 02495 if(FSAL_attr->asked_attributes & FSAL_ATTR_FILEID) 02496 Fattr->fileid = FSAL_attr->fileid; 02497 if(FSAL_attr->asked_attributes & FSAL_ATTR_ATIME) 02498 { 02499 Fattr->atime.seconds = FSAL_attr->atime.seconds; 02500 Fattr->atime.nseconds = FSAL_attr->atime.nseconds; 02501 } 02502 if(FSAL_attr->asked_attributes & FSAL_ATTR_MTIME) 02503 { 02504 Fattr->mtime.seconds = FSAL_attr->mtime.seconds; 02505 Fattr->mtime.nseconds = FSAL_attr->mtime.nseconds; 02506 } 02507 if(FSAL_attr->asked_attributes & FSAL_ATTR_CTIME) 02508 { 02509 Fattr->ctime.seconds = FSAL_attr->ctime.seconds; 02510 Fattr->ctime.nseconds = FSAL_attr->ctime.nseconds; 02511 } 02512 02513 return 1; 02514 } /* nfs3_FSALattr_To_PartialFattr */ 02515 02531 int nfs3_FSALattr_To_Fattr(exportlist_t * pexport, /* In: the related export entry */ 02532 const fsal_attrib_list_t * FSAL_attr, /* In: file attributes */ 02533 fattr3 * Fattr) /* Out: file attributes */ 02534 { 02535 if(FSAL_attr == NULL || Fattr == NULL) 02536 { 02537 LogFullDebug(COMPONENT_NFSPROTO, 02538 "nfs3_FSALattr_To_Fattr: FSAL_attr=%p, Fattr=%p", 02539 FSAL_attr, Fattr); 02540 return 0; 02541 } 02542 02543 if(!nfs3_FSALattr_To_PartialFattr(FSAL_attr, 02544 FSAL_ATTR_TYPE| FSAL_ATTR_MODE | FSAL_ATTR_NUMLINKS | 02545 FSAL_ATTR_OWNER | FSAL_ATTR_GROUP | FSAL_ATTR_SIZE | 02546 FSAL_ATTR_SPACEUSED | FSAL_ATTR_RAWDEV | 02547 FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME, 02548 Fattr)) 02549 return 0; 02550 02551 /* in NFSv3, we only keeps fsid.major, casted into an nfs_uint64 */ 02552 Fattr->fsid = (nfs3_uint64) pexport->filesystem_id.major; 02553 LogFullDebug(COMPONENT_NFSPROTO, 02554 "%s: fsid.major = %#llX (%llu), fsid.minor = %#llX (%llu), nfs3_fsid = %#llX (%llu)", 02555 __func__, 02556 pexport->filesystem_id.major, pexport->filesystem_id.major, 02557 pexport->filesystem_id.minor, pexport->filesystem_id.minor, Fattr->fsid, 02558 Fattr->fsid); 02559 return 1; 02560 } 02561 02574 int nfs2_Sattr_To_FSALattr(fsal_attrib_list_t * pFSAL_attr, /* Out: file attributes */ 02575 sattr2 * Fattr) /* In: file attributes */ 02576 { 02577 struct timeval t; 02578 02579 FSAL_CLEAR_MASK(pFSAL_attr->asked_attributes); 02580 02581 if(Fattr->mode != (unsigned int)-1) 02582 { 02583 pFSAL_attr->mode = unix2fsal_mode(Fattr->mode); 02584 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_MODE); 02585 } 02586 02587 if(Fattr->uid != (unsigned int)-1) 02588 { 02589 pFSAL_attr->owner = Fattr->uid; 02590 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_OWNER); 02591 } 02592 02593 if(Fattr->gid != (unsigned int)-1) 02594 { 02595 pFSAL_attr->group = Fattr->gid; 02596 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_GROUP); 02597 } 02598 02599 if(Fattr->size != (unsigned int)-1) 02600 { 02601 /* Both FSAL_ATTR_SIZE and FSAL_ATTR_SPACEUSED are to be managed */ 02602 pFSAL_attr->filesize = (fsal_size_t) Fattr->size; 02603 pFSAL_attr->spaceused = (fsal_size_t) Fattr->size; 02604 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_SIZE); 02605 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_SPACEUSED); 02606 } 02607 02608 /* if mtime.useconds == 1 millions, 02609 * this means we must set atime and mtime 02610 * to server time (NFS Illustrated p. 98) 02611 */ 02612 if(Fattr->mtime.useconds == 1000000) 02613 { 02614 gettimeofday(&t, NULL); 02615 02616 pFSAL_attr->atime.seconds = pFSAL_attr->mtime.seconds = t.tv_sec; 02617 pFSAL_attr->atime.nseconds = pFSAL_attr->mtime.nseconds = 0 ; 02618 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_ATIME); 02619 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_MTIME); 02620 } 02621 else 02622 { 02623 /* set atime to client */ 02624 02625 if(Fattr->atime.seconds != (unsigned int)-1) 02626 { 02627 pFSAL_attr->atime.seconds = Fattr->atime.seconds; 02628 02629 if(Fattr->atime.seconds != (unsigned int)-1) 02630 pFSAL_attr->atime.nseconds = Fattr->atime.useconds * 1000; 02631 else 02632 pFSAL_attr->atime.nseconds = 0; /* ignored */ 02633 02634 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_ATIME); 02635 } 02636 02637 /* set mtime to client */ 02638 02639 if(Fattr->mtime.seconds != (unsigned int)-1) 02640 { 02641 pFSAL_attr->mtime.seconds = Fattr->mtime.seconds; 02642 02643 if(Fattr->mtime.seconds != (unsigned int)-1) 02644 pFSAL_attr->mtime.nseconds = Fattr->mtime.useconds * 1000; 02645 else 02646 pFSAL_attr->mtime.nseconds = 0; /* ignored */ 02647 02648 FSAL_SET_MASK(pFSAL_attr->asked_attributes, FSAL_ATTR_MTIME); 02649 } 02650 } 02651 02652 return 1; 02653 } /* nfs2_Sattr_To_FSALattr */ 02654 02668 int nfs4_Fattr_Check_Access(fattr4 * Fattr, int access) 02669 { 02670 unsigned int i = 0; 02671 02672 uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 02673 uint32_t attrmasklen = 0; 02674 02675 /* Parameter sanity check */ 02676 if(Fattr == NULL) 02677 return 0; 02678 02679 if(access != FATTR4_ATTR_READ && access != FATTR4_ATTR_WRITE) 02680 return 0; 02681 02682 /* Convert the attribute bitmap to an attribute list */ 02683 nfs4_bitmap4_to_list(&(Fattr->attrmask), &attrmasklen, attrmasklist); 02684 02685 for(i = 0; i < attrmasklen; i++) 02686 { 02687 #ifdef _USE_NFS4_1 02688 if(attrmasklist[i] > FATTR4_FS_CHARSET_CAP) 02689 #else 02690 if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID) 02691 #endif 02692 { 02693 /* Erroneous value... skip */ 02694 continue; 02695 } 02696 02697 if(((int)fattr4tab[attrmasklist[i]].access & access) != access) 02698 return 0; 02699 } 02700 02701 return 1; 02702 } /* nfs4_Fattr_Check_Access */ 02703 02717 int nfs4_Fattr_Check_Access_Bitmap(bitmap4 * pbitmap, int access) 02718 { 02719 unsigned int i = 0; 02720 #ifdef _USE_NFS4_1 02721 #define MAXATTR FATTR4_FS_CHARSET_CAP 02722 #else 02723 #define MAXATTR FATTR4_MOUNTED_ON_FILEID 02724 #endif 02725 uint32_t attrmasklist[MAXATTR]; 02726 uint32_t attrmasklen = 0; 02727 02728 /* Parameter sanity check */ 02729 if(pbitmap == NULL) 02730 return 0; 02731 02732 if(access != FATTR4_ATTR_READ && access != FATTR4_ATTR_WRITE) 02733 return 0; 02734 02735 /* Convert the attribute bitmap to an attribute list */ 02736 nfs4_bitmap4_to_list(pbitmap, &attrmasklen, attrmasklist); 02737 02738 for(i = 0; i < attrmasklen; i++) 02739 { 02740 if(attrmasklist[i] > MAXATTR) 02741 { 02742 /* Erroneous value... skip */ 02743 continue; 02744 } 02745 02746 if(((int)fattr4tab[attrmasklist[i]].access & access) != access) 02747 return 0; 02748 } 02749 02750 return 1; 02751 } /* nfs4_Fattr_Check_Access */ 02752 02764 int nfs4_bitmap4_Remove_Unsupported(bitmap4 * pbitmap ) 02765 { 02766 uint_t i = 0; 02767 uint_t val = 0; 02768 uint_t offset = 0; 02769 uint fattr4tabidx = 0; 02770 02771 uint32_t bitmap_val[3] ; 02772 bitmap4 bout ; 02773 int allsupp = 1; 02774 02775 memset(bitmap_val, 0, 3 * sizeof(uint32_t)); 02776 02777 bout.bitmap4_val = bitmap_val ; 02778 bout.bitmap4_len = pbitmap->bitmap4_len ; 02779 02780 if(pbitmap->bitmap4_len > 0) 02781 LogFullDebug(COMPONENT_NFS_V4, "Bitmap: Len = %u Val = %u|%u", 02782 pbitmap->bitmap4_len, pbitmap->bitmap4_val[0], 02783 pbitmap->bitmap4_val[1]); 02784 else 02785 LogFullDebug(COMPONENT_NFS_V4, "Bitmap: Len = %u ... ", 02786 pbitmap->bitmap4_len); 02787 02788 for(offset = 0; offset < pbitmap->bitmap4_len; offset++) 02789 { 02790 for(i = 0; i < 32; i++) 02791 { 02792 fattr4tabidx = i+32*offset; 02793 #ifdef _USE_NFS4_1 02794 if (fattr4tabidx > FATTR4_FS_CHARSET_CAP) 02795 #else 02796 if (fattr4tabidx > FATTR4_MOUNTED_ON_FILEID) 02797 #endif 02798 goto exit; 02799 02800 val = 1 << i; /* Compute 2**i */ 02801 if(pbitmap->bitmap4_val[offset] & val) 02802 { 02803 if( fattr4tab[fattr4tabidx].supported ) /* keep only supported stuff */ 02804 bout.bitmap4_val[offset] |= val ; 02805 } 02806 } 02807 } 02808 02809 exit: 02810 memcpy(pbitmap->bitmap4_val, bout.bitmap4_val, 02811 bout.bitmap4_len * sizeof(uint32_t)); 02812 02813 return allsupp; 02814 } /* nfs4_Fattr_Bitmap_Remove_Unsupported */ 02815 02816 02829 int nfs4_Fattr_Supported(fattr4 * Fattr) 02830 { 02831 unsigned int i = 0; 02832 02833 uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 02834 uint32_t attrmasklen = 0; 02835 02836 /* Parameter sanity check */ 02837 if(Fattr == NULL) 02838 return 0; 02839 02840 /* Convert the attribute bitmap to an attribute list */ 02841 nfs4_bitmap4_to_list(&(Fattr->attrmask), &attrmasklen, attrmasklist); 02842 02843 for(i = 0; i < attrmasklen; i++) 02844 { 02845 02846 #ifndef _USE_NFS4_1 02847 if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID) 02848 { 02849 /* Erroneous value... skip */ 02850 continue; 02851 } 02852 #endif 02853 02854 LogFullDebug(COMPONENT_NFS_V4, 02855 "nfs4_Fattr_Supported ==============> %s supported flag=%u | ", 02856 fattr4tab[attrmasklist[i]].name, fattr4tab[attrmasklist[i]].supported); 02857 02858 if(!fattr4tab[attrmasklist[i]].supported) 02859 return 0; 02860 } 02861 02862 return 1; 02863 } /* nfs4_Fattr_Supported */ 02864 02877 int nfs4_Fattr_Supported_Bitmap(bitmap4 * pbitmap) 02878 { 02879 unsigned int i = 0; 02880 02881 uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 02882 uint32_t attrmasklen = 0; 02883 02884 /* Parameter sanity check */ 02885 if(pbitmap == NULL) 02886 return 0; 02887 02888 /* Convert the attribute bitmap to an attribute list */ 02889 nfs4_bitmap4_to_list(pbitmap, &attrmasklen, attrmasklist); 02890 02891 for(i = 0; i < attrmasklen; i++) 02892 { 02893 02894 #ifndef _USE_NFS4_1 02895 if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID) 02896 { 02897 /* Erroneous value... skip */ 02898 continue; 02899 } 02900 #endif 02901 02902 LogFullDebug(COMPONENT_NFS_V4, 02903 "nfs4_Fattr_Supported ==============> %s supported flag=%u", 02904 fattr4tab[attrmasklist[i]].name, 02905 fattr4tab[attrmasklist[i]].supported); 02906 if(!fattr4tab[attrmasklist[i]].supported) 02907 return 0; 02908 } 02909 02910 return 1; 02911 } /* nfs4_Fattr_Supported */ 02912 02925 int nfs4_Fattr_cmp(fattr4 * Fattr1, fattr4 * Fattr2) 02926 { 02927 uint32_t attrmasklist1[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 02928 uint32_t attrmasklen1 = 0; 02929 u_int LastOffset; 02930 uint32_t attrmasklist2[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 02931 uint32_t attrmasklen2 = 0; 02932 uint32_t i; 02933 uint32_t k; 02934 unsigned int cmp = 0; 02935 u_int len = 0; 02936 uint32_t attribute_to_set = 0; 02937 02938 if(Fattr1 == NULL) 02939 return FALSE; 02940 02941 if(Fattr2 == NULL) 02942 return FALSE; 02943 02944 if(Fattr1->attrmask.bitmap4_len != Fattr2->attrmask.bitmap4_len) /* different mask */ 02945 return FALSE; 02946 02947 /* Convert the attribute bitmap to an attribute list */ 02948 nfs4_bitmap4_to_list(&(Fattr1->attrmask), &attrmasklen1, attrmasklist1); 02949 nfs4_bitmap4_to_list(&(Fattr2->attrmask), &attrmasklen2, attrmasklist2); 02950 02951 /* Should not occur, bu this is a sanity check */ 02952 if(attrmasklen1 != attrmasklen2) 02953 return FALSE; 02954 02955 for(i = 0; i < attrmasklen1; i++) 02956 { 02957 if(attrmasklist1[i] != attrmasklist2[i]) 02958 return 0; 02959 02960 if(attrmasklist1[i] == FATTR4_RDATTR_ERROR) 02961 return -1; 02962 02963 if(attrmasklist2[i] == FATTR4_RDATTR_ERROR) 02964 return -1; 02965 } 02966 02967 cmp = 0; 02968 LastOffset = 0; 02969 len = 0; 02970 02971 for(i = 0; i < attrmasklen1; i++) 02972 { 02973 attribute_to_set = attrmasklist1[i]; 02974 02975 LogFullDebug(COMPONENT_NFS_V4, 02976 "nfs4_Fattr_cmp ==============> %s", 02977 fattr4tab[attribute_to_set].name); 02978 02979 switch (attribute_to_set) 02980 { 02981 case FATTR4_SUPPORTED_ATTRS: 02982 memcpy(&len, (char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 02983 sizeof(u_int)); 02984 cmp += 02985 memcmp((char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 02986 (char *)(Fattr2->attr_vals.attrlist4_val + LastOffset), 02987 sizeof(u_int)); 02988 02989 len = htonl(len); 02990 LastOffset += sizeof(u_int); 02991 02992 for(k = 0; k < len; k++) 02993 { 02994 cmp += memcmp((char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 02995 (char *)(Fattr2->attr_vals.attrlist4_val + LastOffset), 02996 sizeof(uint32_t)); 02997 LastOffset += sizeof(uint32_t); 02998 } 02999 03000 break; 03001 03002 case FATTR4_FILEHANDLE: 03003 case FATTR4_OWNER: 03004 case FATTR4_OWNER_GROUP: 03005 memcpy(&len, (char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 03006 sizeof(u_int)); 03007 len = ntohl(len); /* xdr marshalling on fattr4 */ 03008 cmp += memcmp((char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 03009 (char *)(Fattr2->attr_vals.attrlist4_val + LastOffset), 03010 sizeof(u_int)); 03011 LastOffset += sizeof(u_int); 03012 cmp += memcmp((char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 03013 (char *)(Fattr2->attr_vals.attrlist4_val + LastOffset), len); 03014 break; 03015 03016 case FATTR4_TYPE: 03017 case FATTR4_FH_EXPIRE_TYPE: 03018 case FATTR4_CHANGE: 03019 case FATTR4_SIZE: 03020 case FATTR4_LINK_SUPPORT: 03021 case FATTR4_SYMLINK_SUPPORT: 03022 case FATTR4_NAMED_ATTR: 03023 case FATTR4_FSID: 03024 case FATTR4_UNIQUE_HANDLES: 03025 case FATTR4_LEASE_TIME: 03026 case FATTR4_RDATTR_ERROR: 03027 case FATTR4_ACL: 03028 case FATTR4_ACLSUPPORT: 03029 case FATTR4_ARCHIVE: 03030 case FATTR4_CANSETTIME: 03031 case FATTR4_CASE_INSENSITIVE: 03032 case FATTR4_CASE_PRESERVING: 03033 case FATTR4_CHOWN_RESTRICTED: 03034 case FATTR4_FILEID: 03035 case FATTR4_FILES_AVAIL: 03036 case FATTR4_FILES_FREE: 03037 case FATTR4_FILES_TOTAL: 03038 case FATTR4_FS_LOCATIONS: 03039 case FATTR4_HIDDEN: 03040 case FATTR4_HOMOGENEOUS: 03041 case FATTR4_MAXFILESIZE: 03042 case FATTR4_MAXLINK: 03043 case FATTR4_MAXNAME: 03044 case FATTR4_MAXREAD: 03045 case FATTR4_MAXWRITE: 03046 case FATTR4_MIMETYPE: 03047 case FATTR4_MODE: 03048 case FATTR4_NO_TRUNC: 03049 case FATTR4_NUMLINKS: 03050 case FATTR4_QUOTA_AVAIL_HARD: 03051 case FATTR4_QUOTA_AVAIL_SOFT: 03052 case FATTR4_QUOTA_USED: 03053 case FATTR4_RAWDEV: 03054 case FATTR4_SPACE_AVAIL: 03055 case FATTR4_SPACE_FREE: 03056 case FATTR4_SPACE_TOTAL: 03057 case FATTR4_SPACE_USED: 03058 case FATTR4_SYSTEM: 03059 case FATTR4_TIME_ACCESS: 03060 case FATTR4_TIME_ACCESS_SET: 03061 case FATTR4_TIME_BACKUP: 03062 case FATTR4_TIME_CREATE: 03063 case FATTR4_TIME_DELTA: 03064 case FATTR4_TIME_METADATA: 03065 case FATTR4_TIME_MODIFY: 03066 case FATTR4_TIME_MODIFY_SET: 03067 case FATTR4_MOUNTED_ON_FILEID: 03068 cmp += memcmp((char *)(Fattr1->attr_vals.attrlist4_val + LastOffset), 03069 (char *)(Fattr2->attr_vals.attrlist4_val + LastOffset), 03070 fattr4tab[attribute_to_set].size_fattr4); 03071 break; 03072 03073 default: 03074 return 0; 03075 break; 03076 } 03077 } 03078 if(cmp == 0) 03079 return TRUE; 03080 else 03081 return FALSE; 03082 } 03083 03084 #ifdef _USE_NFS4_ACL 03085 static int nfs4_decode_acl_special_user(utf8string *utf8str, int *who) 03086 { 03087 int i; 03088 03089 for (i = 0; i < FSAL_ACE_SPECIAL_EVERYONE; i++) 03090 { 03091 if(strncmp(utf8str->utf8string_val, whostr_2_type_map[i].string, utf8str->utf8string_len) == 0) 03092 { 03093 *who = whostr_2_type_map[i].type; 03094 return 0; 03095 } 03096 } 03097 03098 return -1; 03099 } 03100 03101 static int nfs4_decode_acl(fsal_attrib_list_t * pFSAL_attr, fattr4 * Fattr, u_int *LastOffset) 03102 { 03103 fsal_acl_status_t status; 03104 fsal_acl_data_t acldata; 03105 fsal_ace_t *pace; 03106 fsal_acl_t *pacl; 03107 int len; 03108 char buffer[MAXNAMLEN]; 03109 utf8string utf8buffer; 03110 int who; 03111 03112 /* Decode number of ACEs. */ 03113 memcpy(&(acldata.naces), (char*)(Fattr->attr_vals.attrlist4_val + *LastOffset), sizeof(u_int)); 03114 acldata.naces = ntohl(acldata.naces); 03115 LogFullDebug(COMPONENT_NFS_V4, 03116 "SATTR: Number of ACEs = %u", 03117 acldata.naces); 03118 *LastOffset += sizeof(u_int); 03119 03120 /* Allocate memory for ACEs. */ 03121 acldata.aces = (fsal_ace_t *)nfs4_ace_alloc(acldata.naces); 03122 if(acldata.aces == NULL) 03123 { 03124 LogCrit(COMPONENT_NFS_V4, 03125 "SATTR: Failed to allocate ACEs"); 03126 return NFS4ERR_SERVERFAULT; 03127 } 03128 else 03129 memset(acldata.aces, 0, acldata.naces * sizeof(fsal_ace_t)); 03130 03131 /* Decode ACEs. */ 03132 for(pace = acldata.aces; pace < acldata.aces + acldata.naces; pace++) 03133 { 03134 memcpy(&(pace->type), (char*)(Fattr->attr_vals.attrlist4_val + *LastOffset), sizeof(fsal_acetype_t)); 03135 pace->type = ntohl(pace->type); 03136 LogFullDebug(COMPONENT_NFS_V4, 03137 "SATTR: ACE type = 0x%x", 03138 pace->type); 03139 *LastOffset += sizeof(fsal_acetype_t); 03140 03141 memcpy(&(pace->flag), (char*)(Fattr->attr_vals.attrlist4_val + *LastOffset), sizeof(fsal_aceflag_t)); 03142 pace->flag = ntohl(pace->flag); 03143 LogFullDebug(COMPONENT_NFS_V4, 03144 "SATTR: ACE flag = 0x%x", 03145 pace->flag); 03146 *LastOffset += sizeof(fsal_aceflag_t); 03147 03148 memcpy(&(pace->perm), (char*)(Fattr->attr_vals.attrlist4_val + *LastOffset), sizeof(fsal_aceperm_t)); 03149 pace->perm = ntohl(pace->perm); 03150 LogFullDebug(COMPONENT_NFS_V4, 03151 "SATTR: ACE perm = 0x%x", 03152 pace->perm); 03153 *LastOffset += sizeof(fsal_aceperm_t); 03154 03155 /* Find out who type */ 03156 03157 /* Convert name to uid or gid */ 03158 memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + *LastOffset), sizeof(u_int)); 03159 len = ntohl(len); /* xdr marshalling on fattr4 */ 03160 *LastOffset += sizeof(u_int); 03161 03162 memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + *LastOffset), len); 03163 buffer[len] = '\0'; 03164 03165 /* Do not forget that xdr_opaque are aligned on 32bit long words */ 03166 while((len % 4) != 0) 03167 len += 1; 03168 03169 *LastOffset += len; 03170 03171 /* Decode users. */ 03172 LogFullDebug(COMPONENT_NFS_V4, 03173 "SATTR: owner = %s, len = %d, type = %s", 03174 buffer, len, 03175 GET_FSAL_ACE_WHO_TYPE(*pace)); 03176 03177 utf8buffer.utf8string_val = buffer; 03178 utf8buffer.utf8string_len = strlen(buffer); 03179 03180 if(nfs4_decode_acl_special_user(&utf8buffer, &who) == 0) /* Decode special user. */ 03181 { 03182 /* Clear group flag for special users */ 03183 pace->flag &= ~(FSAL_ACE_FLAG_GROUP_ID); 03184 pace->iflag |= FSAL_ACE_IFLAG_SPECIAL_ID; 03185 pace->who.uid = who; 03186 LogFullDebug(COMPONENT_NFS_V4, 03187 "SATTR: ACE special who.uid = 0x%x", 03188 pace->who.uid); 03189 } 03190 else 03191 { 03192 if(pace->flag == FSAL_ACE_FLAG_GROUP_ID) /* Decode group. */ 03193 { 03194 utf82gid(&utf8buffer, &(pace->who.gid)); 03195 LogFullDebug(COMPONENT_NFS_V4, 03196 "SATTR: ACE who.gid = 0x%x", 03197 pace->who.gid); 03198 } 03199 else /* Decode user. */ 03200 { 03201 utf82uid(&utf8buffer, &(pace->who.uid)); 03202 LogFullDebug(COMPONENT_NFS_V4, 03203 "SATTR: ACE who.uid = 0x%x", 03204 pace->who.uid); 03205 } 03206 } 03207 03208 /* Check if we can map a name string to uid or gid. If we can't, do cleanup 03209 * and bubble up NFS4ERR_BADOWNER. */ 03210 if((pace->flag == FSAL_ACE_FLAG_GROUP_ID ? pace->who.gid : pace->who.uid) == -1) 03211 { 03212 LogFullDebug(COMPONENT_NFS_V4, 03213 "SATTR: bad owner"); 03214 nfs4_ace_free(acldata.aces); 03215 return NFS4ERR_BADOWNER; 03216 } 03217 } 03218 03219 pacl = nfs4_acl_new_entry(&acldata, &status); 03220 pFSAL_attr->acl = pacl; 03221 if(pacl == NULL) 03222 { 03223 LogCrit(COMPONENT_NFS_V4, 03224 "SATTR: Failed to create a new entry for ACL"); 03225 return NFS4ERR_SERVERFAULT; 03226 } 03227 else 03228 LogFullDebug(COMPONENT_NFS_V4, 03229 "SATTR: Successfully created a new entry for ACL, status = %u", 03230 status); 03231 03232 /* Set new ACL */ 03233 LogFullDebug(COMPONENT_NFS_V4, 03234 "SATTR: new acl = %p", 03235 pacl); 03236 03237 return NFS4_OK; 03238 } 03239 #endif /* _USE_NFS4_ACL */ 03240 03254 int nfs4_attrmap_to_FSAL_attrmask(bitmap4 attrmap, fsal_attrib_mask_t* attrmask) 03255 { 03256 unsigned int offset = 0; 03257 unsigned int i = 0; 03258 char __attribute__ ((__unused__)) funcname[] = "nfs4_FattrToSattr"; 03259 03260 for(offset = 0; offset < attrmap.bitmap4_len; offset++) 03261 { 03262 for(i = 0; i < 32; i++) 03263 { 03264 if(attrmap.bitmap4_val[offset] & (1 << i)) { 03265 uint32_t val = i + 32 * offset; 03266 switch (val) 03267 { 03268 case FATTR4_TYPE: 03269 *attrmask |= FSAL_ATTR_TYPE; 03270 break; 03271 case FATTR4_FILEID: 03272 *attrmask |= FSAL_ATTR_FILEID; 03273 break; 03274 case FATTR4_FSID: 03275 *attrmask |= FSAL_ATTR_FSID; 03276 break; 03277 case FATTR4_NUMLINKS: 03278 *attrmask |= FSAL_ATTR_NUMLINKS; 03279 break; 03280 case FATTR4_SIZE: 03281 *attrmask |= FSAL_ATTR_SIZE; 03282 break; 03283 case FATTR4_MODE: 03284 *attrmask |= FSAL_ATTR_MODE; 03285 break; 03286 case FATTR4_OWNER: 03287 *attrmask |= FSAL_ATTR_OWNER; 03288 break; 03289 case FATTR4_OWNER_GROUP: 03290 *attrmask |= FSAL_ATTR_GROUP; 03291 break; 03292 case FATTR4_CHANGE: 03293 *attrmask |= FSAL_ATTR_CHGTIME; 03294 break; 03295 case FATTR4_RAWDEV: 03296 *attrmask |= FSAL_ATTR_RAWDEV; 03297 break; 03298 case FATTR4_SPACE_USED: 03299 *attrmask |= FSAL_ATTR_SPACEUSED; 03300 break; 03301 case FATTR4_TIME_ACCESS: 03302 *attrmask |= FSAL_ATTR_ATIME; 03303 break; 03304 case FATTR4_TIME_METADATA: 03305 *attrmask |= FSAL_ATTR_CTIME; 03306 break; 03307 case FATTR4_TIME_MODIFY: 03308 *attrmask |= FSAL_ATTR_MTIME; 03309 break; 03310 case FATTR4_TIME_ACCESS_SET: 03311 *attrmask |= FSAL_ATTR_ATIME; 03312 break; 03313 case FATTR4_TIME_MODIFY_SET: 03314 *attrmask |= FSAL_ATTR_MTIME; 03315 break; 03316 case FATTR4_FILEHANDLE: 03317 LogFullDebug(COMPONENT_NFS_V4, 03318 "Filehandle attribute requested on readdir!"); 03319 /* pFSAL_attr->asked_attributes |= FSAL_ATTR_FILEHANDLE; */ 03320 break; 03321 #ifdef _USE_NFS4_ACL 03322 case FATTR4_ACL: 03323 *attrmask |= FSAL_ATTR_ACL; 03324 break; 03325 #endif /* _USE_NFS4_ACL */ 03326 } 03327 } 03328 } 03329 } 03330 return NFS4_OK; 03331 } /* nfs4_Fattr_To_FSAL_attr */ 03332 03333 static int nfstime4_to_fsal_time(fsal_time_t *ts, const char *attrval) 03334 { 03335 int LastOffset = 0; 03336 uint64_t seconds; 03337 uint32_t nseconds; 03338 03339 memcpy(&seconds, attrval + LastOffset, sizeof(seconds)); 03340 LastOffset += sizeof(seconds) ; 03341 03342 memcpy(&nseconds, attrval + LastOffset, sizeof(nseconds)); 03343 LastOffset += sizeof( nseconds ) ; 03344 03345 ts->seconds = (uint32_t) nfs_ntohl64(seconds); 03346 ts->nseconds = (uint32_t) ntohl(nseconds); 03347 03348 return LastOffset; 03349 } 03350 03351 static int settime4_to_fsal_time(fsal_time_t *ts, const char *attrval) 03352 { 03353 time_how4 how; 03354 int LastOffset = 0; 03355 03356 memcpy(&how, attrval + LastOffset , sizeof(how)); 03357 LastOffset += sizeof(how); 03358 03359 if(ntohl(how) == SET_TO_SERVER_TIME4) 03360 { 03361 ts->seconds = time(NULL); /* Use current server's time */ 03362 ts->nseconds = 0; 03363 } 03364 else 03365 { 03366 LastOffset += nfstime4_to_fsal_time(ts, attrval + LastOffset); 03367 } 03368 03369 return LastOffset; 03370 } 03371 03389 int Fattr4_To_FSAL_attr(fsal_attrib_list_t * pFSAL_attr, fattr4 * Fattr, nfs_fh4 *hdl4) 03390 { 03391 u_int LastOffset = 0; 03392 unsigned int i = 0; 03393 uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ 03394 uint32_t attrmasklen = 0; 03395 uint32_t attribute_to_set = 0; 03396 int len; 03397 char buffer[MAXNAMLEN]; 03398 utf8string utf8buffer; 03399 03400 fattr4_type attr_type; 03401 fattr4_fsid attr_fsid; 03402 fattr4_fileid attr_fileid; 03403 fattr4_rdattr_error rdattr_error; 03404 fattr4_size attr_size; 03405 fattr4_change attr_change; 03406 fattr4_numlinks attr_numlinks; 03407 fattr4_rawdev attr_rawdev; 03408 fattr4_space_used attr_space_used; 03409 #ifdef _USE_NFS4_ACL 03410 int rc; 03411 #endif 03412 03413 if(pFSAL_attr == NULL || Fattr == NULL) 03414 return NFS4ERR_BADXDR; 03415 03416 /* Check attributes data */ 03417 if((Fattr->attr_vals.attrlist4_val == NULL) || 03418 (Fattr->attr_vals.attrlist4_len == 0)) 03419 return NFS4_OK; 03420 03421 /* Convert the attribute bitmap to an attribute list */ 03422 nfs4_bitmap4_to_list(&(Fattr->attrmask), &attrmasklen, attrmasklist); 03423 03424 LogFullDebug(COMPONENT_NFS_V4, 03425 " nfs4_bitmap4_to_list ====> attrmasklen = %d", attrmasklen); 03426 03427 /* Init */ 03428 pFSAL_attr->asked_attributes = 0; 03429 03430 for(i = 0; i < attrmasklen; i++) 03431 { 03432 attribute_to_set = attrmasklist[i]; 03433 03434 #ifdef _USE_NFS4_1 03435 if(attrmasklist[i] > FATTR4_FS_CHARSET_CAP) 03436 #else 03437 if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID) 03438 #endif 03439 { 03440 /* Erroneous value... skip */ 03441 continue; 03442 } 03443 LogFullDebug(COMPONENT_NFS_V4, 03444 "=================> nfs4_Fattr_To_FSAL_attr: i=%u attr=%u", i, 03445 attrmasklist[i]); 03446 LogFullDebug(COMPONENT_NFS_V4, 03447 "Flag for Operation = %d|%d is ON, name = %s reply_size = %d", 03448 attrmasklist[i], fattr4tab[attribute_to_set].val, 03449 fattr4tab[attribute_to_set].name, 03450 fattr4tab[attribute_to_set].size_fattr4); 03451 03452 switch (attribute_to_set) 03453 { 03454 case FATTR4_TYPE: 03455 memcpy((char *)&attr_type, 03456 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03457 sizeof(fattr4_type)); 03458 03459 switch (ntohl(attr_type)) 03460 { 03461 case NF4REG: 03462 pFSAL_attr->type = FSAL_TYPE_FILE; 03463 break; 03464 03465 case NF4DIR: 03466 pFSAL_attr->type = FSAL_TYPE_DIR; 03467 break; 03468 03469 case NF4BLK: 03470 pFSAL_attr->type = FSAL_TYPE_BLK; 03471 break; 03472 03473 case NF4CHR: 03474 pFSAL_attr->type = FSAL_TYPE_CHR; 03475 break; 03476 03477 case NF4LNK: 03478 pFSAL_attr->type = FSAL_TYPE_LNK; 03479 break; 03480 03481 case NF4SOCK: 03482 pFSAL_attr->type = FSAL_TYPE_SOCK; 03483 break; 03484 03485 case NF4FIFO: 03486 pFSAL_attr->type = FSAL_TYPE_FIFO; 03487 break; 03488 03489 default: 03490 /* For wanting of a better solution */ 03491 return NFS4ERR_BADXDR; 03492 } /* switch( pattr->type ) */ 03493 03494 pFSAL_attr->asked_attributes |= FSAL_ATTR_TYPE; 03495 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03496 break; 03497 03498 case FATTR4_FILEID: 03499 /* The analog to the inode number. RFC3530 says "a number uniquely identifying the file within the filesystem" 03500 * I use hpss_GetObjId to extract this information from the Name Server's handle */ 03501 memcpy((char *)&attr_fileid, 03502 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03503 sizeof(fattr4_fileid)); 03504 pFSAL_attr->fileid = nfs_ntohl64(attr_fileid); 03505 03506 pFSAL_attr->asked_attributes |= FSAL_ATTR_FILEID; 03507 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03508 03509 break; 03510 03511 case FATTR4_FSID: 03512 memcpy((char *)&attr_fsid, 03513 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03514 sizeof(fattr4_fsid)); 03515 pFSAL_attr->fsid.major = nfs_ntohl64(attr_fsid.major); 03516 pFSAL_attr->fsid.minor = nfs_ntohl64(attr_fsid.minor); 03517 03518 pFSAL_attr->asked_attributes |= FSAL_ATTR_FSID; 03519 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03520 03521 break; 03522 03523 case FATTR4_NUMLINKS: 03524 memcpy((char *)&attr_numlinks, 03525 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03526 sizeof(fattr4_numlinks)); 03527 pFSAL_attr->numlinks = ntohl(attr_numlinks); 03528 03529 pFSAL_attr->asked_attributes |= FSAL_ATTR_NUMLINKS; 03530 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03531 03532 break; 03533 03534 case FATTR4_SIZE: 03535 memcpy((char *)&attr_size, 03536 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03537 sizeof(fattr4_size)); 03538 03539 /* Do not forget the XDR marshalling for the fattr4 stuff */ 03540 pFSAL_attr->filesize = nfs_ntohl64(attr_size); 03541 03542 pFSAL_attr->asked_attributes |= FSAL_ATTR_SIZE; 03543 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03544 LogFullDebug(COMPONENT_NFS_V4, 03545 " SATTR: size seen %zu", (size_t)pFSAL_attr->filesize); 03546 break; 03547 03548 case FATTR4_MODE: 03549 memcpy((char *)&(pFSAL_attr->mode), 03550 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03551 sizeof(fattr4_mode)); 03552 03553 /* Do not forget the XDR marshalling for the fattr4 stuff */ 03554 pFSAL_attr->mode = ntohl(pFSAL_attr->mode); 03555 03556 pFSAL_attr->asked_attributes |= FSAL_ATTR_MODE; 03557 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03558 LogFullDebug(COMPONENT_NFS_V4, 03559 " SATTR: We see the mode 0%o", pFSAL_attr->mode); 03560 break; 03561 03562 case FATTR4_OWNER: 03563 memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03564 sizeof(u_int)); 03565 len = ntohl(len); /* xdr marshalling on fattr4 */ 03566 LastOffset += sizeof(u_int); 03567 03568 memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), len); 03569 buffer[len] = '\0'; 03570 03571 /* Do not forget that xdr_opaque are aligned on 32bit long words */ 03572 while((len % 4) != 0) 03573 len += 1; 03574 03575 LastOffset += len; 03576 03577 utf8buffer.utf8string_val = buffer; 03578 utf8buffer.utf8string_len = strlen(buffer); 03579 03580 utf82uid(&utf8buffer, &(pFSAL_attr->owner)); 03581 pFSAL_attr->asked_attributes |= FSAL_ATTR_OWNER; 03582 03583 LogFullDebug(COMPONENT_NFS_V4, 03584 " SATTR: We see the owner %s len = %d", buffer, len); 03585 LogFullDebug(COMPONENT_NFS_V4, 03586 " SATTR: We see the owner %d", pFSAL_attr->owner); 03587 break; 03588 03589 case FATTR4_OWNER_GROUP: 03590 memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03591 sizeof(u_int)); 03592 len = ntohl(len); 03593 LastOffset += sizeof(u_int); 03594 03595 memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), len); 03596 buffer[len] = '\0'; 03597 03598 /* Do not forget that xdr_opaque are aligned on 32bit long words */ 03599 while((len % 4) != 0) 03600 len += 1; 03601 03602 LastOffset += len; 03603 03604 utf8buffer.utf8string_val = buffer; 03605 utf8buffer.utf8string_len = strlen(buffer); 03606 03607 utf82gid(&utf8buffer, &(pFSAL_attr->group)); 03608 pFSAL_attr->asked_attributes |= FSAL_ATTR_GROUP; 03609 03610 LogFullDebug(COMPONENT_NFS_V4, 03611 " SATTR: We see the owner_group %s len = %d", buffer, len); 03612 LogFullDebug(COMPONENT_NFS_V4, 03613 " SATTR: We see the owner_group %d", pFSAL_attr->group); 03614 break; 03615 03616 case FATTR4_CHANGE: 03617 memcpy((char *)&attr_change, 03618 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03619 sizeof(fattr4_change)); 03620 pFSAL_attr->chgtime.seconds = (uint32_t) nfs_ntohl64(attr_change); 03621 pFSAL_attr->chgtime.nseconds = 0; 03622 03623 pFSAL_attr->change = nfs_ntohl64(attr_change); 03624 03625 pFSAL_attr->asked_attributes |= FSAL_ATTR_CHGTIME; 03626 pFSAL_attr->asked_attributes |= FSAL_ATTR_CHANGE; 03627 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03628 03629 break; 03630 03631 case FATTR4_RAWDEV: 03632 memcpy((char *)&attr_rawdev, 03633 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03634 sizeof(fattr4_rawdev)); 03635 pFSAL_attr->rawdev.major = (uint32_t) nfs_ntohl64(attr_rawdev.specdata1); 03636 pFSAL_attr->rawdev.minor = (uint32_t) nfs_ntohl64(attr_rawdev.specdata2); 03637 03638 pFSAL_attr->asked_attributes |= FSAL_ATTR_RAWDEV; 03639 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03640 03641 break; 03642 03643 case FATTR4_SPACE_USED: 03644 memcpy((char *)&attr_space_used, 03645 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03646 sizeof(fattr4_space_used)); 03647 pFSAL_attr->spaceused = (uint32_t) nfs_ntohl64(attr_space_used); 03648 03649 pFSAL_attr->asked_attributes |= FSAL_ATTR_SPACEUSED; 03650 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03651 03652 break; 03653 03654 case FATTR4_TIME_ACCESS: /* Used only by FSAL_PROXY to reverse convert */ 03655 LastOffset += nfstime4_to_fsal_time(&pFSAL_attr->atime, 03656 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset)); 03657 pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME; 03658 break; 03659 03660 case FATTR4_TIME_METADATA: /* Used only by FSAL_PROXY to reverse convert */ 03661 LastOffset += nfstime4_to_fsal_time(&pFSAL_attr->ctime, 03662 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset)); 03663 pFSAL_attr->asked_attributes |= FSAL_ATTR_CTIME; 03664 break; 03665 03666 case FATTR4_TIME_MODIFY: /* Used only by FSAL_PROXY to reverse convert */ 03667 LastOffset += nfstime4_to_fsal_time(&pFSAL_attr->mtime, 03668 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset)); 03669 pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME; 03670 break; 03671 03672 case FATTR4_TIME_ACCESS_SET: 03673 LastOffset += settime4_to_fsal_time(&pFSAL_attr->atime, 03674 Fattr->attr_vals.attrlist4_val + LastOffset); 03675 pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME; 03676 break; 03677 03678 case FATTR4_TIME_MODIFY_SET: 03679 LastOffset += settime4_to_fsal_time(&pFSAL_attr->mtime, 03680 Fattr->attr_vals.attrlist4_val + LastOffset); 03681 pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME; 03682 03683 break; 03684 03685 case FATTR4_FILEHANDLE: 03686 memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03687 sizeof(u_int)); 03688 len = ntohl(len); 03689 LastOffset += sizeof(u_int); 03690 if(hdl4) 03691 { 03692 hdl4->nfs_fh4_len = len; 03693 hdl4->nfs_fh4_val = Fattr->attr_vals.attrlist4_val + LastOffset; 03694 } 03695 LastOffset += len; 03696 LogFullDebug(COMPONENT_NFS_V4, 03697 " SATTR: On a demande le filehandle len =%u", len); 03698 break; 03699 03700 case FATTR4_RDATTR_ERROR: 03701 memcpy((char *)&rdattr_error, 03702 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), 03703 sizeof(fattr4_rdattr_error)); 03704 rdattr_error = ntohl(rdattr_error); 03705 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03706 03707 break; 03708 03709 #ifdef _USE_NFS4_ACL 03710 case FATTR4_ACL: 03711 if((rc = nfs4_decode_acl(pFSAL_attr, Fattr, &LastOffset)) != NFS4_OK) 03712 return rc; 03713 03714 pFSAL_attr->asked_attributes |= FSAL_ATTR_ACL; 03715 break; 03716 #endif /* _USE_NFS4_ACL */ 03717 03718 default: 03719 LogFullDebug(COMPONENT_NFS_V4, 03720 " SATTR: Attribut no supporte %d name=%s", 03721 attribute_to_set, fattr4tab[attribute_to_set].name); 03722 LastOffset += fattr4tab[attribute_to_set].size_fattr4; 03723 /* return NFS4ERR_ATTRNOTSUPP ; *//* Should not stop processing */ 03724 break; 03725 } /* switch */ 03726 } /* for */ 03727 03728 return NFS4_OK; 03729 } /* Fattr4_To_FSAL_attr */ 03730 03743 int nfs4_Fattr_To_FSAL_attr(fsal_attrib_list_t * pFSAL_attr, fattr4 * Fattr) 03744 { 03745 return Fattr4_To_FSAL_attr(pFSAL_attr, Fattr, NULL); 03746 } 03747 03748 /* Error conversion routines */ 03760 nfsstat4 nfs4_Errno(cache_inode_status_t error) 03761 { 03762 nfsstat4 nfserror= NFS4ERR_INVAL; 03763 03764 switch (error) 03765 { 03766 case CACHE_INODE_SUCCESS: 03767 nfserror = NFS4_OK; 03768 break; 03769 03770 case CACHE_INODE_MALLOC_ERROR: 03771 case CACHE_INODE_POOL_MUTEX_INIT_ERROR: 03772 case CACHE_INODE_GET_NEW_LRU_ENTRY: 03773 case CACHE_INODE_INIT_ENTRY_FAILED: 03774 case CACHE_INODE_CACHE_CONTENT_EXISTS: 03775 case CACHE_INODE_CACHE_CONTENT_EMPTY: 03776 nfserror = NFS4ERR_SERVERFAULT; 03777 break; 03778 03779 case CACHE_INODE_UNAPPROPRIATED_KEY: 03780 nfserror = NFS4ERR_BADHANDLE; 03781 break; 03782 03783 case CACHE_INODE_BAD_TYPE: 03784 case CACHE_INODE_INVALID_ARGUMENT: 03785 nfserror = NFS4ERR_INVAL; 03786 break; 03787 03788 case CACHE_INODE_NOT_A_DIRECTORY: 03789 nfserror = NFS4ERR_NOTDIR; 03790 break; 03791 03792 case CACHE_INODE_ENTRY_EXISTS: 03793 nfserror = NFS4ERR_EXIST; 03794 break; 03795 03796 case CACHE_INODE_DIR_NOT_EMPTY: 03797 nfserror = NFS4ERR_NOTEMPTY; 03798 break; 03799 03800 case CACHE_INODE_NOT_FOUND: 03801 nfserror = NFS4ERR_NOENT; 03802 break; 03803 03804 case CACHE_INODE_FSAL_ERROR: 03805 case CACHE_INODE_INSERT_ERROR: 03806 case CACHE_INODE_LRU_ERROR: 03807 case CACHE_INODE_HASH_SET_ERROR: 03808 nfserror = NFS4ERR_IO; 03809 break; 03810 03811 case CACHE_INODE_FSAL_EACCESS: 03812 nfserror = NFS4ERR_ACCESS; 03813 break; 03814 03815 case CACHE_INODE_FSAL_EPERM: 03816 case CACHE_INODE_FSAL_ERR_SEC: 03817 nfserror = NFS4ERR_PERM; 03818 break; 03819 03820 case CACHE_INODE_NO_SPACE_LEFT: 03821 nfserror = NFS4ERR_NOSPC; 03822 break; 03823 03824 case CACHE_INODE_IS_A_DIRECTORY: 03825 nfserror = NFS4ERR_ISDIR; 03826 break; 03827 03828 case CACHE_INODE_READ_ONLY_FS: 03829 nfserror = NFS4ERR_ROFS; 03830 break; 03831 03832 case CACHE_INODE_IO_ERROR: 03833 nfserror = NFS4ERR_IO; 03834 break; 03835 03836 case CACHE_INODE_NAME_TOO_LONG: 03837 nfserror = NFS4ERR_NAMETOOLONG; 03838 break; 03839 03840 case CACHE_INODE_KILLED: 03841 case CACHE_INODE_DEAD_ENTRY: 03842 case CACHE_INODE_FSAL_ESTALE: 03843 nfserror = NFS4ERR_STALE; 03844 break; 03845 03846 case CACHE_INODE_STATE_CONFLICT: 03847 nfserror = NFS4ERR_PERM; 03848 break; 03849 03850 case CACHE_INODE_QUOTA_EXCEEDED: 03851 nfserror = NFS4ERR_DQUOT; 03852 break; 03853 03854 case CACHE_INODE_NOT_SUPPORTED: 03855 nfserror = NFS4ERR_NOTSUPP; 03856 break; 03857 03858 case CACHE_INODE_DELAY: 03859 nfserror = NFS4ERR_DELAY; 03860 break; 03861 03862 case CACHE_INODE_FILE_BIG: 03863 nfserror = NFS4ERR_FBIG; 03864 break; 03865 03866 case CACHE_INODE_FILE_OPEN: 03867 nfserror = NFS4ERR_FILE_OPEN; 03868 break; 03869 03870 case CACHE_INODE_STATE_ERROR: 03871 nfserror = NFS4ERR_BAD_STATEID; 03872 break; 03873 03874 case CACHE_INODE_BAD_COOKIE: 03875 nfserror = NFS4ERR_BAD_COOKIE; 03876 break; 03877 03878 case CACHE_INODE_INCONSISTENT_ENTRY: 03879 case CACHE_INODE_HASH_TABLE_ERROR: 03880 case CACHE_INODE_CACHE_CONTENT_ERROR: 03881 case CACHE_INODE_ASYNC_POST_ERROR: 03882 /* Should not occur */ 03883 nfserror = NFS4ERR_INVAL; 03884 break; 03885 } 03886 03887 return nfserror; 03888 } /* nfs4_Errno */ 03889 03901 nfsstat3 nfs3_Errno(cache_inode_status_t error) 03902 { 03903 nfsstat3 nfserror= NFS3ERR_INVAL; 03904 03905 switch (error) 03906 { 03907 case CACHE_INODE_SUCCESS: 03908 nfserror = NFS3_OK; 03909 break; 03910 03911 case CACHE_INODE_MALLOC_ERROR: 03912 case CACHE_INODE_POOL_MUTEX_INIT_ERROR: 03913 case CACHE_INODE_GET_NEW_LRU_ENTRY: 03914 case CACHE_INODE_UNAPPROPRIATED_KEY: 03915 case CACHE_INODE_INIT_ENTRY_FAILED: 03916 case CACHE_INODE_CACHE_CONTENT_EXISTS: 03917 case CACHE_INODE_CACHE_CONTENT_EMPTY: 03918 case CACHE_INODE_INSERT_ERROR: 03919 case CACHE_INODE_LRU_ERROR: 03920 case CACHE_INODE_HASH_SET_ERROR: 03921 case CACHE_INODE_FILE_OPEN: 03922 LogCrit(COMPONENT_NFSPROTO, 03923 "Error %u converted to NFS3ERR_IO but was set non-retryable", 03924 error); 03925 nfserror = NFS3ERR_IO; 03926 break; 03927 03928 case CACHE_INODE_INVALID_ARGUMENT: 03929 nfserror = NFS3ERR_INVAL; 03930 break; 03931 03932 case CACHE_INODE_FSAL_ERROR: 03933 case CACHE_INODE_CACHE_CONTENT_ERROR: 03935 LogCrit(COMPONENT_NFSPROTO, 03936 "Error CACHE_INODE_FSAL_ERROR converted to NFS3ERR_IO but was set non-retryable"); 03937 nfserror = NFS3ERR_IO; 03938 break; 03939 03940 case CACHE_INODE_NOT_A_DIRECTORY: 03941 nfserror = NFS3ERR_NOTDIR; 03942 break; 03943 03944 case CACHE_INODE_ENTRY_EXISTS: 03945 nfserror = NFS3ERR_EXIST; 03946 break; 03947 03948 case CACHE_INODE_DIR_NOT_EMPTY: 03949 nfserror = NFS3ERR_NOTEMPTY; 03950 break; 03951 03952 case CACHE_INODE_NOT_FOUND: 03953 nfserror = NFS3ERR_NOENT; 03954 break; 03955 03956 case CACHE_INODE_FSAL_EACCESS: 03957 nfserror = NFS3ERR_ACCES; 03958 break; 03959 03960 case CACHE_INODE_FSAL_EPERM: 03961 case CACHE_INODE_FSAL_ERR_SEC: 03962 nfserror = NFS3ERR_PERM; 03963 break; 03964 03965 case CACHE_INODE_NO_SPACE_LEFT: 03966 nfserror = NFS3ERR_NOSPC; 03967 break; 03968 03969 case CACHE_INODE_IS_A_DIRECTORY: 03970 nfserror = NFS3ERR_ISDIR; 03971 break; 03972 03973 case CACHE_INODE_READ_ONLY_FS: 03974 nfserror = NFS3ERR_ROFS; 03975 break; 03976 03977 case CACHE_INODE_KILLED: 03978 case CACHE_INODE_DEAD_ENTRY: 03979 case CACHE_INODE_FSAL_ESTALE: 03980 nfserror = NFS3ERR_STALE; 03981 break; 03982 03983 case CACHE_INODE_QUOTA_EXCEEDED: 03984 nfserror = NFS3ERR_DQUOT; 03985 break; 03986 03987 case CACHE_INODE_BAD_TYPE: 03988 nfserror = NFS3ERR_BADTYPE; 03989 break; 03990 03991 case CACHE_INODE_NOT_SUPPORTED: 03992 nfserror = NFS3ERR_NOTSUPP; 03993 break; 03994 03995 case CACHE_INODE_DELAY: 03996 nfserror = NFS3ERR_JUKEBOX; 03997 break; 03998 03999 case CACHE_INODE_IO_ERROR: 04000 LogCrit(COMPONENT_NFSPROTO, 04001 "Error CACHE_INODE_IO_ERROR converted to NFS3ERR_IO but was set non-retryable"); 04002 nfserror = NFS3ERR_IO; 04003 break; 04004 04005 case CACHE_INODE_NAME_TOO_LONG: 04006 nfserror = NFS3ERR_NAMETOOLONG; 04007 break; 04008 04009 case CACHE_INODE_FILE_BIG: 04010 nfserror = NFS3ERR_FBIG; 04011 break; 04012 04013 case CACHE_INODE_BAD_COOKIE: 04014 nfserror = NFS3ERR_BAD_COOKIE; 04015 break; 04016 04017 case CACHE_INODE_INCONSISTENT_ENTRY: 04018 case CACHE_INODE_HASH_TABLE_ERROR: 04019 case CACHE_INODE_STATE_CONFLICT: 04020 case CACHE_INODE_ASYNC_POST_ERROR: 04021 case CACHE_INODE_STATE_ERROR: 04022 /* Should not occur */ 04023 LogDebug(COMPONENT_NFSPROTO, 04024 "Line %u should never be reached in nfs3_Errno for cache_status=%u", 04025 __LINE__, error); 04026 nfserror = NFS3ERR_INVAL; 04027 break; 04028 } 04029 04030 return nfserror; 04031 } /* nfs3_Errno */ 04032 04044 nfsstat2 nfs2_Errno(cache_inode_status_t error) 04045 { 04046 nfsstat2 nfserror= NFSERR_IO; 04047 04048 switch (error) 04049 { 04050 case CACHE_INODE_SUCCESS: 04051 nfserror = NFS_OK; 04052 break; 04053 04054 case CACHE_INODE_MALLOC_ERROR: 04055 case CACHE_INODE_POOL_MUTEX_INIT_ERROR: 04056 case CACHE_INODE_GET_NEW_LRU_ENTRY: 04057 case CACHE_INODE_UNAPPROPRIATED_KEY: 04058 case CACHE_INODE_INIT_ENTRY_FAILED: 04059 case CACHE_INODE_BAD_TYPE: 04060 case CACHE_INODE_CACHE_CONTENT_EXISTS: 04061 case CACHE_INODE_CACHE_CONTENT_EMPTY: 04062 case CACHE_INODE_INSERT_ERROR: 04063 case CACHE_INODE_LRU_ERROR: 04064 case CACHE_INODE_HASH_SET_ERROR: 04065 case CACHE_INODE_INVALID_ARGUMENT: 04066 case CACHE_INODE_FILE_OPEN: 04067 LogCrit(COMPONENT_NFSPROTO, 04068 "Error %u converted to NFSERR_IO but was set non-retryable", 04069 error); 04070 nfserror = NFSERR_IO; 04071 break; 04072 04073 case CACHE_INODE_NOT_A_DIRECTORY: 04074 nfserror = NFSERR_NOTDIR; 04075 break; 04076 04077 case CACHE_INODE_ENTRY_EXISTS: 04078 nfserror = NFSERR_EXIST; 04079 break; 04080 04081 case CACHE_INODE_FSAL_ERROR: 04082 case CACHE_INODE_CACHE_CONTENT_ERROR: 04083 LogCrit(COMPONENT_NFSPROTO, 04084 "Error CACHE_INODE_FSAL_ERROR converted to NFSERR_IO but was set non-retryable"); 04085 nfserror = NFSERR_IO; 04086 break; 04087 04088 case CACHE_INODE_DIR_NOT_EMPTY: 04089 nfserror = NFSERR_NOTEMPTY; 04090 break; 04091 04092 case CACHE_INODE_NOT_FOUND: 04093 nfserror = NFSERR_NOENT; 04094 break; 04095 04096 case CACHE_INODE_FSAL_EACCESS: 04097 nfserror = NFSERR_ACCES; 04098 break; 04099 04100 case CACHE_INODE_NO_SPACE_LEFT: 04101 nfserror = NFSERR_NOSPC; 04102 break; 04103 04104 case CACHE_INODE_FSAL_EPERM: 04105 case CACHE_INODE_FSAL_ERR_SEC: 04106 nfserror = NFSERR_PERM; 04107 break; 04108 04109 case CACHE_INODE_IS_A_DIRECTORY: 04110 nfserror = NFSERR_ISDIR; 04111 break; 04112 04113 case CACHE_INODE_READ_ONLY_FS: 04114 nfserror = NFSERR_ROFS; 04115 break; 04116 04117 case CACHE_INODE_KILLED: 04118 case CACHE_INODE_DEAD_ENTRY: 04119 case CACHE_INODE_FSAL_ESTALE: 04120 nfserror = NFSERR_STALE; 04121 break; 04122 04123 case CACHE_INODE_QUOTA_EXCEEDED: 04124 nfserror = NFSERR_DQUOT; 04125 break; 04126 04127 case CACHE_INODE_IO_ERROR: 04128 LogCrit(COMPONENT_NFSPROTO, 04129 "Error CACHE_INODE_IO_ERROR converted to NFSERR_IO but was set non-retryable"); 04130 nfserror = NFSERR_IO; 04131 break; 04132 04133 case CACHE_INODE_NAME_TOO_LONG: 04134 nfserror = NFSERR_NAMETOOLONG; 04135 break; 04136 04137 case CACHE_INODE_INCONSISTENT_ENTRY: 04138 case CACHE_INODE_HASH_TABLE_ERROR: 04139 case CACHE_INODE_STATE_CONFLICT: 04140 case CACHE_INODE_ASYNC_POST_ERROR: 04141 case CACHE_INODE_STATE_ERROR: 04142 case CACHE_INODE_NOT_SUPPORTED: 04143 case CACHE_INODE_DELAY: 04144 case CACHE_INODE_BAD_COOKIE: 04145 case CACHE_INODE_FILE_BIG: 04146 /* Should not occur */ 04147 LogDebug(COMPONENT_NFSPROTO, 04148 "Line %u should never be reached in nfs2_Errno", __LINE__); 04149 nfserror = NFSERR_IO; 04150 break; 04151 } 04152 04153 return nfserror; 04154 } /* nfs2_Errno */ 04155 04167 int nfs3_AllocateFH(nfs_fh3 *fh) 04168 { 04169 char __attribute__ ((__unused__)) funcname[] = "AllocateFH3"; 04170 04171 if(fh == NULL) 04172 return NFS3ERR_SERVERFAULT; 04173 04174 /* Allocating the filehandle in memory */ 04175 fh->data.data_len = sizeof(struct alloc_file_handle_v3); 04176 if((fh->data.data_val = gsh_malloc(fh->data.data_len)) == NULL) 04177 { 04178 LogError(COMPONENT_NFSPROTO, ERR_SYS, ERR_MALLOC, errno); 04179 return NFS3ERR_SERVERFAULT; 04180 } 04181 04182 memset((char *)fh->data.data_val, 0, fh->data.data_len); 04183 04184 return NFS3_OK; 04185 } /* nfs4_AllocateFH */ 04186 04198 int nfs4_AllocateFH(nfs_fh4 * fh) 04199 { 04200 char __attribute__ ((__unused__)) funcname[] = "AllocateFH4"; 04201 04202 if(fh == NULL) 04203 return NFS4ERR_SERVERFAULT; 04204 04205 /* Allocating the filehandle in memory */ 04206 fh->nfs_fh4_len = sizeof(struct alloc_file_handle_v4); 04207 if((fh->nfs_fh4_val = gsh_malloc(fh->nfs_fh4_len)) == NULL) 04208 { 04209 LogError(COMPONENT_NFS_V4, ERR_SYS, ERR_MALLOC, errno); 04210 return NFS4ERR_RESOURCE; 04211 } 04212 04213 memset((char *)fh->nfs_fh4_val, 0, fh->nfs_fh4_len); 04214 04215 return NFS4_OK; 04216 } /* nfs4_AllocateFH */ 04217 04229 int nfs4_MakeCred(compound_data_t * data) 04230 { 04231 exportlist_client_entry_t related_client; 04232 struct user_cred user_credentials; 04233 04234 if (get_req_uid_gid(data->reqp, 04235 data->pexport, 04236 &user_credentials) == FALSE) 04237 return NFS4ERR_WRONGSEC; 04238 04239 LogFullDebug(COMPONENT_DISPATCH, 04240 "nfs4_MakeCred about to call nfs_export_check_access"); 04241 if(nfs_export_check_access(&data->pworker->hostaddr, 04242 data->reqp, 04243 data->pexport, 04244 nfs_param.core_param.program[P_NFS], 04245 nfs_param.core_param.program[P_MNT], 04246 data->pworker->ht_ip_stats, 04247 ip_stats_pool, 04248 &related_client, 04249 &user_credentials, 04250 FALSE) /* So check_access() doesn't deny based on whether this is a RO export. */ 04251 == FALSE) 04252 return NFS4ERR_WRONGSEC; 04253 04254 if(nfs_check_anon(&related_client, data->pexport, &user_credentials) == FALSE 04255 || nfs_build_fsal_context(data->reqp, 04256 data->pexport, 04257 data->pcontext, 04258 &user_credentials) == FALSE) 04259 return NFS4ERR_WRONGSEC; 04260 04261 return NFS4_OK; 04262 } /* nfs4_MakeCred */ 04263 04264 /* Create access mask based on given access operation. Both mode and ace4 04265 * mask are encoded. */ 04266 fsal_accessflags_t nfs_get_access_mask(uint32_t op, fsal_attrib_list_t *pattr) 04267 { 04268 fsal_accessflags_t access_mask = 0; 04269 04270 switch(op) 04271 { 04272 case ACCESS3_READ: 04273 access_mask |= FSAL_MODE_MASK_SET(FSAL_R_OK); 04274 if(IS_FSAL_DIR(pattr->type)) 04275 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_LIST_DIR); 04276 else 04277 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_READ_DATA); 04278 break; 04279 04280 case ACCESS3_LOOKUP: 04281 if(!IS_FSAL_DIR(pattr->type)) 04282 break; 04283 access_mask |= FSAL_MODE_MASK_SET(FSAL_X_OK); 04284 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_LIST_DIR); 04285 break; 04286 04287 case ACCESS3_MODIFY: 04288 access_mask |= FSAL_MODE_MASK_SET(FSAL_W_OK); 04289 if(IS_FSAL_DIR(pattr->type)) 04290 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_DELETE_CHILD); 04291 else 04292 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_WRITE_DATA); 04293 break; 04294 04295 case ACCESS3_EXTEND: 04296 access_mask |= FSAL_MODE_MASK_SET(FSAL_W_OK); 04297 if(IS_FSAL_DIR(pattr->type)) 04298 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE | 04299 FSAL_ACE_PERM_ADD_SUBDIRECTORY); 04300 else 04301 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_APPEND_DATA); 04302 break; 04303 04304 case ACCESS3_DELETE: 04305 if(!IS_FSAL_DIR(pattr->type)) 04306 break; 04307 access_mask |= FSAL_MODE_MASK_SET(FSAL_W_OK); 04308 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_DELETE_CHILD); 04309 break; 04310 04311 case ACCESS3_EXECUTE: 04312 if(IS_FSAL_DIR(pattr->type)) 04313 break; 04314 access_mask |= FSAL_MODE_MASK_SET(FSAL_X_OK); 04315 access_mask |= FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_EXECUTE); 04316 break; 04317 } 04318 04319 return access_mask; 04320 } 04321 04322 void nfs3_access_debug(char *label, uint32_t access) 04323 { 04324 LogDebug(COMPONENT_NFSPROTO, "%s=%s,%s,%s,%s,%s,%s", 04325 label, 04326 FSAL_TEST_MASK(access, ACCESS3_READ) ? "READ" : "-", 04327 FSAL_TEST_MASK(access, ACCESS3_LOOKUP) ? "LOOKUP" : "-", 04328 FSAL_TEST_MASK(access, ACCESS3_MODIFY) ? "MODIFY" : "-", 04329 FSAL_TEST_MASK(access, ACCESS3_EXTEND) ? "EXTEND" : "-", 04330 FSAL_TEST_MASK(access, ACCESS3_DELETE) ? "DELETE" : "-", 04331 FSAL_TEST_MASK(access, ACCESS3_EXECUTE) ? "EXECUTE" : "-"); 04332 } 04333 04334 void nfs4_access_debug(char *label, uint32_t access, fsal_aceperm_t v4mask) 04335 { 04336 LogDebug(COMPONENT_NFSPROTO, "%s=%s,%s,%s,%s,%s,%s", 04337 label, 04338 FSAL_TEST_MASK(access, ACCESS3_READ) ? "READ" : "-", 04339 FSAL_TEST_MASK(access, ACCESS3_LOOKUP) ? "LOOKUP" : "-", 04340 FSAL_TEST_MASK(access, ACCESS3_MODIFY) ? "MODIFY" : "-", 04341 FSAL_TEST_MASK(access, ACCESS3_EXTEND) ? "EXTEND" : "-", 04342 FSAL_TEST_MASK(access, ACCESS3_DELETE) ? "DELETE" : "-", 04343 FSAL_TEST_MASK(access, ACCESS3_EXECUTE) ? "EXECUTE" : "-"); 04344 04345 if(v4mask) 04346 LogDebug(COMPONENT_NFSPROTO, "v4mask=%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 04347 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_READ_DATA) ? 'r':'-', 04348 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_WRITE_DATA) ? 'w':'-', 04349 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_EXECUTE) ? 'x':'-', 04350 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_ADD_SUBDIRECTORY) ? 'm':'-', 04351 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_READ_NAMED_ATTR) ? 'n':'-', 04352 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_WRITE_NAMED_ATTR) ? 'N':'-', 04353 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_DELETE_CHILD) ? 'p':'-', 04354 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_READ_ATTR) ? 't':'-', 04355 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_WRITE_ATTR) ? 'T':'-', 04356 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_DELETE) ? 'd':'-', 04357 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_READ_ACL) ? 'c':'-', 04358 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_WRITE_ACL) ? 'C':'-', 04359 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_WRITE_OWNER) ? 'o':'-', 04360 FSAL_TEST_MASK(v4mask, FSAL_ACE_PERM_SYNCHRONIZE) ? 'z':'-'); 04361 } 04362 04377 nfsstat4 nfs4_sanity_check_FH(compound_data_t *data, 04378 cache_inode_file_type_t required_type) 04379 { 04380 /* If there is no FH */ 04381 if(nfs4_Is_Fh_Empty(&(data->currentFH))) 04382 { 04383 LogDebug(COMPONENT_FILEHANDLE, 04384 "nfs4_Is_Fh_Empty failed"); 04385 return NFS4ERR_NOFILEHANDLE; 04386 } 04387 04388 /* If the filehandle is invalid */ 04389 if(nfs4_Is_Fh_Invalid(&(data->currentFH))) 04390 { 04391 LogDebug(COMPONENT_FILEHANDLE, 04392 "nfs4_Is_Fh_Invalid failed"); 04393 return NFS4ERR_BADHANDLE; 04394 } 04395 04396 /* Tests if the Filehandle is expired (for volatile filehandle) */ 04397 if(nfs4_Is_Fh_Expired(&(data->currentFH))) 04398 { 04399 LogDebug(COMPONENT_FILEHANDLE, 04400 "nfs4_Is_Fh_Expired failed"); 04401 return NFS4ERR_FHEXPIRED; 04402 } 04403 04404 /* Check for the correct file type */ 04405 if (required_type) 04406 { 04407 if(data->current_filetype != required_type) 04408 { 04409 LogDebug(COMPONENT_NFSPROTO, 04410 "Wrong file type"); 04411 04412 if(required_type == DIRECTORY) 04413 return NFS4ERR_NOTDIR; 04414 if(required_type == SYMBOLIC_LINK) 04415 return NFS4ERR_INVAL; 04416 04417 switch (data->current_filetype) 04418 { 04419 case DIRECTORY: 04420 return NFS4ERR_ISDIR; 04421 default: 04422 return NFS4ERR_INVAL; 04423 } 04424 } 04425 } 04426 04427 return NFS4_OK; 04428 } 04429