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 #ifdef _SOLARIS 00018 #include "solaris_port.h" 00019 #endif /* _SOLARIS */ 00020 00021 #include <string.h> 00022 #ifdef _USE_GSSRPC 00023 #include <gssrpc/rpc.h> 00024 #include <gssrpc/xdr.h> 00025 #else 00026 #include <rpc/rpc.h> 00027 #include <rpc/xdr.h> 00028 #endif 00029 #include "nfs4.h" 00030 00031 #include "fsal_internal.h" 00032 #include "fsal_convert.h" 00033 #include "fsal_common.h" 00034 00035 #include "nfs_proto_functions.h" 00036 #include "nfs_proto_tools.h" 00037 #include "fsal_nfsv4_macros.h" 00038 00067 fsal_status_t PROXYFSAL_readlink(fsal_handle_t * linkhandle, /* IN */ 00068 fsal_op_context_t *context, /* IN */ 00069 fsal_path_t * p_link_content, /* OUT */ 00070 fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ 00071 ) 00072 { 00073 00074 int rc; 00075 00076 COMPOUND4args argnfs4; 00077 COMPOUND4res resnfs4; 00078 nfs_fh4 nfs4fh; 00079 bitmap4 bitmap; 00080 uint32_t bitmap_val[2]; 00081 fsal_attrib_list_t attributes; 00082 proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; 00083 00084 #define FSAL_READLINK_NB_OP_ALLOC 4 00085 nfs_argop4 argoparray[FSAL_READLINK_NB_OP_ALLOC]; 00086 nfs_resop4 resoparray[FSAL_READLINK_NB_OP_ALLOC]; 00087 uint32_t bitmap_res[2]; 00088 00089 fsal_proxy_internal_fattr_t fattr_internal; 00090 char padpath[FSAL_MAX_PATH_LEN]; 00091 00092 struct timeval timeout = TIMEOUTRPC; 00093 00094 /* sanity checks. 00095 * note : link_attributes is optional. 00096 */ 00097 if(!linkhandle || !p_context || !p_link_content) 00098 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); 00099 00100 /* Setup results structures */ 00101 argnfs4.argarray.argarray_val = argoparray; 00102 resnfs4.resarray.resarray_val = resoparray; 00103 fsal_internal_proxy_setup_fattr(&fattr_internal); 00104 argnfs4.minorversion = 0; 00105 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readlink" ; */ 00106 argnfs4.tag.utf8string_val = NULL; 00107 argnfs4.tag.utf8string_len = 0; 00108 argnfs4.argarray.argarray_len = 0; 00109 00110 /* >> retrieve root handle filehandle here << */ 00111 bitmap.bitmap4_val = bitmap_val; 00112 bitmap.bitmap4_len = 2; 00113 fsal_internal_proxy_create_fattr_bitmap(&bitmap); 00114 00115 if(fsal_internal_proxy_extract_fh(&nfs4fh, linkhandle) == FALSE) 00116 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); 00117 00118 #define FSAL_READLINK_IDX_OP_PUTFH 0 00119 #define FSAL_READLINK_IDX_OP_READLINK 1 00120 #define FSAL_READLINK_IDX_OP_GETATTR 2 00121 00122 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00123 COMPOUNDV4_ARG_ADD_OP_READLINK(argnfs4); 00124 COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); 00125 00126 resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00127 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; 00128 resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00129 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; 00130 00131 resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00132 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = 00133 (char *)&fattr_internal; 00134 resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00135 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = 00136 sizeof(fattr_internal); 00137 00138 resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink. 00139 READLINK4res_u.resok4.link.utf8string_val = (char *)padpath; 00140 resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink. 00141 READLINK4res_u.resok4.link.utf8string_len = FSAL_MAX_PATH_LEN; 00142 00143 TakeTokenFSCall(); 00144 00145 /* Call the NFSv4 function */ 00146 COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); 00147 if(rc != RPC_SUCCESS) 00148 { 00149 ReleaseTokenFSCall(); 00150 00151 Return(ERR_FSAL_IO, rc, INDEX_FSAL_readlink); 00152 } 00153 00154 ReleaseTokenFSCall(); 00155 00156 /* >> convert error code and return on error << */ 00157 if(resnfs4.status != NFS4_OK) 00158 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readlink); 00159 00160 /* >> convert fs output to fsal_path_t 00161 * for example, if this is a char * (link_content_out) : 00162 */ 00163 00164 if(fsal_internal_proxy_fsal_utf8_2_path(p_link_content, 00165 &(resnfs4.resarray.resarray_val 00166 [FSAL_READLINK_IDX_OP_READLINK]. 00167 nfs_resop4_u.opreadlink.READLINK4res_u.resok4. 00168 link)) == FALSE) 00169 00170 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); 00171 00172 /* retrieves object attributes, if asked */ 00173 if(link_attributes) 00174 { 00175 /* Use NFSv4 service function to build the FSAL_attr */ 00176 if(nfs4_Fattr_To_FSAL_attr(&attributes, 00177 &resnfs4.resarray. 00178 resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u. 00179 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) 00180 { 00181 FSAL_CLEAR_MASK(link_attributes->asked_attributes); 00182 FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00183 00184 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_readlink); 00185 } 00186 00187 memcpy(link_attributes, &attributes, sizeof(attributes)); 00188 00189 } 00190 00191 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink); 00192 00193 } 00194 00229 fsal_status_t PROXYFSAL_symlink(fsal_handle_t * parent_directory_handle, /* IN */ 00230 fsal_name_t * p_linkname, /* IN */ 00231 fsal_path_t * p_linkcontent, /* IN */ 00232 fsal_op_context_t *context, /* IN */ 00233 fsal_accessmode_t accessmode, /* IN (ignored) */ 00234 fsal_handle_t * link_handle, /* OUT */ 00235 fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ 00236 ) 00237 { 00238 00239 int rc; 00240 00241 COMPOUND4args argnfs4; 00242 COMPOUND4res resnfs4; 00243 nfs_fh4 nfs4fh; 00244 bitmap4 bitmap; 00245 uint32_t bitmap_res[2]; 00246 uint32_t bitmap_mkdir[2]; 00247 uint32_t bitmap_getattr_res[2]; 00248 uint32_t bitmap_conv_val[2]; 00249 fattr4 input_attr; 00250 bitmap4 convert_bitmap; 00251 component4 name; 00252 char nameval[MAXNAMLEN]; 00253 component4 linkname; 00254 char linknameval[MAXNAMLEN]; 00255 char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN]; 00256 00257 fsal_proxy_internal_fattr_t fattr_internal; 00258 fsal_attrib_list_t create_mode_attr; 00259 fsal_attrib_list_t attributes; 00260 proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; 00261 00262 #define FSAL_SYMLINK_NB_OP_ALLOC 4 00263 #define FSAL_SYMLINK_VAL_BUFFER 1024 00264 00265 nfs_argop4 argoparray[FSAL_SYMLINK_NB_OP_ALLOC]; 00266 nfs_resop4 resoparray[FSAL_SYMLINK_NB_OP_ALLOC]; 00267 00268 struct timeval timeout = TIMEOUTRPC; 00269 00270 /* sanity checks. 00271 * note : link_attributes is optional. 00272 */ 00273 if(!parent_directory_handle || 00274 !p_context || !link_handle || !p_linkname || !p_linkcontent) 00275 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); 00276 00277 /* Tests if symlinking is allowed by configuration. */ 00278 00279 if(!global_fs_info.symlink_support) 00280 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink); 00281 00282 /* Setup results structures */ 00283 argnfs4.argarray.argarray_val = argoparray; 00284 resnfs4.resarray.resarray_val = resoparray; 00285 argnfs4.minorversion = 0; 00286 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Symlink" ; */ 00287 argnfs4.tag.utf8string_val = NULL; 00288 argnfs4.tag.utf8string_len = 0; 00289 argnfs4.argarray.argarray_len = 0; 00290 00291 fsal_internal_proxy_setup_fattr(&fattr_internal); 00292 00293 convert_bitmap.bitmap4_val = bitmap_conv_val; 00294 convert_bitmap.bitmap4_len = 2; 00295 00296 memset((char *)&name, 0, sizeof(component4)); 00297 name.utf8string_val = nameval; 00298 name.utf8string_len = sizeof(nameval); 00299 if(fsal_internal_proxy_fsal_name_2_utf8(p_linkname, &name) == FALSE) 00300 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); 00301 00302 memset((char *)&linkname, 0, sizeof(component4)); 00303 linkname.utf8string_val = linknameval; 00304 if(fsal_internal_proxy_fsal_path_2_utf8(p_linkcontent, &linkname) == FALSE) 00305 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); 00306 00307 /* Get NFSv4 File handle */ 00308 if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE) 00309 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); 00310 00311 bitmap.bitmap4_val = bitmap_mkdir; 00312 bitmap.bitmap4_len = 2; 00313 fsal_internal_proxy_create_fattr_bitmap(&bitmap); 00314 00315 create_mode_attr.asked_attributes = FSAL_ATTR_MODE; 00316 create_mode_attr.mode = accessmode; 00317 fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap); 00318 00319 if(nfs4_FSALattr_To_Fattr(NULL, /* no exportlist required here */ 00320 &create_mode_attr, &input_attr, NULL, /* no compound data required here */ 00321 NULL, /* No fh here, filehandle is not a settable attribute */ 00322 &convert_bitmap) == -1) 00323 Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_symlink); 00324 00325 #define FSAL_SYMLINK_IDX_OP_PUTFH 0 00326 #define FSAL_SYMLINK_IDX_OP_SYMLINK 1 00327 #define FSAL_SYMLINK_IDX_OP_GETFH 2 00328 #define FSAL_SYMLINK_IDX_OP_GETATTR 3 00329 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00330 COMPOUNDV4_ARG_ADD_OP_SYMLINK(argnfs4, name, linkname, input_attr); 00331 COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); 00332 COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); 00333 00334 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate. 00335 CREATE4res_u.resok4.attrset.bitmap4_val = bitmap_res; 00336 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate. 00337 CREATE4res_u.resok4.attrset.bitmap4_len = 2; 00338 00339 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 00340 GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; 00341 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 00342 GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; 00343 00344 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00345 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res; 00346 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00347 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; 00348 00349 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00350 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = 00351 (char *)&fattr_internal; 00352 resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00353 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = 00354 sizeof(fattr_internal); 00355 00356 TakeTokenFSCall(); 00357 00358 /* Call the NFSv4 function */ 00359 COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); 00360 nfs4_Fattr_Free(&input_attr); 00361 if(rc != RPC_SUCCESS) 00362 { 00363 ReleaseTokenFSCall(); 00364 00365 Return(ERR_FSAL_IO, 0, INDEX_FSAL_symlink); 00366 } 00367 00368 ReleaseTokenFSCall(); 00369 00370 /* >> convert error code, and return on error << */ 00371 if(resnfs4.status != NFS4_OK) 00372 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_symlink); 00373 00374 /* Use NFSv4 service function to build the FSAL_attr */ 00375 if(nfs4_Fattr_To_FSAL_attr(&attributes, 00376 &resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR]. 00377 nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. 00378 obj_attributes) != NFS4_OK) 00379 { 00380 FSAL_CLEAR_MASK(attributes.asked_attributes); 00381 FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); 00382 00383 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_symlink); 00384 } 00385 00386 if(link_attributes) 00387 { 00388 memcpy(link_attributes, &attributes, sizeof(attributes)); 00389 } 00390 00391 if(fsal_internal_proxy_create_fh 00392 (& 00393 (resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh. 00394 GETFH4res_u.resok4.object), FSAL_TYPE_LNK, attributes.fileid, 00395 link_handle) == FALSE) 00396 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); 00397 00398 /* OK */ 00399 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink); 00400 }