nfs-ganesha 1.4

posixdb_info.c

Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 #include <string.h>
00005 #include "posixdb_internal.h"
00006 
00007 fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn,  /* IN */
00008                                                    posixfsal_handle_t * p_parent_directory_handle,      /* IN/OUT */
00009                                                    fsal_name_t * p_objectname,  /* IN */
00010                                                    fsal_path_t * p_path,        /* OUT */
00011                                                    posixfsal_handle_t *
00012                                                    p_handle /* OUT */ )
00013 {
00014   PGresult *p_res;
00015   fsal_posixdb_status_t st;
00016   char handleid_str[MAX_HANDLEIDSTR_SIZE];
00017   char handlets_str[MAX_HANDLETSSTR_SIZE];
00018   const char *paramValues[3] = { handleid_str, handlets_str, p_objectname->name };
00019 
00020   /* sanity check */
00021   if(!p_conn || !p_handle)
00022     {
00023       ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
00024     }
00025 
00026   CheckConn(p_conn);
00027 
00028   LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name);
00029 
00030   BeginTransaction(p_conn, p_res);
00031   /* lookup for the handle of the file */
00032   if(p_parent_directory_handle && p_parent_directory_handle->data.id)
00033     {
00034       snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_parent_directory_handle->data.id);
00035       snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_parent_directory_handle->data.ts);
00036       p_res = PQexecPrepared(p_conn, "lookupHandleByName", 3, paramValues, NULL, NULL, 0);
00037       CheckResult(p_res);
00038     }
00039   else
00040     {
00041       // get root handle :
00042       p_res = PQexecPrepared(p_conn, "lookupRootHandle", 0, NULL, NULL, NULL, 0);
00043       CheckResult(p_res);
00044     }
00045   /* p_res contains : Parent.handleid, Parent.handlets, Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */
00046 
00047   /* entry not found */
00048   if(PQntuples(p_res) != 1)
00049     {
00050       PQclear(p_res);
00051       RollbackTransaction(p_conn, p_res);
00052       ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
00053     }
00054 
00055   p_handle->data.id = atoll(PQgetvalue(p_res, 0, 0));
00056   p_handle->data.ts = atoi(PQgetvalue(p_res, 0, 1));
00057   posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), PQgetvalue(p_res, 0, 2), PQgetvalue(p_res, 0, 3), PQgetvalue(p_res, 0, 4),      /* nlink */
00058                                              PQgetvalue(p_res, 0, 5),   /* ctime */
00059                                              PQgetvalue(p_res, 0, 6)    /* ftype */
00060       );
00061   PQclear(p_res);
00062 
00063   /* Build the path of the object */
00064   if(p_path && p_objectname)
00065     {
00066       /* build the path of the Parent */
00067       st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path);
00068       if(st.major != ERR_FSAL_POSIXDB_NOERR)
00069         {
00070           RollbackTransaction(p_conn, p_res);
00071           return st;
00072         }
00073 
00074       /* then concatenate the filename */
00075       if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN))
00076         {
00077           RollbackTransaction(p_conn, p_res);
00078           ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
00079         }
00080       p_path->path[p_path->len] = '/';
00081       strcpy(&p_path->path[p_path->len + 1], p_objectname->name);
00082       p_path->len += 1 + p_objectname->len;
00083 
00084       /* add the the path to cache */
00085       fsal_posixdb_CachePath(p_handle, p_path);
00086     }
00087   else
00088     {
00089       /* update handle if it was in cache */
00090       fsal_posixdb_UpdateInodeCache(p_handle);
00091     }
00092 
00093   EndTransaction(p_conn, p_res);
00094 
00095   ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
00096 }
00097 
00098 fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn,        /* IN */
00099                                                      posixfsal_handle_t * p_object_handle,      /* IN/OUT */
00100                                                      fsal_path_t * p_paths,     /* OUT */
00101                                                      int paths_size,    /* IN */
00102                                                      int *p_count /* OUT */ )
00103 {
00104   PGresult *p_res;
00105   fsal_posixdb_status_t st;
00106   char handleid_str[MAX_HANDLEIDSTR_SIZE];
00107   char handlets_str[MAX_HANDLETSSTR_SIZE];
00108   posixfsal_handle_t parent_directory_handle;
00109   int i_path;
00110   int toomanypaths = 0;
00111   const char *paramValues[2] = { handleid_str, handlets_str };
00112 
00113   /* sanity check */
00114   if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0))
00115     {
00116       ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
00117     }
00118 
00119   CheckConn(p_conn);
00120 
00121   LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id);
00122 
00123   BeginTransaction(p_conn, p_res);
00124 
00125   /* lookup for the handle of the file */
00126   snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id);
00127   snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts);
00128 
00129   if(!fsal_posixdb_GetInodeCache(p_object_handle))
00130     {
00131 
00132       p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0);
00133       CheckResult(p_res);
00134       /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */
00135 
00136       LogDebug(COMPONENT_FSAL, "lookupHandle(%u,%u)", (unsigned int)p_object_handle->data.id,
00137                (unsigned int)p_object_handle->data.ts);
00138 
00139       /* entry not found */
00140       if(PQntuples(p_res) != 1)
00141         {
00142           LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", PQntuples(p_res));
00143           RollbackTransaction(p_conn, p_res);
00144           ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
00145         }
00146 
00147       posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), PQgetvalue(p_res, 0, 0), PQgetvalue(p_res, 0, 1), PQgetvalue(p_res, 0, 2),   /* nlink */
00148                                                  PQgetvalue(p_res, 0, 3),       /* ctime */
00149                                                  PQgetvalue(p_res, 0, 4)        /* ftype */
00150           );
00151       PQclear(p_res);
00152 
00153       /* update the inode */
00154       fsal_posixdb_UpdateInodeCache(p_object_handle);
00155     }
00156 
00157   /* Build the paths of the object */
00158   if(p_paths)
00159     {
00160       /* find all the paths to the object */
00161       p_res = PQexecPrepared(p_conn, "lookupPaths", 2, paramValues, NULL, NULL, 0);
00162       CheckResult(p_res);
00163       /* p_res contains name, handleidparent, handletsparent */
00164       *p_count = PQntuples(p_res);
00165       if(*p_count == 0)
00166         {
00167           RollbackTransaction(p_conn, p_res);
00168           ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0);
00169         }
00170       if(*p_count > paths_size)
00171         {
00172           toomanypaths = 1;
00173 
00174           LogCrit(COMPONENT_FSAL, "Too many paths found for object %s.%s: found=%u, max=%d",
00175                   handleid_str, handlets_str, *p_count, paths_size);
00176 
00177           *p_count = paths_size;
00178         }
00179 
00180       for(i_path = 0; i_path < *p_count; i_path++)
00181         {
00182           unsigned int tmp_len;
00183 
00184           /* build the path of the parent directory */
00185           parent_directory_handle.data.id = atoll(PQgetvalue(p_res, i_path, 1));
00186           parent_directory_handle.data.ts = atoi(PQgetvalue(p_res, i_path, 2));
00187 
00188           st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle,
00189                                          &p_paths[i_path]);
00190           if(st.major != ERR_FSAL_POSIXDB_NOERR)
00191             {
00192               RollbackTransaction(p_conn, p_res);
00193               return st;
00194             }
00195 
00196           tmp_len = p_paths[i_path].len;
00197 
00198           if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/'))
00199             {
00200               /* then concatenate the name of the file */
00201               /* but not concatenate '/' */
00202               if((tmp_len + strlen(PQgetvalue(p_res, i_path, 0)) >= FSAL_MAX_PATH_LEN))
00203                 {
00204                   RollbackTransaction(p_conn, p_res);
00205                   ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
00206                 }
00207               strcpy(&p_paths[i_path].path[tmp_len], PQgetvalue(p_res, i_path, 0));
00208               p_paths[i_path].len += strlen(PQgetvalue(p_res, i_path, 0));
00209 
00210             }
00211           else
00212             {
00213               /* then concatenate the name of the file */
00214               if((tmp_len + 1 + strlen(PQgetvalue(p_res, i_path, 0)) >=
00215                   FSAL_MAX_PATH_LEN))
00216                 {
00217                   RollbackTransaction(p_conn, p_res);
00218                   ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
00219                 }
00220               p_paths[i_path].path[tmp_len] = '/';
00221               strcpy(&p_paths[i_path].path[tmp_len + 1], PQgetvalue(p_res, i_path, 0));
00222               p_paths[i_path].len += 1 + strlen(PQgetvalue(p_res, i_path, 0));
00223             }
00224 
00225           /* insert the object into cache */
00226           fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]);
00227 
00228         }
00229       PQclear(p_res);
00230     }
00231 
00232   EndTransaction(p_conn, p_res);
00233 
00234   ReturnCodeDB(toomanypaths ? ERR_FSAL_POSIXDB_TOOMANYPATHS : ERR_FSAL_POSIXDB_NOERR, 0);
00235 }
00236 
00237 fsal_posixdb_status_t fsal_posixdb_getParentDirHandle(fsal_posixdb_conn * p_conn,       /* IN */
00238                                                       posixfsal_handle_t * p_object_handle,     /* IN */
00239                                                       posixfsal_handle_t * p_parent_directory_handle    /* OUT */
00240     )
00241 {
00242   PGresult *p_res;
00243   char handleid_str[MAX_HANDLEIDSTR_SIZE];
00244   char handlets_str[MAX_HANDLETSSTR_SIZE];
00245   const char *paramValues[2] = { handleid_str, handlets_str };
00246 
00247   /* sanity check */
00248   if(!p_conn || !p_parent_directory_handle || !p_object_handle)
00249 
00250     CheckConn(p_conn);
00251 
00252   /* no need to start a transaction, there is anly one query */
00253   snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id);
00254   snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts);
00255   p_res = PQexecPrepared(p_conn, "lookupPathsExt", 2, paramValues, NULL, NULL, 0);
00256   CheckResult(p_res);
00257 
00258   /* entry not found */
00259   if(!PQntuples(p_res))
00260     {
00261       PQclear(p_res);
00262       ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
00263     }
00264   LogDebug(COMPONENT_FSAL, "lookupPathsExt");
00265 
00266   p_parent_directory_handle->data.id = atoll(PQgetvalue(p_res, 0, 1));
00267   p_parent_directory_handle->data.ts = atoi(PQgetvalue(p_res, 0, 2));
00268   posixdb_internal_fillFileinfoFromStrValues(&(p_parent_directory_handle->data.info), PQgetvalue(p_res, 0, 3), PQgetvalue(p_res, 0, 4), PQgetvalue(p_res, 0, 5),     /* nlink */
00269                                              PQgetvalue(p_res, 0, 6),   /* ctime */
00270                                              PQgetvalue(p_res, 0, 7)    /* ftype */
00271       );
00272 
00273   PQclear(p_res);
00274 
00275   ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
00276 }