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 #include "HPSSclapiExt/hpssclapiext.h"
00023 
00024 #include <hpss_errno.h>
00025 
00054 fsal_status_t HPSSFSAL_readlink(hpssfsal_handle_t * linkhandle, /* IN */
00055                                 hpssfsal_op_context_t * p_context,      /* IN */
00056                                 fsal_path_t * p_link_content,   /* OUT */
00057                                 fsal_attrib_list_t * link_attributes    /* [ IN/OUT ] */
00058     )
00059 {
00060 
00061   int rc;
00062   fsal_status_t st;
00063   char link_content_out[FSAL_MAX_PATH_LEN];
00064 
00065   /* sanity checks.
00066    * note : link_attributes is optional.
00067    */
00068   if(!linkhandle || !p_context || !p_link_content)
00069     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);
00070 
00071   /* call to the API */
00072 
00073   TakeTokenFSCall();
00074 
00075   rc = hpss_ReadlinkHandle(&(linkhandle->data.ns_handle),    /* IN - Handle of symbolic link */
00076                            NULL,        /* IN - Path of the link (null=>ignored) */
00077                            link_content_out,    /* OUT - contents of the link */
00078                            FSAL_MAX_PATH_LEN,   /* IN - Size, in bytes, of contents buffer */
00079                            &p_context->credential.hpss_usercred);       /* IN - pointer to user credentials */
00080 
00081   ReleaseTokenFSCall();
00082 
00083   /* /!\ rc is the length for the symlink content !!! */
00084 
00085   /* The HPSS_ENOENT error actually means that handle is STALE */
00086   if(rc == HPSS_ENOENT)
00087     Return(ERR_FSAL_STALE, -rc, INDEX_FSAL_readlink);
00088   else if(rc < 0)
00089     Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_readlink);
00090 
00091   /* convert char * to fsal_path_t */
00092 
00093   st = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content);
00094 
00095   if(FSAL_IS_ERROR(st))
00096     Return(st.major, st.minor, INDEX_FSAL_readlink);
00097 
00098   /* retrieves object attributes, if asked */
00099 
00100   if(link_attributes)
00101     {
00102 
00103       fsal_status_t status;
00104 
00105       status = HPSSFSAL_getattrs(linkhandle, p_context, link_attributes);
00106 
00107       /* On error, we set a flag in the returned attributes */
00108 
00109       if(FSAL_IS_ERROR(status))
00110         {
00111           FSAL_CLEAR_MASK(link_attributes->asked_attributes);
00112           FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00113         }
00114 
00115     }
00116 
00117   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink);
00118 
00119 }
00120 
00155 fsal_status_t HPSSFSAL_symlink(hpssfsal_handle_t * parent_directory_handle,     /* IN */
00156                                fsal_name_t * p_linkname,        /* IN */
00157                                fsal_path_t * p_linkcontent,     /* IN */
00158                                hpssfsal_op_context_t * p_context,       /* IN */
00159                                fsal_accessmode_t accessmode,    /* IN (ignored) */
00160                                hpssfsal_handle_t * link_handle, /* OUT */
00161                                fsal_attrib_list_t * link_attributes     /* [ IN/OUT ] */
00162     )
00163 {
00164 
00165   int rc;
00166   hpss_Attrs_t attrs;
00167 
00168   /* sanity checks.
00169    * note : link_attributes is optional.
00170    */
00171   if(!parent_directory_handle ||
00172      !p_context || !link_handle || !p_linkname || !p_linkcontent)
00173     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);
00174 
00175   /* Tests if symlinking is allowed by configuration. */
00176 
00177   if(!global_fs_info.symlink_support)
00178     Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink);
00179 
00180   /* call to hpss client API. */
00181 
00182   TakeTokenFSCall();
00183 
00184   memset( (char *)link_handle, 0, sizeof( hpssfsal_handle_t ) ) ;
00185   rc = HPSSFSAL_SymlinkHandle(&(parent_directory_handle->data.ns_handle),    /* IN - Handle of existing file */
00186                               p_linkcontent->path,      /* IN - Desired contents of the link */
00187                               p_linkname->name, /* IN - New name of the symbolic link */
00188                               &(p_context->credential.hpss_usercred),   /* IN - pointer to user credentials */
00189                               &(link_handle->data.ns_handle),        /* OUT */
00190                               &attrs    /* OUT - symbolic link attributes */
00191       );
00192 
00193   ReleaseTokenFSCall();
00194 
00195   /* /!\ WARNING : When the directory handle is stale, HPSS returns ENOTDIR.
00196    * If the returned value is HPSS_ENOTDIR, parent handle MAY be stale.
00197    * Thus, we must double-check by calling getattrs.   
00198    */
00199   if(rc == HPSS_ENOTDIR || rc == HPSS_ENOENT)
00200     {
00201       if(HPSSFSAL_IsStaleHandle(&parent_directory_handle->data.ns_handle,
00202                                 &p_context->credential.hpss_usercred))
00203         {
00204           Return(ERR_FSAL_STALE, -rc, INDEX_FSAL_symlink);
00205         }
00206     }
00207 
00208   /* other errors */
00209   if(rc)
00210     Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_symlink);
00211 
00212   /* set output handle */
00213   link_handle->data.obj_type = FSAL_TYPE_LNK;
00214 
00215   /* get attributes if asked */
00216 
00217   if(link_attributes)
00218     {
00219 
00220       fsal_status_t status;
00221 
00222       status = hpss2fsal_attributes(&(link_handle->data.ns_handle), &attrs, link_attributes);
00223 
00224       if(FSAL_IS_ERROR(status))
00225         {
00226           FSAL_CLEAR_MASK(link_attributes->asked_attributes);
00227           FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00228         }
00229 
00230     }
00231 
00232   /* OK */
00233   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink);
00234 }