int nfs4_op_putrootfh(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp) { char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putrootfh"; /* This NFS4 Operation has no argument, it just get then ROOTFH (replace MOUNTPROC3_MNT) */ /* First of all, set the reply to zero to make sure it contains no parasite information */ memset(resp, 0, sizeof(struct nfs_resop4)); resp->resop = NFS4_OP_PUTROOTFH; res_PUTROOTFH4.status = CreateROOTFH4(&(data->rootFH), data); if(res_PUTROOTFH4.status != NFS4_OK) return res_PUTROOTFH4.status; if (data->current_entry) { cache_inode_put(data->current_entry); } /* Fill in compound data */ set_compound_data_for_pseudo(data); /* I copy the root FH to the currentFH */ if(data->currentFH.nfs_fh4_len == 0) { res_PUTROOTFH4.status = nfs4_AllocateFH(&(data->currentFH)); if(res_PUTROOTFH4.status != NFS4_OK) return res_PUTROOTFH4.status; } /* Copy the data from root FH to current FH */ memcpy(data->currentFH.nfs_fh4_val, data->rootFH.nfs_fh4_val, data->rootFH.nfs_fh4_len); data->currentFH.nfs_fh4_len = data->rootFH.nfs_fh4_len; LogHandleNFS4("NFS4 PUTROOTFH ROOT FH: ", &data->rootFH); LogHandleNFS4("NFS4 PUTROOTFH CURRENT FH: ", &data->currentFH); LogFullDebug(COMPONENT_NFS_V4, "NFS4 PUTROOTFH: Ending on status %d", res_PUTROOTFH4.status); return res_PUTROOTFH4.status; } /* nfs4_op_putrootfh */
int CreatePUBFH4(nfs_fh4 * fh, compound_data_t * data) { pseudofs_entry_t psfsentry; int status = 0; psfsentry = *(data->pseudofs->reverse_tab[0]); if((status = nfs4_AllocateFH(&(data->publicFH))) != NFS4_OK) return status; if(!nfs4_PseudoToFhandle(&(data->publicFH), &psfsentry)) return NFS4ERR_BADHANDLE; LogHandleNFS4("CREATE PUB FH: ", &data->publicFH); return NFS4_OK; } /* CreatePUBFH4 */
static int CreateROOTFH4(nfs_fh4 * fh, compound_data_t * data) { pseudofs_entry_t psfsentry; int status = 0; psfsentry = *(data->pseudofs->reverse_tab[0]); /* If rootFH already set, return success */ if(data->rootFH.nfs_fh4_len != 0) return NFS4_OK; if((status = nfs4_AllocateFH(&(data->rootFH))) != NFS4_OK) return status; if(!nfs4_PseudoToFhandle(&(data->rootFH), &psfsentry)) return NFS4ERR_BADHANDLE; LogHandleNFS4("CREATE ROOT FH: ", &data->rootFH); return NFS4_OK; } /* CreateROOTFH4 */
int nfs4_op_lookup(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp) { fsal_name_t name; char strname[MAXNAMLEN]; #ifndef _NO_XATTRD char objname[MAXNAMLEN]; #endif unsigned int xattr_found = FALSE; cache_entry_t *dir_pentry = NULL; cache_entry_t *file_pentry = NULL; fsal_attrib_list_t attrlookup; cache_inode_status_t cache_status; fsal_handle_t *pfsal_handle = NULL; char __attribute__ ((__unused__)) funcname[] = "nfs4_op_lookup"; resp->resop = NFS4_OP_LOOKUP; res_LOOKUP4.status = NFS4_OK; /* If there is no FH */ if(nfs4_Is_Fh_Empty(&(data->currentFH))) { res_LOOKUP4.status = NFS4ERR_NOFILEHANDLE; return res_LOOKUP4.status; } /* If the filehandle is invalid */ if(nfs4_Is_Fh_Invalid(&(data->currentFH))) { res_LOOKUP4.status = NFS4ERR_BADHANDLE; return res_LOOKUP4.status; } /* Tests if the Filehandle is expired (for volatile filehandle) */ if(nfs4_Is_Fh_Expired(&(data->currentFH))) { res_LOOKUP4.status = NFS4ERR_FHEXPIRED; return res_LOOKUP4.status; } /* Check for empty name */ if(op->nfs_argop4_u.oplookup.objname.utf8string_len == 0 || op->nfs_argop4_u.oplookup.objname.utf8string_val == NULL) { res_LOOKUP4.status = NFS4ERR_INVAL; return res_LOOKUP4.status; } /* Check for name to long */ if(op->nfs_argop4_u.oplookup.objname.utf8string_len > FSAL_MAX_NAME_LEN) { res_LOOKUP4.status = NFS4ERR_NAMETOOLONG; return res_LOOKUP4.status; } /* If Filehandle points to a pseudo fs entry, manage it via pseudofs specific functions */ if(nfs4_Is_Fh_Pseudo(&(data->currentFH))) return nfs4_op_lookup_pseudo(op, data, resp); #ifndef _NO_XATTRD /* If Filehandle points to a xattr object, manage it via the xattrs specific functions */ if(nfs4_Is_Fh_Xattr(&(data->currentFH))) return nfs4_op_lookup_xattr(op, data, resp); #endif /* UTF8 strings may not end with \0, but they carry their length */ utf82str(strname, sizeof(strname), &arg_LOOKUP4.objname); #ifndef _NO_XATTRD /* Is this a .xattr.d.<object> name ? */ if(nfs_XattrD_Name(strname, objname)) { strcpy(strname, objname); xattr_found = TRUE; } #endif if((cache_status = cache_inode_error_convert(FSAL_str2name(strname, MAXNAMLEN, &name))) != CACHE_INODE_SUCCESS) { res_LOOKUP4.status = nfs4_Errno(cache_status); return res_LOOKUP4.status; } /* No 'cd .' is allowed return NFS4ERR_BADNAME in this case */ /* No 'cd .. is allowed, return EINVAL in this case. NFS4_OP_LOOKUPP should be use instead */ if(!FSAL_namecmp(&name, (fsal_name_t *) & FSAL_DOT) || !FSAL_namecmp(&name, (fsal_name_t *) & FSAL_DOT_DOT)) { res_LOOKUP4.status = NFS4ERR_BADNAME; return res_LOOKUP4.status; } /* Do the lookup in the HPSS Namespace */ file_pentry = NULL; dir_pentry = data->current_entry; /* Sanity check: dir_pentry should be ACTUALLY a directory */ if(dir_pentry->internal_md.type != DIR_BEGINNING && dir_pentry->internal_md.type != DIR_CONTINUE) { /* This is not a directory */ if(dir_pentry->internal_md.type == SYMBOLIC_LINK) res_LOOKUP4.status = NFS4ERR_SYMLINK; else res_LOOKUP4.status = NFS4ERR_NOTDIR; /* Return failed status */ return res_LOOKUP4.status; } /* BUGAZOMEU: Faire la gestion des cross junction traverse */ if((file_pentry = cache_inode_lookup(dir_pentry, &name, &attrlookup, data->ht, data->pclient, data->pcontext, &cache_status)) != NULL) { /* Extract the fsal attributes from the cache inode pentry */ pfsal_handle = cache_inode_get_fsal_handle(file_pentry, &cache_status); if(cache_status != CACHE_INODE_SUCCESS) { res_LOOKUP4.status = NFS4ERR_SERVERFAULT; return res_LOOKUP4.status; } /* Convert it to a file handle */ if(!nfs4_FSALToFhandle(&data->currentFH, pfsal_handle, data)) { res_LOOKUP4.status = NFS4ERR_SERVERFAULT; return res_LOOKUP4.status; } /* Copy this to the mounted on FH (if no junction is traversed */ memcpy((char *)(data->mounted_on_FH.nfs_fh4_val), (char *)(data->currentFH.nfs_fh4_val), data->currentFH.nfs_fh4_len); data->mounted_on_FH.nfs_fh4_len = data->currentFH.nfs_fh4_len; #if 0 print_buff((char *)cache_inode_get_fsal_handle(file_pentry, &cache_status), sizeof(fsal_handle_t)); print_buff((char *)cache_inode_get_fsal_handle(dir_pentry, &cache_status), sizeof(fsal_handle_t)); #endif if(isFullDebug(COMPONENT_NFS_V4)) { LogFullDebug(COMPONENT_NFS_V4, "----> nfs4_op_lookup: name=%s dir_pentry=%p looked up pentry=%p", strname, dir_pentry, file_pentry); LogFullDebug(COMPONENT_NFS_V4, "----> FSAL handle parent puis fils dans nfs4_op_lookup"); print_buff(COMPONENT_NFS_V4, (char *)cache_inode_get_fsal_handle(file_pentry, &cache_status), sizeof(fsal_handle_t)); print_buff(COMPONENT_NFS_V4, (char *)cache_inode_get_fsal_handle(dir_pentry, &cache_status), sizeof(fsal_handle_t)); } LogHandleNFS4("NFS4 LOOKUP CURRENT FH: ", &data->currentFH); /* Keep the pointer within the compound data */ data->current_entry = file_pentry; data->current_filetype = file_pentry->internal_md.type; /* Return successfully */ res_LOOKUP4.status = NFS4_OK; #ifndef _NO_XATTRD /* If this is a xattr ghost directory name, update the FH */ if(xattr_found == TRUE) res_LOOKUP4.status = nfs4_fh_to_xattrfh(&(data->currentFH), &(data->currentFH)); #endif if((data->current_entry->internal_md.type == DIR_BEGINNING) && (data->current_entry->object.dir_begin.referral != NULL)) { if(!nfs4_Set_Fh_Referral(&(data->currentFH))) { res_LOOKUP4.status = NFS4ERR_SERVERFAULT; return res_LOOKUP4.status; } } return NFS4_OK; } /* If the part of the code is reached, then something wrong occured in the lookup process, status is not HPSS_E_NOERROR * and contains the code for the error */ res_LOOKUP4.status = nfs4_Errno(cache_status); return res_LOOKUP4.status; } /* nfs4_op_lookup */
int nfs4_op_putrootfh(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { fsal_status_t status = {0, 0}; struct fsal_obj_handle *file_obj; PUTROOTFH4res * const res_PUTROOTFH4 = &resp->nfs_resop4_u.opputrootfh; /* First of all, set the reply to zero to make sure * it contains no parasite information */ memset(resp, 0, sizeof(struct nfs_resop4)); resp->resop = NFS4_OP_PUTROOTFH; /* Release any old export reference */ if (op_ctx->ctx_export != NULL) put_gsh_export(op_ctx->ctx_export); op_ctx->ctx_export = NULL; op_ctx->fsal_export = NULL; /* Clear out current entry for now */ set_current_entry(data, NULL); /* Get the root export of the Pseudo FS */ op_ctx->ctx_export = get_gsh_export_by_pseudo("/", true); if (op_ctx->ctx_export == NULL) { LogCrit(COMPONENT_EXPORT, "Could not get export for Pseudo Root"); res_PUTROOTFH4->status = NFS4ERR_NOENT; return res_PUTROOTFH4->status; } op_ctx->fsal_export = op_ctx->ctx_export->fsal_export; /* Build credentials */ res_PUTROOTFH4->status = nfs4_export_check_access(data->req); /* Test for access error (export should not be visible). */ if (res_PUTROOTFH4->status == NFS4ERR_ACCESS) { /* Client has no access at all */ LogDebug(COMPONENT_EXPORT, "Client doesn't have access to Pseudo Root"); return res_PUTROOTFH4->status; } if (res_PUTROOTFH4->status != NFS4_OK) { LogMajor(COMPONENT_EXPORT, "Failed to get FSAL credentials Pseudo Root"); return res_PUTROOTFH4->status; } /* Get the Pesudo Root inode of the mounted on export */ status = nfs_export_get_root_entry(op_ctx->ctx_export, &file_obj); if (FSAL_IS_ERROR(status)) { LogCrit(COMPONENT_EXPORT, "Could not get root inode for Pseudo Root"); res_PUTROOTFH4->status = nfs4_Errno_status(status); return res_PUTROOTFH4->status; } LogMidDebug(COMPONENT_EXPORT, "Root node %p", data->current_obj); set_current_entry(data, file_obj); /* Put our ref */ file_obj->obj_ops.put_ref(file_obj); /* Convert it to a file handle */ if (!nfs4_FSALToFhandle(data->currentFH.nfs_fh4_val == NULL, &data->currentFH, data->current_obj, op_ctx->ctx_export)) { LogCrit(COMPONENT_EXPORT, "Could not get handle for Pseudo Root"); res_PUTROOTFH4->status = NFS4ERR_SERVERFAULT; return res_PUTROOTFH4->status; } LogHandleNFS4("NFS4 PUTROOTFH CURRENT FH: ", &data->currentFH); res_PUTROOTFH4->status = NFS4_OK; return res_PUTROOTFH4->status; } /* nfs4_op_putrootfh */
int nfs4_op_putrootfh(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp) { int error; char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putrootfh"; /* This NFS4 Operation has no argument, it just get then ROOTFH (replace MOUNTPROC3_MNT) */ /* First of all, set the reply to zero to make sure it contains no parasite information */ memset(resp, 0, sizeof(struct nfs_resop4)); resp->resop = NFS4_OP_PUTROOTFH; resp->nfs_resop4_u.opputrootfh.status = NFS4_OK; if((error = CreateROOTFH4(&(data->rootFH), data)) != NFS4_OK) { res_PUTROOTFH4.status = error; return res_PUTROOTFH4.status; } data->current_entry = NULL; /* No cache inode entry for the directory within pseudo fs */ data->current_filetype = DIRECTORY; /* Only directory in the pseudo fs */ /* I copy the root FH to the currentFH and, if not already done, to the publicFH */ /* For the moment, I choose to have rootFH = publicFH */ /* For initial mounted_on_FH, I'll use the rootFH, this will change at junction traversal */ if(data->currentFH.nfs_fh4_len == 0) { if((error = nfs4_AllocateFH(&(data->currentFH))) != NFS4_OK) { resp->nfs_resop4_u.opputrootfh.status = error; return error; } } memcpy((char *)(data->currentFH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val), data->rootFH.nfs_fh4_len); data->currentFH.nfs_fh4_len = data->rootFH.nfs_fh4_len; if(data->mounted_on_FH.nfs_fh4_len == 0) { if((error = nfs4_AllocateFH(&(data->mounted_on_FH))) != NFS4_OK) { resp->nfs_resop4_u.opputrootfh.status = error; return error; } } memcpy((char *)(data->mounted_on_FH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val), data->rootFH.nfs_fh4_len); data->mounted_on_FH.nfs_fh4_len = data->rootFH.nfs_fh4_len; if(data->publicFH.nfs_fh4_len == 0) { if((error = nfs4_AllocateFH(&(data->publicFH))) != NFS4_OK) { resp->nfs_resop4_u.opputrootfh.status = error; return error; } } /* Copy the data where they are supposed to be */ memcpy((char *)(data->publicFH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val), data->rootFH.nfs_fh4_len); data->publicFH.nfs_fh4_len = data->rootFH.nfs_fh4_len; LogHandleNFS4("NFS4 PUTROOTFH ROOT FH: ", &data->rootFH); LogHandleNFS4("NFS4 PUTROOTFH CURRENT FH: ", &data->currentFH); LogFullDebug(COMPONENT_NFS_V4, "NFS4 PUTROOTFH: Ending on status %d", resp->nfs_resop4_u.opputrootfh.status); return resp->nfs_resop4_u.opputrootfh.status; } /* nfs4_op_putrootfh */