fsal_posixdb_status_t fsal_posixdb_buildOnePath(fsal_posixdb_conn * p_conn,
                                                posixfsal_handle_t * p_handle,
                                                fsal_path_t * p_path)
{
  PGresult *p_res;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  unsigned int shift;
  char *new_pos;
  int toomanypaths = 0;
  const char *paramValues[2] = { handleid_str, handlets_str };

  if(!p_conn || !p_handle || !p_path)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }

  /* init values */
  memset(p_path, 0, sizeof(fsal_path_t));

  /* Nothing to do, it's the root path */
  if(p_handle->data.id == 0 && p_handle->data.ts == 0)
    ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);

  /* check if the entry is in the cache */
  if(fsal_posixdb_GetPathCache(p_handle, p_path))
    ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);

  snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_handle->data.id);
  snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_handle->data.ts);

  /* with PL/PGSQL */
#ifdef _WITH_PLPGSQL
  p_res = PQexecPrepared(p_conn, "buildOnePathPL", 2, paramValues, NULL, NULL, 0);
  CheckResult(p_res);

  p_path->len = strlen(PQgetvalue(p_res, 0, 0));

  if(p_path->len >= FSAL_MAX_PATH_LEN)
    {
      PQclear(p_res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
    }

  strcpy(p_path->path, PQgetvalue(p_res, 0, 0));
  PQclear(p_res);

  /* set result in cache */
  fsal_posixdb_CachePath(p_handle, p_path);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);

