nfs-ganesha 1.4

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