nfs-ganesha 1.4

posixdb_info.c

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