#else
  /* without PL/PGSQL */
  while(handleid_str[0] != '\0')
    {
      p_res = PQexecPrepared(p_conn, "buildOnePath", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);

      if(PQntuples(p_res) == 0)
        {
          PQclear(p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);        /* not found */
        }

      if(PQntuples(p_res) > 1)
        {
          LogCrit(COMPONENT_FSAL, "Too many paths found for object %s.%s: found=%d, expected=1",
                  handleid_str, handlets_str, PQntuples(p_res));

          toomanypaths++;       /* too many entries */
        }

      if(!strncmp(handleid_str, PQgetvalue(p_res, 0, 1), MAX_HANDLEIDSTR_SIZE)
         && !strncmp(handlets_str, PQgetvalue(p_res, 0, 2), MAX_HANDLETSSTR_SIZE))
        {
          PQclear(p_res);
          break;                  /* handle is equal to its parent handle (root reached) */
        }
      strncpy(handleid_str, PQgetvalue(p_res, 0, 1), MAX_HANDLEIDSTR_SIZE);
      strncpy(handlets_str, PQgetvalue(p_res, 0, 2), MAX_HANDLETSSTR_SIZE);

      /* insertion of the name at the beginning of the path */
      shift = strlen(PQgetvalue(p_res, 0, 0));
      if(p_path->len + shift >= FSAL_MAX_PATH_LEN)
        {
          PQclear(p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
        }
      new_pos = p_path->path + shift;
      memmove(new_pos, p_path->path, p_path->len);
      memcpy(p_path->path, PQgetvalue(p_res, 0, 0), shift);
      p_path->len += shift;

      PQclear(p_res);
    }

  if(toomanypaths)
    {
      LogCrit(COMPONENT_FSAL, "Returned path: %s", p_path->path);
      ReturnCodeDB(ERR_FSAL_POSIXDB_TOOMANYPATHS, toomanypaths);        /* too many entries */
    }
  else
    {
      /* set result in cache */
      fsal_posixdb_CachePath(p_handle, p_path);

      ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
    }
#endif
}
Example #2
0
fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn,        /* IN */
                                                     posixfsal_handle_t * p_object_handle,      /* IN/OUT */
                                                     fsal_path_t * p_paths,     /* OUT */
                                                     int paths_size,    /* IN */
                                                     int *p_count /* OUT */ )
{
  fsal_posixdb_status_t st;
  result_handle_t res;
  MYSQL_ROW row;
  posixfsal_handle_t parent_directory_handle;
  int i_path;
  int toomanypaths = 0;
  char query[2048];

  /* sanity check */
  if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0))
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }
  LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id);

  BeginTransaction(p_conn);

  /* lookup for the handle of the file */

  if(!fsal_posixdb_GetInodeCache(p_object_handle))
    {

      snprintf(query, 2048,
               "SELECT Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
               "FROM Handle WHERE handleid=%llu AND handlets=%u", p_object_handle->data.id,
               p_object_handle->data.ts);

      st = db_exec_sql(p_conn, query, &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;

      /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */

      LogDebug(COMPONENT_FSAL, "lookupHandle(%llu,%u)", p_object_handle->data.id,
                 (unsigned int)p_object_handle->data.ts);
      if((mysql_num_rows(res) != 1) || ((row = mysql_fetch_row(res)) == NULL))
        {
          LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", mysql_num_rows(res));
          mysql_free_result(res);
          RollbackTransaction(p_conn);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
        }

      posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info),
                                                 row[0], row[1], row[2], row[3], row[4]);
      mysql_free_result(res);

      /* update the inode */
      fsal_posixdb_UpdateInodeCache(p_object_handle);
    }

  /* Build the paths of the object */
  if(p_paths)
    {
      /* find all the paths to the object */

      snprintf(query, 2048, "SELECT name, handleidparent, handletsparent "
               "FROM Parent WHERE handleid=%llu AND handlets=%u",
               p_object_handle->data.id, p_object_handle->data.ts);

      st = db_exec_sql(p_conn, query, &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;

      /* res contains name, handleidparent, handletsparent */
      *p_count = mysql_num_rows(res);
      if(*p_count == 0)
        {
          mysql_free_result(res);
          RollbackTransaction(p_conn);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0);
        }
      else if(*p_count > paths_size)
        {
          toomanypaths = 1;

          LogCrit(COMPONENT_FSAL, "Too many paths found for object %llu.%u: found=%u, max=%d",
                     p_object_handle->data.id, p_object_handle->data.ts, *p_count, paths_size);

          *p_count = paths_size;
        }

      for(i_path = 0; i_path < *p_count; i_path++)
        {
          unsigned int tmp_len;

          row = mysql_fetch_row(res);
          if(row == NULL)
            {
              mysql_free_result(res);
              RollbackTransaction(p_conn);
              ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
            }

          /* build the path of the parent directory */
          parent_directory_handle.data.id = atoll(row[1]);
          parent_directory_handle.data.ts = atoi(row[2]);

          st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle,
                                         &p_paths[i_path]);
          if(FSAL_POSIXDB_IS_ERROR(st))
            goto free_res;

          tmp_len = p_paths[i_path].len;

          if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/'))
            {
              /* then concatenate the name of the file */
              /* but not concatenate '/' */
              if((tmp_len + strlen(row[0]) >= FSAL_MAX_PATH_LEN))
                {
                  mysql_free_result(res);
                  RollbackTransaction(p_conn);
                  ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
                }
              strcpy(&p_paths[i_path].path[tmp_len], row[0]);
              p_paths[i_path].len += strlen(row[0]);

            }
          else
            {
              /* then concatenate the name of the file */
              if((tmp_len + 1 + strlen(row[0]) >= FSAL_MAX_PATH_LEN))
                {
                  mysql_free_result(res);
                  RollbackTransaction(p_conn);
                  ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
                }
              p_paths[i_path].path[tmp_len] = '/';
              strcpy(&p_paths[i_path].path[tmp_len + 1], row[0]);
              p_paths[i_path].len += 1 + strlen(row[0]);
            }

          /* insert the object into cache */
          fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]);

        }

      mysql_free_result(res);
    }

  st = EndTransaction(p_conn);

  if(toomanypaths)
    ReturnCodeDB(ERR_FSAL_POSIXDB_TOOMANYPATHS, 0);
  else
    return st;

 free_res:
  mysql_free_result(res);
 rollback:
  RollbackTransaction(p_conn);
  return st;
}
Example #3
0
fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn,        /* IN */
                                                     posixfsal_handle_t * p_object_handle,      /* IN/OUT */
                                                     fsal_path_t * p_paths,     /* OUT */
                                                     int paths_size,    /* IN */
                                                     int *p_count /* OUT */ )
{
  PGresult *p_res;
  fsal_posixdb_status_t st;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  posixfsal_handle_t parent_directory_handle;
  int i_path;
  int toomanypaths = 0;
  const char *paramValues[2] = { handleid_str, handlets_str };

  /* sanity check */
  if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0))
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }

  CheckConn(p_conn);

  LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id);

  BeginTransaction(p_conn, p_res);

  /* lookup for the handle of the file */
  snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id);
  snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts);

  if(!fsal_posixdb_GetInodeCache(p_object_handle))
    {

      p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);
      /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */

      LogDebug(COMPONENT_FSAL, "lookupHandle(%u,%u)", (unsigned int)p_object_handle->data.id,
               (unsigned int)p_object_handle->data.ts);

      /* entry not found */
      if(PQntuples(p_res) != 1)
        {
          LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", PQntuples(p_res));
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
        }

      posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), PQgetvalue(p_res, 0, 0), PQgetvalue(p_res, 0, 1), PQgetvalue(p_res, 0, 2),   /* nlink */
                                                 PQgetvalue(p_res, 0, 3),       /* ctime */
                                                 PQgetvalue(p_res, 0, 4)        /* ftype */
          );
      PQclear(p_res);

      /* update the inode */
      fsal_posixdb_UpdateInodeCache(p_object_handle);
    }

  /* Build the paths of the object */
  if(p_paths)
    {
      /* find all the paths to the object */
      p_res = PQexecPrepared(p_conn, "lookupPaths", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);
      /* p_res contains name, handleidparent, handletsparent */
      *p_count = PQntuples(p_res);
      if(*p_count == 0)
        {
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0);
        }
      if(*p_count > paths_size)
        {
          toomanypaths = 1;

          LogCrit(COMPONENT_FSAL, "Too many paths found for object %s.%s: found=%u, max=%d",
                  handleid_str, handlets_str, *p_count, paths_size);

          *p_count = paths_size;
        }

      for(i_path = 0; i_path < *p_count; i_path++)
        {
          unsigned int tmp_len;

          /* build the path of the parent directory */
          parent_directory_handle.data.id = atoll(PQgetvalue(p_res, i_path, 1));
          parent_directory_handle.data.ts = atoi(PQgetvalue(p_res, i_path, 2));

          st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle,
                                         &p_paths[i_path]);
          if(st.major != ERR_FSAL_POSIXDB_NOERR)
            {
              RollbackTransaction(p_conn, p_res);
              return st;
            }

          tmp_len = p_paths[i_path].len;

          if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/'))
            {
              /* then concatenate the name of the file */
              /* but not concatenate '/' */
              if((tmp_len + strlen(PQgetvalue(p_res, i_path, 0)) >= FSAL_MAX_PATH_LEN))
                {
                  RollbackTransaction(p_conn, p_res);
                  ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
                }
              strcpy(&p_paths[i_path].path[tmp_len], PQgetvalue(p_res, i_path, 0));
              p_paths[i_path].len += strlen(PQgetvalue(p_res, i_path, 0));

            }
          else
            {
              /* then concatenate the name of the file */
              if((tmp_len + 1 + strlen(PQgetvalue(p_res, i_path, 0)) >=
                  FSAL_MAX_PATH_LEN))
                {
                  RollbackTransaction(p_conn, p_res);
                  ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
                }
              p_paths[i_path].path[tmp_len] = '/';
              strcpy(&p_paths[i_path].path[tmp_len + 1], PQgetvalue(p_res, i_path, 0));
              p_paths[i_path].len += 1 + strlen(PQgetvalue(p_res, i_path, 0));
            }

          /* insert the object into cache */
          fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]);

        }
      PQclear(p_res);
    }

  EndTransaction(p_conn, p_res);

  ReturnCodeDB(toomanypaths ? ERR_FSAL_POSIXDB_TOOMANYPATHS : ERR_FSAL_POSIXDB_NOERR, 0);
}
Example #4
0
fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn,  /* IN */
                                                   posixfsal_handle_t * p_parent_directory_handle,      /* IN/OUT */
                                                   fsal_name_t * p_objectname,  /* IN */
                                                   fsal_path_t * p_path,        /* OUT */
                                                   posixfsal_handle_t *
                                                   p_handle /* OUT */ )
{
  fsal_posixdb_status_t st;
  char query[2048];
  result_handle_t res;
  MYSQL_ROW row;

  /* sanity check */
  if(!p_conn || !p_handle)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }
  LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name ? p_objectname->name : "/");

  BeginTransaction(p_conn);
  /* lookup for the handle of the file */
  if(p_parent_directory_handle && p_parent_directory_handle->data.id)
    {
      snprintf(query, 2048,
               "SELECT Parent.handleid, Parent.handlets, Handle.deviceid, "
               "Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
               "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid AND Parent.handlets=Handle.handlets "
               "WHERE handleidparent=%llu AND handletsparent=%u AND name='%s'",
               p_parent_directory_handle->data.id,
               p_parent_directory_handle->data.ts, p_objectname->name);

      st = db_exec_sql(p_conn, query, &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;
    }
  else
    {
      /* get root handle: */

      st = db_exec_sql(p_conn,
                       "SELECT Parent.handleid, Parent.handlets, Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
                       "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid AND Parent.handlets=Handle.handlets "
                       "WHERE Parent.handleidparent=Parent.handleid AND Parent.handletsparent=Parent.handlets",
                       &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;
    }
  /* res contains : Parent.handleid, Parent.handlets, Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */

  /* entry not found */
  if((mysql_num_rows(res) != 1) || ((row = mysql_fetch_row(res)) == NULL))
    {
      mysql_free_result(res);
      RollbackTransaction(p_conn);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }

  p_handle->data.id = atoll(row[0]);
  p_handle->data.ts = atoi(row[1]);
  posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), row[2], row[3], /* devid, inode */
                                             row[4],    /* nlink */
                                             row[5],    /* ctime */
                                             row[6]);   /* ftype */
  mysql_free_result(res);

  /* Build the path of the object */
  if(p_path && p_objectname)
    {
      /* build the path of the Parent */
      st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;

      /* then concatenate the filename */
      if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN))
        {
          RollbackTransaction(p_conn);
          ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
        }
      p_path->path[p_path->len] = '/';
      strcpy(&p_path->path[p_path->len + 1], p_objectname->name);
      p_path->len += 1 + p_objectname->len;

      /* add the the path to cache */
      fsal_posixdb_CachePath(p_handle, p_path);
    }
  else
    {
      /* update handle if it was in cache */
      fsal_posixdb_UpdateInodeCache(p_handle);
    }

  return EndTransaction(p_conn);

 rollback:
  RollbackTransaction(p_conn);
  return st;
}
Example #5
0
fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn,  /* IN */
                                                   posixfsal_handle_t * p_parent_directory_handle,      /* IN/OUT */
                                                   fsal_name_t * p_objectname,  /* IN */
                                                   fsal_path_t * p_path,        /* OUT */
                                                   posixfsal_handle_t *
                                                   p_handle /* OUT */ )
{
  PGresult *p_res;
  fsal_posixdb_status_t st;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  const char *paramValues[3] = { handleid_str, handlets_str, p_objectname->name };

  /* sanity check */
  if(!p_conn || !p_handle)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }

  CheckConn(p_conn);

  LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name);

  BeginTransaction(p_conn, p_res);
  /* lookup for the handle of the file */
  if(p_parent_directory_handle && p_parent_directory_handle->data.id)
    {
      snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_parent_directory_handle->data.id);
      snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_parent_directory_handle->data.ts);
      p_res = PQexecPrepared(p_conn, "lookupHandleByName", 3, paramValues, NULL, NULL, 0);
      CheckResult(p_res);
    }
  else
    {
      // get root handle :
      p_res = PQexecPrepared(p_conn, "lookupRootHandle", 0, NULL, NULL, NULL, 0);
      CheckResult(p_res);
    }
  /* p_res contains : Parent.handleid, Parent.handlets, Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */

  /* entry not found */
  if(PQntuples(p_res) != 1)
    {
      PQclear(p_res);
      RollbackTransaction(p_conn, p_res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }

  p_handle->data.id = atoll(PQgetvalue(p_res, 0, 0));
  p_handle->data.ts = atoi(PQgetvalue(p_res, 0, 1));
  posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), PQgetvalue(p_res, 0, 2), PQgetvalue(p_res, 0, 3), PQgetvalue(p_res, 0, 4),      /* nlink */
                                             PQgetvalue(p_res, 0, 5),   /* ctime */
                                             PQgetvalue(p_res, 0, 6)    /* ftype */
      );
  PQclear(p_res);

  /* Build the path of the object */
  if(p_path && p_objectname)
    {
      /* build the path of the Parent */
      st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path);
      if(st.major != ERR_FSAL_POSIXDB_NOERR)
        {
          RollbackTransaction(p_conn, p_res);
          return st;
        }

      /* then concatenate the filename */
      if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN))
        {
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
        }
      p_path->path[p_path->len] = '/';
      strcpy(&p_path->path[p_path->len + 1], p_objectname->name);
      p_path->len += 1 + p_objectname->len;

      /* add the the path to cache */
      fsal_posixdb_CachePath(p_handle, p_path);
    }
  else
    {
      /* update handle if it was in cache */
      fsal_posixdb_UpdateInodeCache(p_handle);
    }

  EndTransaction(p_conn, p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}