nfs-ganesha 1.4

fsal_create.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #ifdef _SOLARIS
00019 #include "solaris_port.h"
00020 #endif                          /* _SOLARIS */
00021 
00022 #include <string.h>
00023 #ifdef _USE_GSSRPC
00024 #include <gssrpc/rpc.h>
00025 #include <gssrpc/xdr.h>
00026 #else
00027 #include <rpc/rpc.h>
00028 #include <rpc/xdr.h>
00029 #endif
00030 #include "nfs4.h"
00031 
00032 #include "fsal_internal.h"
00033 #include "fsal_convert.h"
00034 #include "fsal_common.h"
00035 
00036 #include "nfs_proto_functions.h"
00037 #include "nfs_proto_tools.h"
00038 #include "fsal_nfsv4_macros.h"
00039 
00040 #ifdef _APPLE
00041 #define strnlen( s, l ) strlen( s )
00042 #endif
00043 
00080 fsal_status_t PROXYFSAL_create(fsal_handle_t * parent_directory_handle,    /* IN */
00081                                fsal_name_t * p_filename,        /* IN */
00082                                fsal_op_context_t *context,      /* IN */
00083                                fsal_accessmode_t accessmode,    /* IN */
00084                                fsal_handle_t * object_handle,      /* OUT */
00085                                fsal_attrib_list_t * object_attributes   /* [ IN/OUT ] */
00086     )
00087 {
00088   int rc;
00089   COMPOUND4args argnfs4;
00090   COMPOUND4res resnfs4;
00091   nfs_fh4 nfs4fh;
00092   bitmap4 bitmap;
00093   uint32_t bitmap_res[2];
00094   uint32_t bitmap_conv_val[2];
00095   uint32_t bitmap_create[2];
00096   uint32_t bitmap_getattr_res[2];
00097   fattr4 input_attr;
00098   bitmap4 convert_bitmap;
00099   component4 name;
00100   char nameval[MAXNAMLEN];
00101   char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];
00102   fsal_status_t fsal_status;
00103   proxyfsal_file_t fd;
00104   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00105 
00106 #define FSAL_CREATE_NB_OP_ALLOC 4
00107 #define FSAL_CREATE_VAL_BUFFER  1024
00108 
00109   fsal_proxy_internal_fattr_t fattr_internal;
00110   fsal_attrib_list_t create_mode_attr;
00111   fsal_attrib_list_t attributes;
00112   nfs_argop4 argoparray[FSAL_CREATE_NB_OP_ALLOC];
00113   nfs_resop4 resoparray[FSAL_CREATE_NB_OP_ALLOC];
00114   struct timeval timeout = TIMEOUTRPC;
00115   char owner_val[FSAL_PROXY_OWNER_LEN];
00116   unsigned int owner_len = 0;
00117 
00118   /* sanity checks.
00119    * note : object_attributes is optional.
00120    */
00121   if(!parent_directory_handle || !p_context || !object_handle || !p_filename)
00122     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);
00123 
00124   PRINT_HANDLE("FSAL_create", parent_directory_handle);
00125 
00126   /* Create the owner */
00127   snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu",
00128            getpid(), p_context, (unsigned long long int)p_context->file_counter);
00129   owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN);
00130   p_context->file_counter += 1;
00131 
00132   /* Setup results structures */
00133   argnfs4.argarray.argarray_val = argoparray;
00134   resnfs4.resarray.resarray_val = resoparray;
00135   argnfs4.minorversion = 0;
00136   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Mkdir" ; */
00137   argnfs4.tag.utf8string_val = NULL;
00138   argnfs4.tag.utf8string_len = 0;
00139   argnfs4.argarray.argarray_len = 0;
00140 
00141   fsal_internal_proxy_setup_fattr(&fattr_internal);
00142 
00143   convert_bitmap.bitmap4_val = bitmap_conv_val;
00144   convert_bitmap.bitmap4_len = 2;
00145 
00146   memset((char *)&name, 0, sizeof(component4));
00147   name.utf8string_val = nameval;
00148   name.utf8string_len = sizeof(nameval);
00149   if(fsal_internal_proxy_fsal_name_2_utf8(p_filename, &name) == FALSE)
00150     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);
00151 
00152   /* Get NFSv4 File handle */
00153   if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE)
00154     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);
00155 
00156   if(isFullDebug(COMPONENT_FSAL))
00157     {
00158       char outstr[1024];
00159 
00160       nfs4_sprint_fhandle(&nfs4fh, outstr);
00161       LogFullDebug(COMPONENT_FSAL, "FSAL_CREATE: extracted server (as client) parent handle=%s\n",
00162                    outstr);
00163     }
00164 
00165   bitmap.bitmap4_val = bitmap_create;
00166   bitmap.bitmap4_len = 2;
00167   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00168 
00169   create_mode_attr.asked_attributes = FSAL_ATTR_MODE;
00170   create_mode_attr.mode = accessmode;
00171   fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap);
00172 
00173   if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
00174                             &create_mode_attr, &input_attr, NULL,       /* no compound data required here */
00175                             NULL,       /* No fh here, filehandle is not a settable attribute */
00176                             &convert_bitmap) == -1)
00177     Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_create);
00178 
00179 #define FSAL_CREATE_IDX_OP_PUTFH       0
00180 #define FSAL_CREATE_IDX_OP_OPEN_CREATE 1
00181 #define FSAL_CREATE_IDX_OP_GETFH       2
00182 #define FSAL_CREATE_IDX_OP_GETATTR     3
00183   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00184   COMPOUNDV4_ARG_ADD_OP_OPEN_CREATE(argnfs4, name, input_attr, p_context->clientid,
00185                                     owner_val, owner_len);
00186   COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
00187   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00188 
00189   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
00190       OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res;
00191   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
00192       OPEN4res_u.resok4.attrset.bitmap4_len = 2;
00193 
00194   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00195       GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
00196   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00197       GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
00198 
00199   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00200       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
00201   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00202       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00203 
00204   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00205       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00206       (char *)&fattr_internal;
00207   resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00208       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00209       sizeof(fattr_internal);
00210 
00211   TakeTokenFSCall();
00212 
00213   /* Call the NFSv4 function */
00214   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00215   nfs4_Fattr_Free(&input_attr);
00216   if(rc != RPC_SUCCESS)
00217     {
00218       ReleaseTokenFSCall();
00219 
00220       Return(ERR_FSAL_IO, rc, INDEX_FSAL_create);
00221     }
00222 
00223   ReleaseTokenFSCall();
00224 
00225   /* >> convert error code, and return on error << */
00226   if(resnfs4.status != NFS4_OK)
00227     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_create);
00228 
00229   /* Use NFSv4 service function to build the FSAL_attr */
00230   if(nfs4_Fattr_To_FSAL_attr(&attributes,
00231                              &resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].
00232                              nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
00233                              obj_attributes) != NFS4_OK)
00234     {
00235       FSAL_CLEAR_MASK(attributes.asked_attributes);
00236       FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);
00237 
00238       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_create);
00239 
00240     }
00241 
00242   /* Return attributes if asked */
00243   if(object_attributes)
00244     {
00245       memcpy(object_attributes, &attributes, sizeof(attributes));
00246     }
00247 
00248   if(isFullDebug(COMPONENT_FSAL))
00249     {
00250       char outstr[1024];
00251 
00252       nfs4_sprint_fhandle(&nfs4fh, outstr);
00253       LogFullDebug(COMPONENT_FSAL, "FSAL_CREATE: extracted server (as client) created file handle=%s\n",
00254            outstr);
00255     }
00256 
00257   if(fsal_internal_proxy_create_fh
00258      (&
00259       (resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00260        GETFH4res_u.resok4.object), FSAL_TYPE_FILE, attributes.fileid,
00261       object_handle) == FALSE)
00262     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);
00263 
00264   /* Keep the information into the file descriptor as well */
00265   memcpy((char *)&fd.fhandle, (char *)object_handle, sizeof(fd.fhandle));
00266 
00267   fd.openflags = FSAL_O_RDWR;
00268   fd.current_offset = 0;
00269   fd.pcontext = p_context;
00270 
00271   /* Keep the returned stateid for later use */
00272   fd.stateid.seqid =
00273       resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
00274       OPEN4res_u.resok4.stateid.seqid;
00275   memcpy((char *)fd.stateid.other,
00276          resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.
00277          opopen.OPEN4res_u.resok4.stateid.other, 12);
00278 
00279   /* See if a OPEN_CONFIRM is required */
00280   if(resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
00281      OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM)
00282     {
00283       fsal_status = FSAL_proxy_open_confirm(&fd);
00284       if(FSAL_IS_ERROR(fsal_status))
00285         Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_create);
00286     }
00287 
00288   /* The created file is still opened, to preserve the correct seqid for later use, we close it */
00289   fsal_status = FSAL_close((fsal_file_t *) &fd);
00290   if(FSAL_IS_ERROR(fsal_status))
00291     Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_create);
00292 
00293   /* OK */
00294   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_create);
00295 }                               /* FSAL_create */
00296 
00334 fsal_status_t PROXYFSAL_mkdir(fsal_handle_t * parent_directory_handle,     /* IN */
00335                               fsal_name_t * p_dirname,  /* IN */
00336                               fsal_op_context_t *context,       /* IN */
00337                               fsal_accessmode_t accessmode,     /* IN */
00338                               fsal_handle_t * object_handle,       /* OUT */
00339                               fsal_attrib_list_t * object_attributes    /* [ IN/OUT ] */
00340     )
00341 {
00342 
00343   int rc;
00344 
00345   COMPOUND4args argnfs4;
00346   COMPOUND4res resnfs4;
00347   nfs_fh4 nfs4fh;
00348   bitmap4 bitmap;
00349   uint32_t bitmap_res[2];
00350   uint32_t bitmap_mkdir[2];
00351   uint32_t bitmap_getattr_res[2];
00352   uint32_t bitmap_conv_val[2];
00353   fattr4 input_attr;
00354   bitmap4 convert_bitmap;
00355   component4 name;
00356   char nameval[MAXNAMLEN];
00357   char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];
00358   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00359 
00360   fsal_proxy_internal_fattr_t fattr_internal;
00361   fsal_attrib_list_t create_mode_attr;
00362   fsal_attrib_list_t attributes;
00363 
00364 #define FSAL_MKDIR_NB_OP_ALLOC 4
00365 #define FSAL_MKDIR_VAL_BUFFER  1024
00366 
00367   nfs_argop4 argoparray[FSAL_MKDIR_NB_OP_ALLOC];
00368   nfs_resop4 resoparray[FSAL_MKDIR_NB_OP_ALLOC];
00369 
00370   struct timeval timeout = TIMEOUTRPC;
00371 
00372   /* sanity checks.
00373    * note : object_attributes is optional.
00374    */
00375   if(!parent_directory_handle || !p_context || !object_handle || !p_dirname)
00376     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir);
00377 
00378   PRINT_HANDLE("FSAL_mkdir", parent_directory_handle);
00379 
00380   /* Setup results structures */
00381   argnfs4.argarray.argarray_val = argoparray;
00382   resnfs4.resarray.resarray_val = resoparray;
00383   argnfs4.minorversion = 0;
00384   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Mkdir" ; */
00385   argnfs4.tag.utf8string_val = NULL;
00386   argnfs4.tag.utf8string_len = 0;
00387   argnfs4.argarray.argarray_len = 0;
00388 
00389   fsal_internal_proxy_setup_fattr(&fattr_internal);
00390 
00391   convert_bitmap.bitmap4_val = bitmap_conv_val;
00392   convert_bitmap.bitmap4_len = 2;
00393 
00394   memset((char *)&name, 0, sizeof(component4));
00395   name.utf8string_val = nameval;
00396   name.utf8string_len = sizeof(nameval);
00397   if(fsal_internal_proxy_fsal_name_2_utf8(p_dirname, &name) == FALSE)
00398     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir);
00399 
00400   /* Get NFSv4 File handle */
00401   if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE)
00402     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir);
00403 
00404   bitmap.bitmap4_val = bitmap_mkdir;
00405   bitmap.bitmap4_len = 2;
00406   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00407 
00408   create_mode_attr.asked_attributes = FSAL_ATTR_MODE;
00409   create_mode_attr.mode = accessmode;
00410   fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap);
00411 
00412   if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
00413                             &create_mode_attr, &input_attr, NULL,       /* no compound data required here */
00414                             NULL,       /* No fh here, filehandle is not a settable attribute */
00415                             &convert_bitmap) == -1)
00416     Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_mkdir);
00417 
00418 #define FSAL_MKDIR_IDX_OP_PUTFH     0
00419 #define FSAL_MKDIR_IDX_OP_MKDIR     1
00420 #define FSAL_MKDIR_IDX_OP_GETFH     2
00421 #define FSAL_MKDIR_IDX_OP_GETATTR   3
00422   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
00423   COMPOUNDV4_ARG_ADD_OP_MKDIR(argnfs4, name, input_attr);
00424   COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
00425   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00426 
00427   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_MKDIR].nfs_resop4_u.opcreate.
00428       CREATE4res_u.resok4.attrset.bitmap4_val = bitmap_res;
00429   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_MKDIR].nfs_resop4_u.opcreate.
00430       CREATE4res_u.resok4.attrset.bitmap4_len = 2;
00431 
00432   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETFH].nfs_resop4_u.opgetfh.GETFH4res_u.
00433       resok4.object.nfs_fh4_val = (char *)padfilehandle;
00434   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETFH].nfs_resop4_u.opgetfh.GETFH4res_u.
00435       resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
00436 
00437   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00438       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
00439   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00440       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00441 
00442   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00443       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00444       (char *)&fattr_internal;
00445   resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00446       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00447       sizeof(fattr_internal);
00448 
00449   TakeTokenFSCall();
00450 
00451   /* Call the NFSv4 function */
00452   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00453   nfs4_Fattr_Free(&input_attr);
00454   if(rc != RPC_SUCCESS)
00455     {
00456       ReleaseTokenFSCall();
00457 
00458       Return(ERR_FSAL_IO, 0, INDEX_FSAL_mkdir);
00459     }
00460 
00461   ReleaseTokenFSCall();
00462 
00463   /* >> convert error code, and return on error << */
00464   if(resnfs4.status != NFS4_OK)
00465     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_mkdir);
00466 
00467   /* Use NFSv4 service function to build the FSAL_attr */
00468   if(nfs4_Fattr_To_FSAL_attr(&attributes,
00469                              &resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETATTR].
00470                              nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
00471                              obj_attributes) != NFS4_OK)
00472     {
00473       FSAL_CLEAR_MASK(attributes.asked_attributes);
00474       FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);
00475 
00476       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_mkdir);
00477 
00478     }
00479 
00480   if(object_attributes)
00481     {
00482       memcpy(object_attributes, &attributes, sizeof(attributes));
00483     }
00484 
00485   if(fsal_internal_proxy_create_fh
00486      (&
00487       (resnfs4.resarray.resarray_val[FSAL_MKDIR_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
00488        GETFH4res_u.resok4.object), FSAL_TYPE_DIR, attributes.fileid,
00489       object_handle) == FALSE)
00490     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir);
00491 
00492   PRINT_HANDLE("FSAL_mkdir new obj", object_handle);
00493 
00494   /* OK */
00495   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mkdir);
00496 
00497 }
00498 
00536 fsal_status_t PROXYFSAL_link(fsal_handle_t * target_handle,        /* IN */
00537                              fsal_handle_t * dir_handle,   /* IN */
00538                              fsal_name_t * p_link_name, /* IN */
00539                              fsal_op_context_t *context,        /* IN */
00540                              fsal_attrib_list_t * attributes    /* [ IN/OUT ] */
00541     )
00542 {
00543   int rc;
00544 
00545   COMPOUND4args argnfs4;
00546   COMPOUND4res resnfs4;
00547   nfs_fh4 nfs4fh_target;
00548   nfs_fh4 nfs4fh_dest;
00549   bitmap4 bitmap;
00550   uint32_t bitmap_val[2];
00551   uint32_t bitmap_res[2];
00552   component4 name;
00553   char nameval[MAXNAMLEN];
00554   proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;
00555 
00556   fsal_proxy_internal_fattr_t fattr_internal;
00557 
00558   struct timeval timeout = TIMEOUTRPC;
00559 
00560   /* sanity checks.
00561    * note : attributes is optional.
00562    */
00563   if(!target_handle || !dir_handle || !p_context || !p_link_name)
00564     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);
00565 
00566   /* Tests if hardlinking is allowed by configuration. */
00567 
00568   if(!global_fs_info.link_support)
00569     Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_link);
00570 
00571 #define FSAL_LINK_NB_OP_ALLOC 6
00572   nfs_argop4 argoparray[FSAL_LINK_NB_OP_ALLOC];
00573   nfs_resop4 resoparray[FSAL_LINK_NB_OP_ALLOC];
00574 
00575   /* Setup results structures */
00576   argnfs4.argarray.argarray_val = argoparray;
00577   resnfs4.resarray.resarray_val = resoparray;
00578   fsal_internal_proxy_setup_fattr(&fattr_internal);
00579   argnfs4.minorversion = 0;
00580   /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Link" ; */
00581   argnfs4.tag.utf8string_val = NULL;
00582   argnfs4.tag.utf8string_len = 0;
00583   argnfs4.argarray.argarray_len = 0;
00584 
00585   bitmap.bitmap4_val = bitmap_val;
00586   bitmap.bitmap4_len = 2;
00587   fsal_internal_proxy_create_fattr_bitmap(&bitmap);
00588 
00589   if(fsal_internal_proxy_extract_fh(&nfs4fh_target, target_handle) == FALSE)
00590     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);
00591 
00592   if(fsal_internal_proxy_extract_fh(&nfs4fh_dest, dir_handle) == FALSE)
00593     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);
00594 
00595   memset((char *)&name, 0, sizeof(component4));
00596   name.utf8string_val = nameval;
00597   name.utf8string_len = sizeof(nameval);
00598   if(fsal_internal_proxy_fsal_name_2_utf8(p_link_name, &name) == FALSE)
00599     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);
00600 
00601 #define FSAL_LINK_IDX_OP_PUTFH_TARGET 0
00602 #define FSAL_LINK_IDX_OP_SAVEFH       1
00603 #define FSAL_LINK_IDX_OP_PUTFH_DEST   2
00604 #define FSAL_LINK_IDX_OP_LINK         3
00605 #define FSAL_LINK_IDX_OP_RESTOREFH    4
00606 #define FSAL_LINK_IDX_OP_GETATTR      5
00607   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_target);
00608   COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4);
00609   COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_dest);
00610   COMPOUNDV4_ARG_ADD_OP_LINK(argnfs4, name);
00611   COMPOUNDV4_ARG_ADD_OP_RESTOREFH(argnfs4);
00612   COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
00613 
00614   resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00615       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
00616   resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00617       GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;
00618 
00619   resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00620       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
00621       (char *)&fattr_internal;
00622   resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
00623       GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
00624       sizeof(fattr_internal);
00625 
00626   TakeTokenFSCall();
00627 
00628   /* Call the NFSv4 function */
00629   COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
00630   if(rc != RPC_SUCCESS)
00631     {
00632       ReleaseTokenFSCall();
00633 
00634       Return(ERR_FSAL_IO, rc, INDEX_FSAL_link);
00635     }
00636 
00637   ReleaseTokenFSCall();
00638 
00639   if(resnfs4.status != NFS4_OK)
00640     return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_link);
00641 
00642   if(attributes)
00643     {
00644       /* Use NFSv4 service function to build the FSAL_attr */
00645       if(nfs4_Fattr_To_FSAL_attr(attributes,
00646                                  &resnfs4.resarray.
00647                                  resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.
00648                                  opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
00649         {
00650           FSAL_CLEAR_MASK(attributes->asked_attributes);
00651           FSAL_SET_MASK(attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00652 
00653           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_link);
00654         }
00655     }
00656 
00657   /* OK */
00658   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link);
00659 
00660 }
00661 
00669 fsal_status_t PROXYFSAL_mknode(fsal_handle_t * parentdir_handle,   /* IN */
00670                                fsal_name_t * p_node_name,       /* IN */
00671                                fsal_op_context_t * p_context,      /* IN */
00672                                fsal_accessmode_t accessmode,    /* IN */
00673                                fsal_nodetype_t nodetype,        /* IN */
00674                                fsal_dev_t * dev,        /* IN */
00675                                fsal_handle_t * p_object_handle,    /* OUT (handle to the created node) */
00676                                fsal_attrib_list_t * node_attributes     /* [ IN/OUT ] */
00677     )
00678 {
00679 
00680   /* sanity checks.
00681    * note : link_attributes is optional.
00682    */
00683   if(!parentdir_handle || !p_context || !nodetype || !dev || !p_node_name)
00684     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);
00685 
00686   /* Not implemented */
00687   Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_mknode);
00688 
00689 }