nfs-ganesha 1.4

fsal_symlinks.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 #include "fsal.h"
00018 #include "fsal_internal.h"
00019 #include "fsal_convert.h"
00020 #include "fsal_common.h"
00021 #include <string.h>
00022 
00051 fsal_status_t ZFSFSAL_readlink(fsal_handle_t * linkhandle, /* IN */
00052                             fsal_op_context_t * p_context,      /* IN */
00053                             fsal_path_t * p_link_content,       /* OUT */
00054                             fsal_attrib_list_t * link_attributes        /* [ IN/OUT ] */
00055     )
00056 {
00057 
00058   fsal_status_t st;
00059   char link_content_out[FSAL_MAX_PATH_LEN];
00060   creden_t cred;
00061 
00062   /* sanity checks.
00063    * note : link_attributes is optional.
00064    */
00065   if(!linkhandle || !p_context || !p_link_content)
00066     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);
00067 
00068   cred.uid = p_context->credential.user;
00069   cred.gid = p_context->credential.group;
00070 
00071   TakeTokenFSCall();
00072 
00073   libzfswrap_readlink(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs,
00074                       &cred,
00075                       ((zfsfsal_handle_t *)linkhandle)->data.zfs_handle,
00076                       link_content_out,
00077                       sizeof(link_content_out));
00078 
00079   ReleaseTokenFSCall();
00080 
00081   /* >> convert error code and return on error << */
00082 
00083   /* >> convert fs output to fsal_path_t
00084    * for example, if this is a char * (link_content_out) :
00085    */
00086 
00087   st = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content);
00088 
00089   if(FSAL_IS_ERROR(st))
00090     Return(st.major, st.minor, INDEX_FSAL_readlink);
00091 
00092   /* retrieves object attributes, if asked */
00093 
00094   if(link_attributes)
00095     {
00096 
00097       fsal_status_t status;
00098 
00099       status = ZFSFSAL_getattrs(linkhandle, p_context, link_attributes);
00100 
00101       /* On error, we set a flag in the returned attributes */
00102 
00103       if(FSAL_IS_ERROR(status))
00104         {
00105           FSAL_CLEAR_MASK(link_attributes->asked_attributes);
00106           FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00107         }
00108 
00109     }
00110   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink);
00111 
00112 }
00113 
00148 fsal_status_t ZFSFSAL_symlink(fsal_handle_t * parent_directory_handle,     /* IN */
00149                            fsal_name_t * p_linkname,    /* IN */
00150                            fsal_path_t * p_linkcontent, /* IN */
00151                            fsal_op_context_t * p_context,       /* IN */
00152                            fsal_accessmode_t accessmode,        /* IN (ignored) */
00153                            fsal_handle_t * link_handle, /* OUT */
00154                            fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */
00155     )
00156 {
00157 
00158   creden_t cred;
00159 
00160   /* sanity checks.
00161    * note : link_attributes is optional.
00162    */
00163   if(!parent_directory_handle ||
00164      !p_context || !link_handle || !p_linkname || !p_linkcontent)
00165     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00166 
00167   /* Tests if symlinking is allowed by configuration. */
00168   if(!global_fs_info.symlink_support)
00169     Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink);
00170 
00171   /* Hook to prevent creation of anything inside the snapshot */
00172   if(((zfsfsal_handle_t *)parent_directory_handle)->data.i_snap != 0)
00173   {
00174     LogDebug(COMPONENT_FSAL, "Trying to create a symlink inside a snapshot");
00175     Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_symlink);
00176   }
00177 
00178   cred.uid = p_context->credential.user;
00179   cred.gid = p_context->credential.group;
00180 
00181   TakeTokenFSCall();
00182 
00183   inogen_t object;
00184   libzfswrap_symlink(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs,
00185                      &cred,
00186                      ((zfsfsal_handle_t *)parent_directory_handle)->data.zfs_handle,
00187                      p_linkname->name,
00188                      p_linkcontent->path, &object);
00189 
00190   ReleaseTokenFSCall();
00191 
00192   /* >> convert status and return on error <<  */
00193 
00194   /* >> set output handle << */
00195   ((zfsfsal_handle_t *)link_handle)->data.zfs_handle = object;
00196   ((zfsfsal_handle_t *)link_handle)->data.type = FSAL_TYPE_LNK;
00197   ((zfsfsal_handle_t *)link_handle)->data.i_snap = 0;
00198 
00199   if(link_attributes)
00200     {
00201 
00202       fsal_status_t status = ZFSFSAL_getattrs(link_handle, p_context, link_attributes);
00203 
00204       /* On error, we set a flag in the returned attributes */
00205       if(FSAL_IS_ERROR(status))
00206         {
00207           FSAL_CLEAR_MASK(link_attributes->asked_attributes);
00208           FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00209         }
00210     }
00211 
00212   /* OK */
00213   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink);
00214 }