blob: a85155ab70a6f9e84db1a69f34de58c1bee95a79 [file] [log] [blame]
/*
*
*
* Copyright CEA/DAM/DIF (2008)
* contributeur : Philippe DENIEL philippe.deniel@cea.fr
* Thomas LEIBOVICI thomas.leibovici@cea.fr
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* ---------------------------------------
*/
/**
* @file nfs_file_handle.h
* @brief Prototypes for the file handle in v3 and v4
*/
#ifndef NFS_FILE_HANDLE_H
#define NFS_FILE_HANDLE_H
#include <sys/types.h>
#include <sys/param.h>
#include "log.h"
#include "sal_data.h"
#include "export_mgr.h"
#include "nfs_fh.h"
/**
* @brief Get the actual size of a v3 handle based on the sized fsopaque
*
* @return The filehandle size
*/
static inline size_t nfs3_sizeof_handle(struct file_handle_v3 *hdl)
{
int hsize;
int aligned_hsize;
hsize = offsetof(struct file_handle_v3, fsopaque) + hdl->fs_len;
/* correct packet's fh length so it's divisible by 4 to trick dNFS into
working. This is essentially sending the padding. */
aligned_hsize = roundup(hsize, 4);
if (aligned_hsize <= NFS3_FHSIZE)
hsize = aligned_hsize;
return hsize;
}
/**
*
* @brief Allocates a buffer to be used for storing a NFSv4 filehandle.
*
* Allocates a buffer to be used for storing a NFSv3 filehandle.
*
* @param fh [INOUT] the filehandle to manage.
*
*/
static inline
void nfs3_AllocateFH(nfs_fh3 *fh)
{
/* Allocating the filehandle in memory */
fh->data.data_len = NFS3_FHSIZE;
fh->data.data_val = gsh_calloc(1, NFS3_FHSIZE);
}
static inline void nfs3_freeFH(nfs_fh3 *fh)
{
fh->data.data_len = 0;
gsh_free(fh->data.data_val);
fh->data.data_val = NULL;
}
/**
*
* @brief Allocates a buffer to be used for storing a NFSv4 filehandle.
*
* Allocates a buffer to be used for storing a NFSv4 filehandle.
*
* @param fh [INOUT] the filehandle to manage.
*
*/
static inline
void nfs4_AllocateFH(nfs_fh4 *fh)
{
/* Allocating the filehandle in memory */
fh->nfs_fh4_len = NFS4_FHSIZE;
fh->nfs_fh4_val = gsh_calloc(1, NFS4_FHSIZE);
}
static inline void nfs4_freeFH(nfs_fh4 *fh)
{
fh->nfs_fh4_len = 0;
gsh_free(fh->nfs_fh4_val);
fh->nfs_fh4_val = NULL;
}
/**
* @brief Get the actual size of a v4 handle based on the sized fsopaque
*
* @return The filehandle size
*/
static inline size_t nfs4_sizeof_handle(struct file_handle_v4 *hdl)
{
return offsetof(struct file_handle_v4, fsopaque)+hdl->fs_len;
}
#define LEN_FH_STR 1024
/* File handle translation utility */
#ifdef _USE_NFS3
struct fsal_obj_handle *nfs3_FhandleToCache(nfs_fh3 *, nfsstat3 *, int *);
#endif
bool nfs4_FSALToFhandle(bool allocate,
nfs_fh4 *fh4,
const struct fsal_obj_handle *fsalhandle,
struct gsh_export *exp);
bool nfs3_FSALToFhandle(bool allocate,
nfs_fh3 *fh3,
const struct fsal_obj_handle *fsalhandle,
struct gsh_export *exp);
/* nfs3 validation */
int nfs3_Is_Fh_Invalid(nfs_fh3 *);
/**
*
* nfs3_FhandleToExportId
*
* This routine extracts the export id from the file handle NFSv3
*
* @param pfh3 [IN] file handle to manage.
*
* @return the export id.
*
*/
static inline int nfs3_FhandleToExportId(nfs_fh3 *pfh3)
{
file_handle_v3_t *pfile_handle;
if (nfs3_Is_Fh_Invalid(pfh3) != NFS4_OK)
return -1; /* Badly formed argument */
pfile_handle = (file_handle_v3_t *) (pfh3->data.data_val);
/*exportid is in network byte order in nfs_fh3*/
return ntohs(pfile_handle->exportid);
} /* nfs3_FhandleToExportId */
static inline int nlm4_FhandleToExportId(netobj *pfh3)
{
nfs_fh3 fh3;
if (pfh3 == NULL)
return nfs3_FhandleToExportId(NULL);
fh3.data.data_val = pfh3->n_bytes;
fh3.data.data_len = pfh3->n_len;
return nfs3_FhandleToExportId(&fh3);
}
/**
*
* @brief Test if an NFS v4 file handle is empty.
*
* This routine is used to test if a fh is empty (contains no data).
*
* @param pfh [IN] file handle to test.
*
* @return NFS4_OK if successfull, NFS4ERR_NOFILEHANDLE is fh is empty.
*
*/
static inline int nfs4_Is_Fh_Empty(nfs_fh4 *pfh)
{
if (pfh == NULL) {
LogMajor(COMPONENT_FILEHANDLE, "INVALID HANDLE: pfh=NULL");
return NFS4ERR_NOFILEHANDLE;
}
if (pfh->nfs_fh4_len == 0) {
LogInfo(COMPONENT_FILEHANDLE, "INVALID HANDLE: empty");
return NFS4ERR_NOFILEHANDLE;
}
return NFS4_OK;
} /* nfs4_Is_Fh_Empty */
/* NFSv4 specific FH related functions */
int nfs4_Is_Fh_Invalid(nfs_fh4 *);
int nfs4_Is_Fh_DSHandle(nfs_fh4 *);
nfsstat4 nfs4_sanity_check_FH(compound_data_t *data,
object_file_type_t required_type,
bool ds_allowed);
nfsstat4 nfs4_sanity_check_saved_FH(compound_data_t *data, int required_type,
bool ds_allowed);
/* File handle print function (mostly used for debugging) */
void print_fhandle3(log_components_t, nfs_fh3 *);
void print_fhandle4(log_components_t, nfs_fh4 *);
void print_fhandle_nlm(log_components_t, netobj *);
void print_buff(log_components_t, char *, int);
void LogCompoundFH(compound_data_t *);
void sprint_fhandle3(char *str, nfs_fh3 *fh);
void sprint_fhandle4(char *str, nfs_fh4 *fh);
void sprint_fhandle_nlm(char *str, netobj *fh);
void sprint_buff(char *str, char *buff, int len);
void sprint_mem(char *str, char *buff, int len);
void nfs_FhandleToStr(u_long rq_vers, nfs_fh3 *pfh3, nfs_fh4 *pfh4, char *str);
#define LogHandleNFS4(label, fh4) \
do { \
if (isFullDebug(COMPONENT_NFS_V4)) { \
char str[LEN_FH_STR]; \
sprint_fhandle4(str, fh4); \
LogFullDebug(COMPONENT_NFS_V4, "%s%s", label, str); \
} \
} while (0)
#endif /* NFS_FILE_HANDLE_H */