nfs-ganesha 1.4
|
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 }