Ejemplo n.º 1
0
fsal_posixdb_status_t fsal_posixdb_deleteParent(fsal_posixdb_conn * p_conn,     /* IN */
                                                char *handleid_str,     /* IN */
                                                char *handlets_str,     /* IN */
                                                char *handleidparent_str,       /* IN */
                                                char *handletsparent_str,       /* IN */
                                                char *filename, /* IN */
                                                int nlink)      /* IN */
{
  PGresult *p_res;
  char nlink_str[MAX_NLINKSTR_SIZE];
  const char *paramValues[3];

  /* Sanity check */
  if(!p_conn || !filename || nlink < 1)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }

  /* delete the Parent entry */
  paramValues[0] = handleidparent_str;
  paramValues[1] = handletsparent_str;
  paramValues[2] = filename;

  /* invalidate name cache */
  fsal_posixdb_InvalidateCache();

  p_res = PQexecPrepared(p_conn, "deleteParent", 3, paramValues, NULL, NULL, 0);
  CheckCommand(p_res);

  /* delete the handle or update it */
  if(nlink == 1)
    {
      /* delete the handle */
      /* If there are other entries in the Parent table with this Handle, they will be deleted (thanks to foreign keys) */
      paramValues[0] = handleid_str;
      paramValues[1] = handlets_str;

      /* invalidate cache */
      fsal_posixdb_InvalidateCache();

      p_res = PQexecPrepared(p_conn, "deleteHandle", 2, paramValues, NULL, NULL, 0);
      CheckCommand(p_res);
    }
  else
    {
      /* update the Handle entry ( Handle.nlink <- (nlink - 1) ) */
      paramValues[0] = handleid_str;
      paramValues[1] = handlets_str;
      snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", nlink - 1);
      paramValues[2] = nlink_str;

      /* invalidate cache */
      fsal_posixdb_InvalidateCache();

      p_res = PQexecPrepared(p_conn, "updateHandleNlink", 3, paramValues, NULL, NULL, 0);
      CheckCommand(p_res);
    }

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 2
0
fsal_posixdb_status_t fsal_posixdb_delete(fsal_posixdb_conn * p_conn,   /* IN */
                                          posixfsal_handle_t * p_parent_directory_handle,       /* IN */
                                          fsal_name_t * p_filename,     /* IN */
                                          fsal_posixdb_fileinfo_t *
                                          p_object_info /* IN */ )
{
  result_handle_t res;
  fsal_posixdb_status_t st;
  char query[2048];

    /*******************
     * 1/ sanity check *
     *******************/

  if(!p_conn || !p_parent_directory_handle || !p_filename)
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  BeginTransaction(p_conn);

    /*******************************
     * 2/ we check the file exists *
     *******************************/

  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' "
           "FOR UPDATE", p_parent_directory_handle->data.id,
           p_parent_directory_handle->data.ts, p_filename->name);

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

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

    /***********************************************
     * 3/ Get information about the file to delete *
     ***********************************************/

  st = fsal_posixdb_internal_delete(p_conn, p_parent_directory_handle->data.id,
                                    p_parent_directory_handle->data.ts,
                                    p_filename->name, p_object_info);
  if(FSAL_POSIXDB_IS_ERROR(st))
    goto rollback;

  return EndTransaction(p_conn);

 rollback:
  RollbackTransaction(p_conn);
  return st;
}
Ejemplo n.º 3
0
fsal_posixdb_status_t fsal_posixdb_getParentDirHandle(fsal_posixdb_conn * p_conn,       /* IN */
                                                      posixfsal_handle_t * p_object_handle,     /* IN */
                                                      posixfsal_handle_t * p_parent_directory_handle    /* OUT */
    )
{
  fsal_posixdb_status_t st;
  MYSQL_ROW row;
  result_handle_t res;
  char query[2048];

  /* sanity check */
  if(!p_conn || !p_parent_directory_handle || !p_object_handle)
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  /* no need to start a transaction, there is only one query */

  snprintf(query, 2048,
           "SELECT Parent.name, Parent.handleidparent, Parent.handletsparent, "
           "Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
           "FROM Parent LEFT JOIN Handle ON Parent.handleidparent = Handle.handleid AND Parent.handletsparent=Handle.handlets "
           "WHERE Parent.handleid=%llu AND Parent.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))
    return st;

  /* entry not found */
  if(mysql_num_rows(res) == 0)
    {
      mysql_free_result(res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }

  row = mysql_fetch_row(res);
  if(row == NULL)
    {
      mysql_free_result(res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }
  LogDebug(COMPONENT_FSAL, "lookupPathsExt");

  p_parent_directory_handle->data.id = atoll(row[1]);
  p_parent_directory_handle->data.ts = atoi(row[2]);
  posixdb_internal_fillFileinfoFromStrValues(&(p_parent_directory_handle->data.info), row[3],
                                             row[4], row[5], row[6], row[7]);

  mysql_free_result(res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 4
0
/** 
 * @brief Lock the line of the Handle table with inode & devid defined in p_info
 * 
 * @param p_conn
 *        Database connection
 * @param p_info 
 *        Information about the file
 * 
 * @return ERR_FSAL_POSIXDB_NOERR if no error,
 *         another error code else.
 */
fsal_posixdb_status_t fsal_posixdb_lockHandleForUpdate(fsal_posixdb_conn * p_conn,      /* IN */
                                                       fsal_posixdb_fileinfo_t *
                                                       p_info /* IN */ )
{
  result_handle_t res;
  fsal_posixdb_status_t st;
  char query[2048];

  BeginTransaction(p_conn);

  snprintf(query, 2048, "SELECT handleid, handlets, nlink, ctime, ftype "
           "FROM Handle WHERE deviceid=%llu AND inode=%llu "
           "FOR UPDATE", (unsigned long long)p_info->devid, (unsigned long long)p_info->inode);

  st = db_exec_sql(p_conn, query, &res);
  if(FSAL_POSIXDB_IS_ERROR(st))
    {
      RollbackTransaction(p_conn);
      return st;
    }

  mysql_free_result(res);

  /* Do not end the transaction, because it will be closed by the next call to a posixdb function */

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 5
0
/** 
 * @brief Lock the line of the Handle table with inode & devid defined in p_info
 * 
 * @param p_conn
 *        Database connection
 * @param p_info 
 *        Information about the file
 * 
 * @return ERR_FSAL_POSIXDB_NOERR if no error,
 *         another error code else.
 */
fsal_posixdb_status_t fsal_posixdb_lockHandleForUpdate(fsal_posixdb_conn * p_conn,      /* IN */
                                                       fsal_posixdb_fileinfo_t *
                                                       p_info /* IN */ )
{
  PGresult *p_res;
  char devid_str[MAX_DEVICEIDSTR_SIZE];
  char inode_str[MAX_INODESTR_SIZE];
  const char *paramValues[2];

  CheckConn(p_conn);

  BeginTransaction(p_conn, p_res);

  snprintf(devid_str, MAX_DEVICEIDSTR_SIZE, "%lli", (long long int)p_info->devid);
  snprintf(inode_str, MAX_INODESTR_SIZE, "%lli", (long long int)p_info->inode);
  paramValues[0] = devid_str;
  paramValues[1] = inode_str;
  p_res = PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0);
  CheckResult(p_res);
  PQclear(p_res);

  /* Do not end the transaction, because it will be closed by the next call to a posixdb function */

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 6
0
fsal_posixdb_status_t posixdb_internal_fillFileinfoFromStrValues(fsal_posixdb_fileinfo_t *
                                                                 p_info, char *devid_str,
                                                                 char *inode_str,
                                                                 char *nlink_str,
                                                                 char *ctime_str,
                                                                 char *ftype_str)
{

  if(!p_info)
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  p_info->devid = devid_str ? (dev_t) atoll(devid_str) : 0;
  p_info->inode = inode_str ? (ino_t) atoll(inode_str) : 0;
  p_info->nlink = nlink_str ? atoi(nlink_str) : 0;
  p_info->ctime = ctime_str ? (time_t) atoi(ctime_str) : 0;
  p_info->ftype = ftype_str ? (fsal_nodetype_t) atoi(ftype_str) : 0;

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 7
0
/** 
 * @brief Unlock the Handle line previously locked by fsal_posixdb_lockHandleForUpdate
 * 
 * @param p_conn
 *        Database connection
 * 
 * @return ERR_FSAL_POSIXDB_NOERR if no error,
 *         another error code else.
 */
fsal_posixdb_status_t fsal_posixdb_cancelHandleLock(fsal_posixdb_conn * p_conn /* IN */ )
{
  PGresult *p_res;
  PGTransactionStatusType transStatus = PQtransactionStatus(p_conn);

  if(transStatus == PQTRANS_ACTIVE || transStatus == PQTRANS_INTRANS)
    {
      RollbackTransaction(p_conn, p_res);
    }

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 8
0
fsal_posixdb_status_t fsal_posixdb_getParentDirHandle(fsal_posixdb_conn * p_conn,       /* IN */
                                                      posixfsal_handle_t * p_object_handle,     /* IN */
                                                      posixfsal_handle_t * p_parent_directory_handle    /* OUT */
    )
{
  PGresult *p_res;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  const char *paramValues[2] = { handleid_str, handlets_str };

  /* sanity check */
  if(!p_conn || !p_parent_directory_handle || !p_object_handle)

    CheckConn(p_conn);

  /* no need to start a transaction, there is anly one query */
  snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id);
  snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts);
  p_res = PQexecPrepared(p_conn, "lookupPathsExt", 2, paramValues, NULL, NULL, 0);
  CheckResult(p_res);

  /* entry not found */
  if(!PQntuples(p_res))
    {
      PQclear(p_res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }
  LogDebug(COMPONENT_FSAL, "lookupPathsExt");

  p_parent_directory_handle->data.id = atoll(PQgetvalue(p_res, 0, 1));
  p_parent_directory_handle->data.ts = atoi(PQgetvalue(p_res, 0, 2));
  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 */
                                             PQgetvalue(p_res, 0, 6),   /* ctime */
                                             PQgetvalue(p_res, 0, 7)    /* ftype */
      );

  PQclear(p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 9
0
fsal_posixdb_status_t fsal_posixdb_flush(fsal_posixdb_conn * p_conn)
{
  PGresult *p_res;

  p_res = PQexec(p_conn, "DELETE FROM Parent");
  CheckCommand(p_res);
  PQclear(p_res);

  p_res = PQexec(p_conn, "DELETE FROM Handle");
  CheckCommand(p_res);
  PQclear(p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
fsal_posixdb_status_t fsal_posixdb_internal_delete(fsal_posixdb_conn * p_conn,  /* IN */
                                                   char *handleidparent_str,    /* IN */
                                                   char *handletsparent_str,    /* IN */
                                                   char *filename,      /* IN */
                                                   fsal_posixdb_fileinfo_t *
                                                   p_object_info /* IN */ )
{

  PGresult *p_res;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  fsal_posixdb_status_t st;
  fsal_posixdb_fileinfo_t infodb;
  const char *paramValues[3];

  if(!p_conn || !handleidparent_str || !handletsparent_str || !filename)
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  paramValues[0] = handleidparent_str;
  paramValues[1] = handletsparent_str;
  paramValues[2] = filename;
  p_res = PQexecPrepared(p_conn, "lookupHandleByNameFU", 3, paramValues, NULL, NULL, 0);
  CheckResult(p_res);
  /* p_res contains : handleid, handlets, deviceId, inode, nlink, ctime, ftype  */

  /* no entry found */
  if(PQntuples(p_res) != 1)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }

  strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
  strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);

  /* consistency check */
  /* fill 'infodb' with information about the handle in the database */
  posixdb_internal_fillFileinfoFromStrValues(&infodb, PQgetvalue(p_res, 0, 2),  /* no need to compare inode & devid, they are the same */
                                             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);

  if(p_object_info && fsal_posixdb_consistency_check(&infodb, p_object_info))
    {
      /* not consistent, the bad handle have to be deleted */
      LogCrit(COMPONENT_FSAL, "Consistency check failed while deleting a Path : Handle deleted");
      infodb.ftype = FSAL_TYPE_DIR;     /* considers that the entry is a directory in order to delete all its Parent entries and its Handle */
    }

  switch (infodb.ftype)
    {
    case FSAL_TYPE_DIR:
      /* directory */
      st = fsal_posixdb_recursiveDelete(p_conn, handleid_str, handlets_str, infodb.ftype);
      break;
    default:
      st = fsal_posixdb_deleteParent(p_conn,
                                     handleid_str,
                                     handlets_str,
                                     handleidparent_str,
                                     handletsparent_str, filename, infodb.nlink);
    }
  return st;
}
Ejemplo n.º 12
0
fsal_posixdb_status_t fsal_posixdb_disconnect(fsal_posixdb_conn * p_conn)
{
    mysql_close(&p_conn->db_conn);
    gsh_free(p_conn);
    ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 13
0
fsal_posixdb_status_t fsal_posixdb_recursiveDelete(fsal_posixdb_conn * p_conn,
                                                   char *handleid_str, char *handlets_str,
                                                   fsal_nodetype_t ftype)
{
  PGresult *p_res;
  fsal_posixdb_status_t st;
  fsal_nodetype_t ftype_tmp;
  unsigned int i;
  unsigned int i_max;
  const char *paramValues[2];

  /* Sanity check */
  if(!p_conn || !handleid_str || !handlets_str)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }

  if(ftype == FSAL_TYPE_DIR)
    {
      /* We find all the children of the directory in order to delete them, and then we delete the current handle */
      paramValues[0] = handleid_str;
      paramValues[1] = handlets_str;
      p_res = PQexecPrepared(p_conn, "lookupChildrenFU", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);
      i_max = (unsigned int)PQntuples(p_res);
      for(i = 0; i < i_max; i++)
        {
          ftype_tmp = (fsal_nodetype_t) atoi(PQgetvalue(p_res, i, 2));
          if(ftype_tmp == FSAL_TYPE_DIR)
            {
              st = fsal_posixdb_recursiveDelete(p_conn, PQgetvalue(p_res, i, 0),
                                                PQgetvalue(p_res, i, 1), ftype_tmp);
            }
          else
            {
              st = fsal_posixdb_deleteParent(p_conn, PQgetvalue(p_res, i, 0),   /* handleidparent */
                                             PQgetvalue(p_res, i, 1),   /* handletsparent */
                                             handleid_str, handlets_str, PQgetvalue(p_res, i, 3),       /* filename */
                                             atoi(PQgetvalue(p_res, i, 4))      /* nlink */
                  );
            }
          if(FSAL_POSIXDB_IS_ERROR(st))
            {
              PQclear(p_res);
              return st;
            }
        }
      PQclear(p_res);
    }

  /* Delete the Handle */
  /* All Parent entries having this handle will be deleted thanks to foreign keys */
  paramValues[0] = handleid_str;
  paramValues[1] = handlets_str;

  /* invalidate name cache */
  fsal_posixdb_InvalidateCache();

  p_res = PQexecPrepared(p_conn, "deleteHandle", 2, paramValues, NULL, NULL, 0);
  CheckCommand(p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 14
0
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
}
Ejemplo n.º 15
0
fsal_posixdb_status_t fsal_posixdb_initPreparedQueries(fsal_posixdb_conn * p_conn)
{
    int rc;
    unsigned int retry = 1;

    static const char *buildonepath_query =
        "SELECT CONCAT('/',name), handleidparent, handletsparent FROM Parent WHERE handleid=? AND handlets=?";

    /* @TODO  retry = lmgr_config.connect_retry_min; */

    /* create prepared statements */

    do
    {
        /* First create the prepared statement */
        p_conn->stmt_tab[BUILDONEPATH] = mysql_stmt_init(&p_conn->db_conn);

        /* retry if connection to server failed */
        if((p_conn->stmt_tab[BUILDONEPATH] == NULL)
                && db_is_retryable(mysql_errno(&p_conn->db_conn)))
        {
            LogCrit(COMPONENT_FSAL, "Connection to database lost in %s()... Retrying in %u sec.",
                    __FUNCTION__, retry);
            sleep(retry);
            retry *= 2;
            /*if ( retry > lmgr_config.connect_retry_max )
               retry = lmgr_config.connect_retry_max; */
        }
        else
            break;

    }
    while(1);

    if(!p_conn->stmt_tab[BUILDONEPATH])
        ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, mysql_errno(&p_conn->db_conn));

    /* another retry loop */
    /* @TODO retry = lmgr_config.connect_retry_min; */
    retry = 1;

    do
    {
        /* prepare the request */
        rc = mysql_stmt_prepare(p_conn->stmt_tab[BUILDONEPATH], buildonepath_query,
                                strlen(buildonepath_query));

        if(rc && db_is_retryable(mysql_stmt_errno(p_conn->stmt_tab[BUILDONEPATH])))
        {
            LogCrit(COMPONENT_FSAL, "Connection to database lost in %s()... Retrying in %u sec.",
                    __FUNCTION__, retry);
            sleep(retry);
            retry *= 2;
            /*if ( retry > lmgr_config.connect_retry_max )
               retry = lmgr_config.connect_retry_max; */

        }
        else
            break;

    }
    while(1);

    if(rc)
    {
        LogCrit(COMPONENT_FSAL, "Failed to create prepared statement: Error: %s (query='%s')",
                mysql_stmt_error(p_conn->stmt_tab[BUILDONEPATH]), buildonepath_query);
        mysql_stmt_close(p_conn->stmt_tab[BUILDONEPATH]);
        ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, rc);
    }

    ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
fsal_posixdb_status_t fsal_posixdb_add(fsal_posixdb_conn * p_conn,      /* IN */
                                       fsal_posixdb_fileinfo_t * p_object_info, /* IN */
                                       posixfsal_handle_t * p_parent_directory_handle,  /* IN */
                                       fsal_name_t * p_filename,        /* IN */
                                       posixfsal_handle_t * p_object_handle /* OUT */ )
{
  PGresult *p_res;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  char handleidparent_str[MAX_HANDLEIDSTR_SIZE];
  char handletsparent_str[MAX_HANDLETSSTR_SIZE];
  char devid_str[MAX_DEVICEIDSTR_SIZE];
  char inode_str[MAX_INODESTR_SIZE];
  int found;
  const char *paramValues[6];
  fsal_posixdb_status_t st;

  /*******************
   * 1/ sanity check *
   *******************/

  /* parent_directory and filename are NULL only if it is the root directory */
  if(!p_conn || !p_object_info || !p_object_handle
     || (p_filename && !p_parent_directory_handle) || (!p_filename
                                                       && p_parent_directory_handle))
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  CheckConn(p_conn);

  LogFullDebug(COMPONENT_FSAL, "adding entry with parentid=%llu, id=%"PRIu64", name=%s\n",
         p_parent_directory_handle ? p_parent_directory_handle->data.id : 0,
         p_object_info ? p_object_info->inode : 0,
         p_filename ? p_filename->name : "NULL");

  BeginTransaction(p_conn, p_res);

  /*********************************
   * 2/ we check the parent handle *
   *********************************/

  if(p_parent_directory_handle)
    {                           /* the root has no parent */
      snprintf(handleidparent_str, MAX_HANDLEIDSTR_SIZE, "%llu",
               p_parent_directory_handle->data.id);
      snprintf(handletsparent_str, MAX_HANDLETSSTR_SIZE, "%i",
               p_parent_directory_handle->data.ts);
      paramValues[0] = handleidparent_str;
      paramValues[1] = handletsparent_str;
      p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);

      if(PQntuples(p_res) != 1)
        {
          /* parent entry not found */
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
        }
      PQclear(p_res);
    }
  /**********************************************************
   * 3/ Check if there is an existing Handle for the object *
   **********************************************************/
  snprintf(devid_str, MAX_DEVICEIDSTR_SIZE, "%llu",
           (unsigned long long int)p_object_info->devid);
  snprintf(inode_str, MAX_INODESTR_SIZE, "%llu",
           (unsigned long long int)p_object_info->inode);
  paramValues[0] = devid_str;
  paramValues[1] = inode_str;
  p_res = PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0);
  CheckResult(p_res);
  found = (PQntuples(p_res) == 1);

  if(found)
    {                           /* a Handle (that matches devid & inode) already exists */
      /* fill 'info' with information about the handle in the database */
      posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), NULL, NULL, PQgetvalue(p_res, 0, 2), /* nlink */
                                                 PQgetvalue(p_res, 0, 3),       /* ctime */
                                                 PQgetvalue(p_res, 0, 4)        /* ftype */
          );
      p_object_handle->data.info.inode = p_object_info->inode;
      p_object_handle->data.info.devid = p_object_info->devid;
      strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
      strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);
      PQclear(p_res);

      p_object_handle->data.id = atoll(handleid_str);
      p_object_handle->data.ts = atoi(handlets_str);

      /* check the consistency of the handle */
      if(fsal_posixdb_consistency_check(&(p_object_handle->data.info), p_object_info))
        {
          /* consistency check failed */
          /* p_object_handle has been filled in order to be able to fix the consistency later */
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_CONSISTENCY, 0);
        }

      /* update nlink & ctime if needed */
      if(p_object_info->nlink != p_object_handle->data.info.nlink
         || p_object_info->ctime != p_object_handle->data.info.ctime)
        {
          char nlink_str[MAX_NLINKSTR_SIZE];
          char ctime_str[MAX_CTIMESTR_SIZE];

          snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", p_object_info->nlink);
          snprintf(ctime_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ctime);
          paramValues[0] = handleid_str;
          paramValues[1] = handlets_str;
          paramValues[2] = nlink_str;
          paramValues[3] = ctime_str;

          p_object_handle->data.info = *p_object_info;

          p_res = PQexecPrepared(p_conn, "updateHandle", 4, paramValues, NULL, NULL, 0);
          CheckCommand(p_res);
        }

      fsal_posixdb_UpdateInodeCache(p_object_handle);

    }
  else
    {                           /* no handle found */
      /* Handle does not exist, add a new Handle entry */
      char nlink_str[MAX_NLINKSTR_SIZE];
      char ctime_str[MAX_CTIMESTR_SIZE];
      char ftype_str[MAX_FTYPESTR_SIZE];
      PQclear(p_res);

      p_object_handle->data.ts = (int)time(NULL);
      p_object_handle->data.info = *p_object_info;
      snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts);
      snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", p_object_info->nlink);
      snprintf(ctime_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ctime);
      snprintf(ftype_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ftype);

      paramValues[0] = devid_str;
      paramValues[1] = inode_str;
      paramValues[2] = handlets_str;
      paramValues[3] = nlink_str;
      paramValues[4] = ctime_str;
      paramValues[5] = ftype_str;

      p_res = PQexecPrepared(p_conn, "insertHandle", 6, paramValues, NULL, NULL, 0);
      CheckCommand(p_res);

      PQclear(p_res);

      p_res =
          PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);

      strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
      strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);
      p_object_handle->data.id = atoll(PQgetvalue(p_res, 0, 0));
      PQclear(p_res);

      /* now, we have the handle id */
      fsal_posixdb_UpdateInodeCache(p_object_handle);

    }

  /************************************************
   * add (or update) an entry in the Parent table *
   ************************************************/
  paramValues[0] = p_parent_directory_handle ? handleidparent_str : handleid_str;
  paramValues[1] = p_parent_directory_handle ? handletsparent_str : handlets_str;
  paramValues[2] = p_filename ? p_filename->name : "";
  p_res = PQexecPrepared(p_conn, "lookupParent", 3, paramValues, NULL, NULL, 0);
  CheckResult(p_res);
  /* p-res contains handleid & handlets */
  found = (PQntuples(p_res) == 1);
  paramValues[3] = handleid_str;
  paramValues[4] = handlets_str;
  if(found)
    {
      /* update the Parent entry if necessary (there entry exists with another handle) */
      if((fsal_u64_t) atoll(PQgetvalue(p_res, 0, 0)) != p_object_handle->data.id
         || atoi(PQgetvalue(p_res, 0, 1)) != p_object_handle->data.ts)
        {
          /* steps :
             - check the nlink value of the Parent entry to be overwritten
             - if nlink = 1, then we can delete the handle.
             else we have to update it (nlink--) : that is done by fsal_posixdb_deleteParent
             - update the handle of the entry
           */
          char bad_handleid_str[MAX_HANDLEIDSTR_SIZE];
          char bad_handlets_str[MAX_HANDLETSSTR_SIZE];
          int nlink;

          strncpy(bad_handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
          strncpy(bad_handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);
          PQclear(p_res);       /* clear old res before a new query */

          /* check the nlink value of the entry to be updated */
          paramValues[0] = handleidparent_str;
          paramValues[1] = handletsparent_str;
          p_res = PQexecPrepared(p_conn, "lookupHandleFU", 2, paramValues, NULL, NULL, 0);
          CheckResult(p_res);

          found = (PQntuples(p_res) == 1);

          if(found)
            {                   /* we have retrieved the handle information of the bad entry */
              nlink = atoi(PQgetvalue(p_res, 0, 4));
              PQclear(p_res);   /* clear old res before a new query */

              /* a Parent entry already exists, we delete it */

              st = fsal_posixdb_deleteParent(p_conn, bad_handleid_str, bad_handlets_str,
                                             p_parent_directory_handle ?
                                             handleidparent_str : handleid_str,
                                             p_parent_directory_handle ?
                                             handletsparent_str : handlets_str,
                                             p_filename ? p_filename->name : "", nlink);
              if(FSAL_POSIXDB_IS_ERROR(st))
                {
                  RollbackTransaction(p_conn, p_res);
                  return st;
                }
            }
          else
            {                   /* the Handle line has been deleted */
              PQclear(p_res);   /* clear old res before a new query */
            }

          /* the bad entry has been deleted. Now we had a new Parent entry */
          goto add_new_parent_entry;

        }
      else
        {
          /* a Parent entry exists with our handle, nothing to do */
          PQclear(p_res);
        }
    }
  else
    {
      /* add a Parent entry */
      PQclear(p_res);
 add_new_parent_entry:
      paramValues[0] = p_parent_directory_handle ? handleidparent_str : handleid_str;
      paramValues[1] = p_parent_directory_handle ? handletsparent_str : handlets_str;
      paramValues[2] = p_filename ? p_filename->name : "";
      paramValues[3] = handleid_str;
      paramValues[4] = handlets_str;

      p_res = PQexecPrepared(p_conn, "insertParent", 5, paramValues, NULL, NULL, 0);
      CheckCommand(p_res);
      PQclear(p_res);
      /* XXX : is it possible to have unique key violation ? */
    }

  EndTransaction(p_conn, p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 19
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);
}
Ejemplo n.º 20
0
/** 
 * @brief Unlock the Handle line previously locked by fsal_posixdb_lockHandleForUpdate
 * 
 * @param p_conn
 *        Database connection
 * 
 * @return ERR_FSAL_POSIXDB_NOERR if no error,
 *         another error code else.
 */
