nfs-ganesha 1.4

fsal_rcp.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=4:tabstop=4:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #include "fsal.h"
00019 #include "fsal_internal.h"
00020 #include "fsal_convert.h"
00021 #include <string.h>
00022 #include <fcntl.h>
00023 #include "abstract_mem.h"
00024 
00052 fsal_status_t GPFSFSAL_rcp(fsal_handle_t * filehandle,      /* IN */
00053                        fsal_op_context_t * p_context,   /* IN */
00054                        fsal_path_t * p_local_path,      /* IN */
00055                        fsal_rcpflag_t transfer_opt      /* IN */
00056     )
00057 {
00058 
00059   int local_fd;
00060   int local_flags;
00061   int errsv;
00062 
00063   fsal_file_t fs_fd;
00064   fsal_openflags_t fs_flags;
00065 
00066   fsal_status_t st = FSAL_STATUS_NO_ERROR;
00067 
00068   /* default buffer size for RCP: 10MB */
00069 #define RCP_BUFFER_SIZE 10485760
00070   caddr_t IObuffer;
00071 
00072   int to_local = FALSE;
00073   int to_fs = FALSE;
00074 
00075   int eof = FALSE;
00076 
00077   ssize_t local_size;
00078   fsal_size_t fs_size;
00079 
00080   /* sanity checks. */
00081 
00082   if(!filehandle || !p_context || !p_local_path)
00083     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rcp);
00084 
00085   to_local = ((transfer_opt & FSAL_RCP_FS_TO_LOCAL) == FSAL_RCP_FS_TO_LOCAL);
00086   to_fs = ((transfer_opt & FSAL_RCP_LOCAL_TO_FS) == FSAL_RCP_LOCAL_TO_FS);
00087 
00088   if(to_local)
00089     LogFullDebug(COMPONENT_FSAL,
00090                  "FSAL_rcp: FSAL -> local file (%s)", p_local_path->path);
00091 
00092   if(to_fs)
00093     LogFullDebug(COMPONENT_FSAL,
00094                  "FSAL_rcp: local file -> FSAL (%s)", p_local_path->path);
00095 
00096   /* must give the sens of transfert (exactly one) */
00097 
00098   if((!to_local && !to_fs) || (to_local && to_fs))
00099     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp);
00100 
00101   /* first, open local file with the correct flags */
00102 
00103   if(to_fs)
00104     {
00105       local_flags = O_RDONLY;
00106     }
00107   else
00108     {
00109       local_flags = O_WRONLY | O_TRUNC;
00110 
00111       if((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT)
00112         local_flags |= O_CREAT;
00113 
00114       if((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL)
00115         local_flags |= O_EXCL;
00116 
00117     }
00118 
00119   if(isFullDebug(COMPONENT_FSAL))
00120     {
00121       char msg[1024];
00122 
00123       msg[0] = '\0';
00124 
00125       if((local_flags & O_RDONLY) == O_RDONLY)
00126         strcat(msg, "O_RDONLY ");
00127 
00128       if((local_flags & O_WRONLY) == O_WRONLY)
00129         strcat(msg, "O_WRONLY ");
00130 
00131       if((local_flags & O_TRUNC) == O_TRUNC)
00132         strcat(msg, "O_TRUNC ");
00133 
00134       if((local_flags & O_CREAT) == O_CREAT)
00135         strcat(msg, "O_CREAT ");
00136 
00137       if((local_flags & O_EXCL) == O_EXCL)
00138         strcat(msg, "O_EXCL ");
00139 
00140       LogFullDebug(COMPONENT_FSAL, "Openning local file %s with flags: %s",
00141                    p_local_path->path, msg);
00142     }
00143 
00144   local_fd = open(p_local_path->path, local_flags);
00145   errsv = errno;
00146 
00147   if(local_fd == -1)
00148     {
00149       Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_rcp);
00150     }
00151 
00152   /* call FSAL_open with the correct flags */
00153 
00154   if(to_fs)
00155     {
00156       fs_flags = FSAL_O_WRONLY | FSAL_O_TRUNC;
00157 
00158       /* invalid flags for local to filesystem */
00159 
00160       if(((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT)
00161          || ((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL))
00162         {
00163           /* clean & return */
00164           close(local_fd);
00165           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp);
00166         }
00167     }
00168   else
00169     {
00170       fs_flags = FSAL_O_RDONLY;
00171     }
00172 
00173   if(isFullDebug(COMPONENT_FSAL))
00174     {
00175       char msg[1024];
00176 
00177       msg[0] = '\0';
00178 
00179       if((fs_flags & FSAL_O_RDONLY) == FSAL_O_RDONLY)
00180         strcat(msg, "FSAL_O_RDONLY ");
00181 
00182       if((fs_flags & FSAL_O_WRONLY) == FSAL_O_WRONLY)
00183         strcat(msg, "FSAL_O_WRONLY ");
00184 
00185       if((fs_flags & FSAL_O_TRUNC) == FSAL_O_TRUNC)
00186         strcat(msg, "FSAL_O_TRUNC ");
00187 
00188       LogFullDebug(COMPONENT_FSAL, "Openning FSAL file with flags: %s", msg);
00189     }
00190 
00191 
00192   st = FSAL_open(filehandle, p_context, fs_flags, &fs_fd, NULL);
00193 
00194   if(FSAL_IS_ERROR(st))
00195     {
00196       /* clean & return */
00197       close(local_fd);
00198       Return(st.major, st.minor, INDEX_FSAL_rcp);
00199     }
00200   LogFullDebug(COMPONENT_FSAL,
00201                "Allocating IO buffer of size %llu",
00202                (unsigned long long)RCP_BUFFER_SIZE);
00203 
00204   /* Allocates buffer */
00205 
00206   IObuffer = gsh_malloc(RCP_BUFFER_SIZE);
00207 
00208   if(IObuffer == NULL)
00209     {
00210       /* clean & return */
00211       close(local_fd);
00212       FSAL_close(&fs_fd);
00213       Return(ERR_FSAL_NOMEM, ENOMEM, INDEX_FSAL_rcp);
00214     }
00215 
00216   /* read/write loop */
00217 
00218   while(!eof)
00219     {
00220       /* initialize error code */
00221       st = FSAL_STATUS_NO_ERROR;
00222 
00223       LogFullDebug(COMPONENT_FSAL, "Read a block from source");
00224 
00225       /* read */
00226 
00227       if(to_fs)                 /* from local filesystem */
00228         {
00229           LogFullDebug(COMPONENT_FSAL,
00230                        "Read a block from local file system");
00231           local_size = read(local_fd, IObuffer, RCP_BUFFER_SIZE);
00232 
00233           if(local_size == -1)
00234             {
00235               st.major = ERR_FSAL_IO;
00236               st.minor = errno;
00237               break;            /* exit loop */
00238             }
00239 
00240           eof = (local_size == 0);
00241           if(!eof)
00242             {
00243               LogFullDebug(COMPONENT_FSAL,
00244                            "Write a block (%llu bytes) to FSAL",
00245                             (unsigned long long)local_size);
00246 
00247               st = FSAL_write(&fs_fd, p_context, NULL, local_size, IObuffer, &fs_size);
00248               if(FSAL_IS_ERROR(st))
00249                 {
00250                   LogFullDebug(COMPONENT_FSAL,
00251                                "Error writing to FSAL");
00252                   break;          /* exit loop */
00253                 }
00254             }
00255           else
00256             {
00257               LogFullDebug(COMPONENT_FSAL,
00258                            "End of file on local file system");
00259             }
00260         }
00261       else                      /* from FSAL filesystem */
00262         {
00263           LogFullDebug(COMPONENT_FSAL,
00264                        "Read a block from FSAL");
00265           fs_size = 0;
00266           st = FSAL_read(&fs_fd, NULL, RCP_BUFFER_SIZE, IObuffer, &fs_size, &eof);
00267 
00268           if(FSAL_IS_ERROR(st))
00269             break;              /* exit loop */
00270 
00271           if(fs_size > 0)
00272             {
00273               LogFullDebug(COMPONENT_FSAL,
00274                            "Write a block (%llu bytes) to local file system",
00275                             (unsigned long long)fs_size);
00276 
00277               local_size = write(local_fd, IObuffer, fs_size);
00278 
00279               if(local_size == -1)
00280                 {
00281                   st.major = ERR_FSAL_IO;
00282                   st.minor = errno;
00283                   break;        /* exit loop */
00284                 }
00285             }
00286           else
00287             {
00288               LogFullDebug(COMPONENT_FSAL,
00289                            "End of file on FSAL");
00290               break;
00291             }
00292 
00293           LogFullDebug(COMPONENT_FSAL, "Size read from source: %llu",
00294                        (unsigned long long)fs_size);
00295         }
00296     }                           /* while !eof */
00297 
00298   /* Clean */
00299 
00300   gsh_free(IObuffer);
00301   close(local_fd);
00302   FSAL_close(&fs_fd);
00303 
00304   /* return status. */
00305 
00306   Return(st.major, st.minor, INDEX_FSAL_rcp);
00307 
00308 }