/** * @brief NFS4_OP_ACCESS, checks for file's accessibility. * * This function impelments the NFS4_OP_ACCESS operation, which checks * for file's accessibility. * * @param[in] op Arguments for nfs4_op * @param[in,out] data Compound request's data * @param[out] resp Results for nfs4_op * * @return per RFC5661, p. 362 * */ int nfs4_op_access(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { ACCESS4args * const arg_ACCESS4 = &op->nfs_argop4_u.opaccess; ACCESS4res * const res_ACCESS4 = &resp->nfs_resop4_u.opaccess; cache_inode_status_t cache_status; uint32_t max_access = (ACCESS4_READ | ACCESS4_LOOKUP | ACCESS4_MODIFY | ACCESS4_EXTEND | ACCESS4_DELETE | ACCESS4_EXECUTE); /* initialize output */ res_ACCESS4->ACCESS4res_u.resok4.supported = 0; res_ACCESS4->ACCESS4res_u.resok4.access = 0; resp->resop = NFS4_OP_ACCESS; res_ACCESS4->status = NFS4_OK; /* Do basic checks on a filehandle */ res_ACCESS4->status = nfs4_sanity_check_FH(data, NO_FILE_TYPE, false); if (res_ACCESS4->status != NFS4_OK) return res_ACCESS4->status; /* Check for input parameter's sanity */ if (arg_ACCESS4->access > max_access) { res_ACCESS4->status = NFS4ERR_INVAL; return res_ACCESS4->status; } /* Perform the 'access' call */ cache_status = nfs_access_op(data->current_entry, arg_ACCESS4->access, &res_ACCESS4->ACCESS4res_u.resok4.access, &res_ACCESS4->ACCESS4res_u.resok4.supported); if (cache_status == CACHE_INODE_SUCCESS || cache_status == CACHE_INODE_FSAL_EACCESS) res_ACCESS4->status = NFS4_OK; else res_ACCESS4->status = nfs4_Errno(cache_status); return res_ACCESS4->status; } /* nfs4_op_access */
int nfs3_access(nfs_arg_t *arg, struct svc_req *req, nfs_res_t *res) { cache_inode_status_t cache_status; cache_entry_t *entry = NULL; int rc = NFS_REQ_OK; if (isDebug(COMPONENT_NFSPROTO)) { char str[LEN_FH_STR]; sprint_fhandle3(str, &(arg->arg_access3.object)); LogDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling nfs3_access handle: %s", str); } /* to avoid setting it on each error case */ res->res_access3.ACCESS3res_u.resfail.obj_attributes.attributes_follow = FALSE; /* Convert file handle into a vnode */ entry = nfs3_FhandleToCache(&(arg->arg_access3.object), &(res->res_access3.status), &rc); if (entry == NULL) { /* Status and rc have been set by nfs3_FhandleToCache */ goto out; } /* Perform the 'access' call */ cache_status = nfs_access_op(entry, arg->arg_access3.access, &res->res_access3.ACCESS3res_u.resok.access, NULL); if (cache_status == CACHE_INODE_SUCCESS || cache_status == CACHE_INODE_FSAL_EACCESS) { /* Build Post Op Attributes */ nfs_SetPostOpAttr(entry, &(res->res_access3.ACCESS3res_u.resok. obj_attributes)); res->res_access3.status = NFS3_OK; rc = NFS_REQ_OK; goto out; } /* If we are here, there was an error */ if (nfs_RetryableError(cache_status)) { rc = NFS_REQ_DROP; goto out; } res->res_access3.status = nfs3_Errno(cache_status); nfs_SetPostOpAttr(entry, &(res->res_access3.ACCESS3res_u.resfail. obj_attributes)); out: if (entry) cache_inode_put(entry); return rc; } /* nfs3_access */