fsal_posixdb_status_t fsal_posixdb_cancelHandleLock(fsal_posixdb_conn * p_conn /* IN */ )
{
  RollbackTransaction(p_conn);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
Ejemplo n.º 21
0
/** connection to database */
fsal_posixdb_status_t fsal_posixdb_connect(fsal_posixdb_conn_params_t * dbparams,
        fsal_posixdb_conn ** p_conn)
{
    my_bool reconnect = 1;
    char password[1024] = "";
    int rc;
    unsigned int port;

    /* read password from password file */
    rc = ReadPasswordFromFile(dbparams->passwdfile, password);
    if(rc)
        ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, rc);

    /* resolve the port number */
    if(dbparams->port[0] != '\0')
    {
        if(!isdigit(dbparams->port[0]))
        {
            LogCrit(COMPONENT_FSAL,
                    "Numerical value expected for database port number (invalid value: %s)",
                    dbparams->port);
            ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, 0);
        }

        port = atoi(dbparams->port);
    }
    else
        port = 0;

    *p_conn = gsh_malloc(sizeof(fsal_posixdb_conn));
    if(*p_conn == NULL)
    {
        LogCrit(COMPONENT_FSAL, "ERROR: failed to allocate memory");
        ReturnCodeDB(ERR_FSAL_POSIXDB_NO_MEM, errno);
    }

    /* Init client structure */
    if(mysql_init(&(*p_conn)->db_conn) == NULL)
    {
        gsh_free(*p_conn);
        LogCrit(COMPONENT_FSAL, "ERROR: failed to create MySQL client struct");
        ReturnCodeDB(ERR_FSAL_POSIXDB_BADCONN, errno);
    }
