nfs-ganesha 1.4

nfs4_referral.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  * 
00023  * ---------------------------------------
00024  */
00025 
00036 #ifdef HAVE_CONFIG_H
00037 #include "config.h"
00038 #endif
00039 
00040 #ifdef _SOLARIS
00041 #include "solaris_port.h"
00042 #endif
00043 
00044 #include <stdio.h>
00045 #include <string.h>
00046 #include <pthread.h>
00047 #include <fcntl.h>
00048 #include <sys/file.h>           /* for having FNDELAY */
00049 #include "HashData.h"
00050 #include "HashTable.h"
00051 #include "log.h"
00052 #include "ganesha_rpc.h"
00053 #include "nfs4.h"
00054 #include "nfs_core.h"
00055 #include "nfs_proto_functions.h"
00056 #include "nfs_tools.h"
00057 #include "nfs_exports.h"
00058 #include "nfs_file_handle.h"
00059 #include "cache_inode.h"
00060 
00061 int nfs4_Set_Fh_Referral(nfs_fh4 * pfh)
00062 {
00063   file_handle_v4_t *pfhandle4;
00064 
00065   if(pfh == NULL)
00066     return 0;
00067 
00068   pfhandle4 = (file_handle_v4_t *) (pfh->nfs_fh4_val);
00069 
00070   pfhandle4->refid = 1;
00071 
00072   return 1;
00073 }
00074 
00075 int nfs4_referral_str_To_Fattr_fs_location(char *input_str, char *buff, u_int *plen)
00076 {
00077   char str[MAXPATHLEN];
00078   char local_part[MAXPATHLEN];
00079   char *local_comp[MAXNAMLEN];
00080   char remote_part[MAXPATHLEN];
00081   char *remote_comp[MAXNAMLEN];
00082   char server_part[MAXPATHLEN];
00083 
00084   u_int nb_comp_local = 1;
00085   u_int nb_comp_remote = 1;
00086   u_int lastoff = 0;
00087   u_int tmp_int = 0;
00088   u_int i = 0;
00089   u_int delta_xdr = 0;
00090 
00091   char *ptr = NULL;
00092 
00093   if(!plen || !buff || !input_str)
00094     return 0;
00095 
00096   strncpy(str, input_str, MAXPATHLEN);
00097 
00098   /* Find the ":" in the string */
00099   for(ptr = str; *ptr != ':'; ptr++) ;
00100   *ptr = '\0';
00101   ptr += 1;
00102 
00103   memset( local_part, 0, MAXPATHLEN ) ;
00104   strncpy(local_part, str, MAXPATHLEN);
00105 
00106   memset( remote_part, 0, MAXPATHLEN ) ;
00107   strncpy(remote_part, ptr, MAXPATHLEN);
00108 
00109   /* Each part should not start with a leading slash */
00110   if(local_part[0] == '/')
00111     strncpy(local_part, str + 1, MAXPATHLEN);
00112 
00113   if(remote_part[0] == '/')
00114     strncpy(remote_part, ptr + 1, MAXPATHLEN);
00115 
00116   /* Find the "@" in the remote_part */
00117   for(ptr = remote_part; *ptr != '@'; ptr++) ;
00118   *ptr = '\0';
00119   ptr += 1;
00120 
00121   memset( server_part, 0 , MAXPATHLEN ) ;
00122   strncpy(server_part, ptr, MAXPATHLEN);
00123 
00124   local_comp[0] = local_part;
00125   for(ptr = local_part; *ptr != '\0'; ptr++)
00126     if(*ptr == '/')
00127       {
00128         local_comp[nb_comp_local] = ptr + 1;
00129         nb_comp_local += 1;
00130       }
00131   for(tmp_int = 0; tmp_int < nb_comp_local; tmp_int++)
00132     {
00133       ptr = local_comp[tmp_int] - 1;
00134       *ptr = '\0';
00135     }
00136 
00137   remote_comp[0] = remote_part;
00138   for(ptr = remote_part; *ptr != '\0'; ptr++)
00139     if(*ptr == '/')
00140       {
00141         remote_comp[nb_comp_remote] = ptr + 1;
00142         nb_comp_remote += 1;
00143       }
00144   for(tmp_int = 0; tmp_int < nb_comp_remote; tmp_int++)
00145     {
00146       ptr = remote_comp[tmp_int] - 1;
00147       *ptr = '\0';
00148     }
00149 
00150   /* This attributes is equivalent to a "mount" command line,
00151    * To understand what's follow, imagine that you do kind of "mount refer@server nfs_ref" */
00152 
00153   LogFullDebug(COMPONENT_NFS_V4_REFERRAL, "--> %s", input_str);
00154 
00155   LogFullDebug(COMPONENT_NFS_V4_REFERRAL, "   %u comp local", nb_comp_local);
00156   for(tmp_int = 0; tmp_int < nb_comp_local; tmp_int++)
00157     LogFullDebug(COMPONENT_NFS_V4_REFERRAL, "     #%s#", local_comp[tmp_int]);
00158 
00159   LogFullDebug(COMPONENT_NFS_V4_REFERRAL, "   %u comp remote", nb_comp_remote);
00160   for(tmp_int = 0; tmp_int < nb_comp_remote; tmp_int++)
00161     LogFullDebug(COMPONENT_NFS_V4_REFERRAL, "     #%s#", remote_comp[tmp_int]);
00162 
00163   LogFullDebug(COMPONENT_NFS_V4_REFERRAL, "   server = #%s#", server_part);
00164 
00165   /* 1- Number of component in local path */
00166   tmp_int = htonl(nb_comp_local);
00167   memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00168   lastoff += sizeof(u_int);
00169 
00170   /* 2- each component in local path */
00171   for(i = 0; i < nb_comp_local; i++)
00172     {
00173       /* The length for the string */
00174       tmp_int = htonl(strlen(local_comp[i]));
00175       memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00176       lastoff += sizeof(u_int);
00177 
00178       /* the string itself */
00179       memcpy((char *)(buff + lastoff), local_comp[i], strlen(local_comp[i]));
00180       lastoff += strlen(local_comp[i]);
00181 
00182       /* The XDR padding  : strings must be aligned to 32bits fields */
00183       if((strlen(local_comp[i]) % 4) == 0)
00184         delta_xdr = 0;
00185       else
00186         {
00187           delta_xdr = 4 - (strlen(local_comp[i]) % 4);
00188           memset((char *)(buff + lastoff), 0, delta_xdr);
00189           lastoff += delta_xdr;
00190         }
00191     }
00192 
00193   /* 3- there is only one fs_location in the fs_locations array */
00194   tmp_int = htonl(1);
00195   memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00196   lastoff += sizeof(u_int);
00197 
00198   /* 4- Only ine server in fs_location entry */
00199   tmp_int = htonl(1);
00200   memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00201   lastoff += sizeof(u_int);
00202 
00203   /* 5- the len for the server's adress */
00204   tmp_int = htonl(strlen(server_part));
00205   memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00206   lastoff += sizeof(u_int);
00207 
00208   /* 6- the server's string */
00209   memcpy((char *)(buff + lastoff), server_part, strlen(server_part));
00210   lastoff += strlen(server_part);
00211 
00212   /* 7- XDR padding for server's string */
00213   if((strlen(server_part) % 4) == 0)
00214     delta_xdr = 0;
00215   else
00216     {
00217       delta_xdr = 4 - (strlen(server_part) % 4);
00218       memset((char *)(buff + lastoff), 0, delta_xdr);
00219       lastoff += delta_xdr;
00220     }
00221 
00222   /* 8- Number of component in remote path */
00223   tmp_int = htonl(nb_comp_remote);
00224   memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00225   lastoff += sizeof(u_int);
00226 
00227   /* 9- each component in local path */
00228   for(i = 0; i < nb_comp_remote; i++)
00229     {
00230       /* The length for the string */
00231       tmp_int = htonl(strlen(remote_comp[i]));
00232       memcpy((char *)(buff + lastoff), &tmp_int, sizeof(u_int));
00233       lastoff += sizeof(u_int);
00234 
00235       /* the string itself */
00236       memcpy((char *)(buff + lastoff), remote_comp[i], strlen(remote_comp[i]));
00237       lastoff += strlen(remote_comp[i]);
00238 
00239       /* The XDR padding  : strings must be aligned to 32bits fields */
00240       if((strlen(remote_comp[i]) % 4) == 0)
00241         delta_xdr = 0;
00242       else
00243         {
00244           delta_xdr = 4 - (strlen(remote_comp[i]) % 4);
00245           memset((char *)(buff + lastoff), 0, delta_xdr);
00246           lastoff += delta_xdr;
00247         }
00248     }
00249 
00250   /* Set the len then return */
00251   *plen = lastoff;
00252 
00253   return 1;
00254 }                               /* nfs4_referral_str_To_Fattr_fs_location */