#if ( MYSQL_VERSION_ID >= 50013 )
    /* set auto-reconnect option */
    mysql_options(&(*p_conn)->db_conn, MYSQL_OPT_RECONNECT, &reconnect);
#else
    /* older version */
    (*p_conn)->db_conn->reconnect = 1;
#endif

    /* connect to server */
    if(!mysql_real_connect(&(*p_conn)->db_conn, dbparams->host, dbparams->login,
                           password, dbparams->dbname, port, NULL, 0))
    {
        int rc;
        LogCrit(COMPONENT_FSAL, "Failed to connect to MySQL server: Error: %s",
                mysql_error(&(*p_conn)->db_conn));
        rc = mysql_errno(&(*p_conn)->db_conn);
        gsh_free(*p_conn);
        ReturnCodeDB(ERR_FSAL_POSIXDB_BADCONN, rc);
    }

    /* Note [MySQL reference guide]: mysql_real_connect()  incorrectly reset
     * the MYSQL_OPT_RECONNECT  option to its default value before MySQL 5.1.6.
     * Therefore, prior to that version, if you want reconnect to be enabled for
     * each connection, you must call mysql_options() with the MYSQL_OPT_RECONNECT
     * option after each call to mysql_real_connect().
     */
#if (MYSQL_VERSION_ID >= 50013) && (MYSQL_VERSION_ID < 50106)
    /* reset auto-reconnect option */
    mysql_options(&(*p_conn)->db_conn, MYSQL_OPT_RECONNECT, &reconnect);
#endif

    LogEvent(COMPONENT_FSAL, "Logged on to database sucessfully");

    /* Create prepared statements */
    return fsal_posixdb_initPreparedQueries(*p_conn);

}