void populatedb(fsal_posixdb_conn * p_conn, char *path)
{
  int rc;
  fsal_posixdb_fileinfo_t info;
  fsal_name_t fsalname;
  posixfsal_handle_t handle, handle_parent;
  struct stat buffstat;
  char *begin, *end, backup;

  if(path[0] != '/')
    {
      fputs("Error : you should provide a complete path", stderr);
      return;
    }

  if(path[strlen(path) - 1] != '/')
    strcat(path, "/");

  /* add the path (given in arguments) to the database */
  rc = lstat("/", &buffstat);
  fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
  fsal_internal_posixdb_add_entry(p_conn, NULL, &info, NULL, &handle_parent);

  begin = end = path;
  while(*end != '\0')
    {
      while(*begin == '/')
        begin++;
      if(*begin == '\0')
        break;
      end = begin + 1;
      while(*end != '/' && *end != '\0')
        end++;
      backup = *end;
      *end = '\0';

      rc = lstat(path, &buffstat);
      fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
      FSAL_str2name(begin, FSAL_MAX_NAME_LEN, &fsalname);
      fsal_internal_posixdb_add_entry(p_conn, &fsalname, &info, &handle_parent, &handle);
      memcpy(&handle_parent, &handle, sizeof(posixfsal_handle_t));

      *end = backup;
      begin = end;
    }

  /* add files */
  printf("Adding entries in %s... rc=%d ", path, rc);
  fflush(stdout);
  add_dir(p_conn, path, &handle_parent);
  puts("done");
}
Beispiel #2
0
/** 
 * @brief Get the handle of a file, knowing its name and its parent dir
 * 
 * @param p_context 
 * @param p_parent_dir_handle 
 *    Handle of the parent directory
 * @param p_fsalname 
 *    Name of the object
 * @param p_infofs
 *    Information about the file (taken from the filesystem) to be compared to information stored in database
 * @param p_object_handle 
 *    Handle of the file.
 * 
 * @return
 *    ERR_FSAL_NOERR, if no error
 *    Anothere error code else.
 */
fsal_status_t fsal_internal_getInfoFromName(posixfsal_op_context_t * p_context, /* IN */
                                            posixfsal_handle_t * p_parent_dir_handle,   /* IN */
                                            fsal_name_t * p_fsalname,   /* IN */
                                            fsal_posixdb_fileinfo_t * p_infofs, /* IN */
                                            posixfsal_handle_t * p_object_handle)       /* OUT */
{
  fsal_posixdb_status_t stdb;
  fsal_status_t st;

  stdb = fsal_posixdb_getInfoFromName(p_context->p_conn,
                                      p_parent_dir_handle,
                                      p_fsalname, NULL, p_object_handle);
  switch (stdb.major)
    {
    case ERR_FSAL_POSIXDB_NOERR:
      /* No error, the object is in the database */
      /* check consistency */
      if(fsal_posixdb_consistency_check(&(p_object_handle->data.info), p_infofs))
        {
          /* Entry not consistent */
          /* Delete the Handle entry, then add a new one (with a Parent entry) */
          stdb = fsal_posixdb_deleteHandle(p_context->p_conn, p_object_handle);
          if(FSAL_POSIXDB_IS_ERROR(stdb) && FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
            return st;
          /* don't break, add a new entry */
        }
      else
        {
          break;
        }
    case ERR_FSAL_POSIXDB_NOENT:
      /* object not in the database, add a new entry */
      st = fsal_internal_posixdb_add_entry(p_context->p_conn,
                                           p_fsalname,
                                           p_infofs,
                                           p_parent_dir_handle, p_object_handle);
      if(FSAL_IS_ERROR(st))
        return st;
      break;
    default:
      /* error */
      if(FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
        return st;
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
void add_dir(fsal_posixdb_conn * p_conn, char *path, posixfsal_handle_t * p_dir_handle)
{
  DIR *dirp;
  struct dirent *dp;
  struct dirent dpe;
  posixfsal_handle_t new_handle;
  struct stat buffstat;
  char path_temp[FSAL_MAX_PATH_LEN];
  fsal_status_t st;
  fsal_posixdb_fileinfo_t info;
  fsal_name_t fsalname;

  if((dirp = opendir(path)))
    {
      while(!readdir_r(dirp, &dpe, &dp) && dp)
        {
          if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
            continue;
          if(!strcmp(dp->d_name, ".snapshot"))
            {
              fputs("(ignoring .snapshot)", stderr);
              continue;
            }
          strcpy(path_temp, path);
          strcat(path_temp, dp->d_name);
          lstat(path_temp, &buffstat);

          fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
          FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &fsalname);
          st = fsal_internal_posixdb_add_entry(p_conn, &fsalname, &info, p_dir_handle,
                                               &new_handle);
          if(FSAL_IS_ERROR(st))
            {
              fprintf(stderr, "[Error %i/%i]\n", st.major, st.minor);
              return;
            }
          if(S_ISDIR(buffstat.st_mode))
            {
              strcat(path_temp, "/");
              add_dir(p_conn, path_temp, &new_handle);
            }
        };
      closedir(dirp);
    }
}
Beispiel #4
0
/**
 * FSAL_create:
 * Create a regular file.
 *
 * \param parent_directory_handle (input):
 *        Handle of the parent directory where the file is to be created.
 * \param p_filename (input):
 *        Pointer to the name of the file to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the file to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param object_handle (output):
 *        Pointer to the handle of the created file.
 * \param object_attributes (optional input/output): 
 *        The attributes of the created file.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occurred.
 */
fsal_status_t POSIXFSAL_create(fsal_handle_t * parent_directory_handle,  /* IN */
                               fsal_name_t * p_filename,        /* IN */
                               fsal_op_context_t * context,      /* IN */
                               fsal_accessmode_t accessmode,    /* IN */
                               fsal_handle_t * object_handle,    /* OUT */
                               fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */
    )
{

  posixfsal_handle_t * p_parent_directory_handle
    = (posixfsal_handle_t *) parent_directory_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) p_object_handle;
  int rc, fd, errsv;
  int setgid_bit = 0;
  fsal_status_t status;

  fsal_path_t fsalpath;
  struct stat buffstat;
  fsal_posixdb_fileinfo_t info;
  mode_t unix_mode;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!p_parent_directory_handle || !p_context || !p_object_handle || !p_filename)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);

  /* convert fsal mode to unix mode. */
  unix_mode = fsal2unix_mode(accessmode);

  /* Apply umask */
  unix_mode = unix_mode & ~global_fs_info.umask;

  LogFullDebug(COMPONENT_FSAL, "Creation mode: 0%o", accessmode);

  /* build the destination path */
  status =
      fsal_internal_getPathFromHandle(p_context, p_parent_directory_handle, 1, &fsalpath,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_create);

  /* Check the user can write in the directory, and check the setgid bit on the directory */
  if(buffstat.st_mode & S_ISGID)
    setgid_bit = 1;

  status = fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_create);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath, p_filename);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_create);

  /* call to API */

  TakeTokenFSCall();
  /* create the file */
  fd = open(fsalpath.path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, unix_mode);   /* error if the file already exists */
  errsv = errno;
  if(fd == -1)
    goto releaseToken;
  /* close the file descriptor */
  rc = close(fd);
  errsv = errno;
  if(rc)
    goto releaseToken;
  /* stat the new file */
  rc = lstat(fsalpath.path, &buffstat);
  errsv = errno;

 releaseToken:
  ReleaseTokenFSCall();

  if(fd == -1 || rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_create);

  /* add the file to the database */
  if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info)))
    Return(status.major, status.minor, INDEX_FSAL_create);
  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_filename, &info,
                                      p_parent_directory_handle, p_object_handle)))
    Return(status.major, status.minor, INDEX_FSAL_create);

  /* the file has been created */
  /* chown the file to the current user */

  if(p_context->credential.user != geteuid())
    {
      TakeTokenFSCall();
      /* if the setgid_bit was set on the parent directory,
       * do not change the group of the created file,
       * because it's already the parentdir's group */
      rc = lchown(fsalpath.path, p_context->credential.user,
                  setgid_bit ? -1 : (int)p_context->credential.group);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_create);

      buffstat.st_uid = p_context->credential.user;
      buffstat.st_gid = p_context->credential.group;
    }

  /* add the file to the database */

  if(p_object_attributes)
    {

      /* convert POSIX attributes to fsal attributes */
      status = posix2fsal_attributes(&buffstat, p_object_attributes);
      /* on error, we set a special bit in the mask. */
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
          FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_create);

}
Beispiel #5
0
/**
 * FSAL_mknode:
 * Create a special object in the filesystem.
 * Not supported upon HPSS.
 *
 * \return ERR_FSAL_NOTSUPP.
 */
fsal_status_t POSIXFSAL_mknode(fsal_handle_t * parentdir_hdl,   /* IN */
                               fsal_name_t * p_node_name,       /* IN */
                               fsal_op_context_t * context,      /* IN */
                               fsal_accessmode_t accessmode,    /* IN */
                               fsal_nodetype_t nodetype,        /* IN */
                               fsal_dev_t * dev,        /* IN */
                               fsal_handle_t * object_handle,    /* OUT (handle to the created node) */
                               fsal_attrib_list_t * node_attributes     /* [ IN/OUT ] */
    )
{
  posixfsal_handle_t * parentdir_handle = (posixfsal_handle_t *) parentdir_hdl;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) object_handle;
  int rc, errsv;
  int setgid_bit = 0;
  struct stat buffstat;
  fsal_status_t status;
  fsal_path_t fsalpath;
  fsal_posixdb_fileinfo_t info;

  mode_t unix_mode = 0;
  dev_t unix_dev = 0;

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!parentdir_handle || !p_context || !p_node_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);

  unix_mode = fsal2unix_mode(accessmode);

  /* Apply umask */
  unix_mode = unix_mode & ~global_fs_info.umask;

  switch (nodetype)
    {
    case FSAL_TYPE_BLK:
      if(!dev)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);
      unix_mode |= S_IFBLK;
      unix_dev = (dev->major << 8) | (dev->minor & 0xFF);
      break;

    case FSAL_TYPE_CHR:
      if(!dev)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);
      unix_mode |= S_IFCHR;
      unix_dev = (dev->major << 8) | (dev->minor & 0xFF);
      break;

    case FSAL_TYPE_SOCK:
      unix_mode |= S_IFSOCK;
      break;

    case FSAL_TYPE_FIFO:
      unix_mode |= S_IFIFO;
      break;

    default:
      LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d", nodetype);
      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_mknode);
    }

  /* build the destination path */
  status =
      fsal_internal_getPathFromHandle(p_context, parentdir_handle, 1, &fsalpath,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  /* Check the user can write in the directory, and check weither the setgid bit on the directory */
  if(buffstat.st_mode & S_ISGID)
    setgid_bit = 1;

  status = fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath, p_node_name);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  /* creates the node, then stats it */
  TakeTokenFSCall();

  rc = mknod(fsalpath.path, unix_mode, unix_dev);
  if(!rc)
    rc = lstat(fsalpath.path, &buffstat);
  errsv = errno;

  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mknode);

  /* add the object to the database */
  if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info)))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_node_name, &info,
                                      parentdir_handle, p_object_handle)))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  /* the node has been created */
  /* chown the file to the current user/group */

  if(p_context->credential.user != geteuid())
    {
      TakeTokenFSCall();

      /* if the setgid_bit was set on the parent directory, do not change the group of the created file, because it's already the parentdir's group */
      rc = lchown(fsalpath.path, p_context->credential.user,
                  setgid_bit ? -1 : (int)p_context->credential.group);
      errsv = errno;

      ReleaseTokenFSCall();

      if(rc)
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mknode);

      buffstat.st_uid = p_context->credential.user;
      buffstat.st_gid = p_context->credential.group;
    }

  /* Fills the attributes if needed */
  if(node_attributes)
    {

      status = posix2fsal_attributes(&buffstat, node_attributes);

      /* on error, we set a special bit in the mask. */

      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(node_attributes->asked_attributes);
          FSAL_SET_MASK(node_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* Finished */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mknode);

}
Beispiel #6
0
/**
 * FSAL_link:
 * Create a hardlink.
 *
 * \param target_handle (input):
 *        Handle of the target object.
 * \param dir_handle (input):
 *        Pointer to the directory handle where
 *        the hardlink is to be created.
 * \param p_link_name (input):
 *        Pointer to the name of the hardlink to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the directory to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param attributes (optionnal input/output): 
 *        The post_operation attributes of the linked object.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_link(fsal_handle_t * target_handle,      /* IN */
                             fsal_handle_t * dir_handle, /* IN */
                             fsal_name_t * p_link_name, /* IN */
                             fsal_op_context_t * context,        /* IN */
                             fsal_attrib_list_t * p_attributes  /* [ IN/OUT ] */
    )
{

  posixfsal_handle_t * p_target_handle = (posixfsal_handle_t *) target_handle;
  posixfsal_handle_t * p_dir_handle = (posixfsal_handle_t *) dir_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  int rc, errsv;
  fsal_status_t status;
  fsal_path_t fsalpath_old, fsalpath_new;
  fsal_posixdb_fileinfo_t info;
  posixfsal_handle_t newhandle;
  struct stat buffstat, buffstat_dir;

  /* sanity checks.
   * note : attributes is optional.
   */
  if(!p_target_handle || !p_dir_handle || !p_context || !p_link_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

  /* Tests if hardlinking is allowed by configuration. */

  if(!global_fs_info.link_support)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_link);

  LogFullDebug(COMPONENT_FSAL, "linking %llu/%i to %llu.%i/%s \n", p_target_handle->data.id,
               p_target_handle->data.ts, p_dir_handle->data.id, p_dir_handle->data.ts, p_link_name->name);

  /* get the old path */
  status =
      fsal_internal_getPathFromHandle(p_context, p_target_handle, 0, &fsalpath_old,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    {
      Return(status.major, status.minor, INDEX_FSAL_link);
    }

  /* build the destination path and check permissions on the directory */
  status =
      fsal_internal_getPathFromHandle(p_context, p_dir_handle, 1, &fsalpath_new,
                                      &buffstat_dir);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  status =
      fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat_dir, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath_new, p_link_name);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  /* Create the link on the filesystem */

  TakeTokenFSCall();
  rc = link(fsalpath_old.path, fsalpath_new.path);
  errsv = errno;
  ReleaseTokenFSCall();
  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_link);

  /* add the link in the database */
  buffstat.st_nlink++;          /* avoid to stat the new file */
  status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_link_name, &info,
                                      p_dir_handle, &newhandle)))
    Return(status.major, status.minor, INDEX_FSAL_link);

  /* optionnaly get attributes */

  if(p_attributes)
    {
      TakeTokenFSCall();
      rc = lstat(fsalpath_old.path, &buffstat);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)
        {
          status.major = posix2fsal_error(errsv);
          status.minor = errsv;
        }
      else
        {
          status = posix2fsal_attributes(&buffstat, p_attributes);
        }

      /* on error, we set a special bit in the mask. */
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(p_attributes->asked_attributes);
          FSAL_SET_MASK(p_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link);

}
Beispiel #7
0
/**
 * FSAL_mkdir:
 * Create a directory.
 *
 * \param parent_directory_handle (input):
 *        Handle of the parent directory where
 *        the subdirectory is to be created.
 * \param p_dirname (input):
 *        Pointer to the name of the directory to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the directory to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param object_handle (output):
 *        Pointer to the handle of the created directory.
 * \param object_attributes (optionnal input/output): 
 *        The attributes of the created directory.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_mkdir(fsal_handle_t * parent_directory_handle,   /* IN */
                              fsal_name_t * p_dirname,  /* IN */
                              fsal_op_context_t * context,       /* IN */
                              fsal_accessmode_t accessmode,     /* IN */
                              fsal_handle_t * object_handle,     /* OUT */
                              fsal_attrib_list_t * p_object_attributes  /* [ IN/OUT ] */
    )
{

  posixfsal_handle_t * p_parent_directory_handle
    = (posixfsal_handle_t *) parent_directory_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) object_handle;
  int rc, errsv;
  int setgid_bit = 0;
  struct stat buffstat;
  mode_t unix_mode;
  fsal_status_t status;
  fsal_path_t fsalpath;
  fsal_posixdb_fileinfo_t info;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!p_parent_directory_handle || !p_context || !p_object_handle || !p_dirname)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir);

  /* convert FSAL mode to HPSS mode. */
  unix_mode = fsal2unix_mode(accessmode);

  /* Apply umask */
  unix_mode = unix_mode & ~global_fs_info.umask;

  /* build the destination path */
  status =
      fsal_internal_getPathFromHandle(p_context, p_parent_directory_handle, 1, &fsalpath,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  /* Check the user can write in the directory, and check the setgid bit on the directory */
  if(buffstat.st_mode & S_ISGID)
    setgid_bit = 1;

  status = fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath, p_dirname);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  /* creates the directory and stats it */
  TakeTokenFSCall();

  rc = mkdir(fsalpath.path, unix_mode);
  if(!rc)
    rc = lstat(fsalpath.path, &buffstat);
  errsv = errno;

  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mkdir);

  /* add the directory to the database */
  if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info)))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);
  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_dirname, &info,
                                      p_parent_directory_handle, p_object_handle)))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  /* the directory has been created */
  /* chown the file to the current user/group */

  if(p_context->credential.user != geteuid())
    {
      TakeTokenFSCall();
      /* if the setgid_bit was set on the parent directory, do not change the group of the created file, because it's already the parentdir's group */
      rc = lchown(fsalpath.path, p_context->credential.user,
                  setgid_bit ? -1 : (int)p_context->credential.group);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mkdir);

      buffstat.st_uid = p_context->credential.user;
      buffstat.st_gid = p_context->credential.group;
    }

  /* Fills the attributes if needed */
  if(p_object_attributes)
    {

      status = posix2fsal_attributes(&buffstat, p_object_attributes);

      /* on error, we set a special bit in the mask. */

      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
          FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mkdir);

}
Beispiel #8
0
/** 
 * @brief Get the handle of a file from a fsal_posixdb_child array, knowing its name
 * 
 * @param p_context 
 * @param p_parent_dir_handle 
 *    Handle of the parent directory
 * @param p_fsalname 
 *    Name of the object
 * @param p_infofs
 *    Information about the file (taken from the filesystem) to be compared to information stored in database
 * @param p_children
 *    fsal_posixdb_child array (that contains the entries of the directory stored in the db)
 * @param p_object_handle 
 *    Handle of the file.
 * 
 * @return
 *    ERR_FSAL_NOERR, if no error
 *    Anothere error code else.
 */
fsal_status_t fsal_internal_getInfoFromChildrenList(posixfsal_op_context_t * p_context, /* IN */
                                                    posixfsal_handle_t * p_parent_dir_handle,   /* IN */
                                                    fsal_name_t * p_fsalname,   /* IN */
                                                    fsal_posixdb_fileinfo_t * p_infofs, /* IN */
                                                    fsal_posixdb_child * p_children,    /* IN */
                                                    unsigned int children_count,        /* IN */
                                                    posixfsal_handle_t * p_object_handle)       /* OUT */
{
  fsal_posixdb_status_t stdb;
  fsal_status_t st;
  int cmp = -1;                 /* when no children is available */
  unsigned int count;

  /* sanity check */
  if(!p_context || !p_parent_dir_handle || !p_fsalname || (!p_children && children_count)
     || !p_object_handle)
    ReturnCode(ERR_FSAL_FAULT, 0);

  /* check if the filename is in the list */
  for(count = 0; count < children_count; count++)
    {
      cmp = FSAL_namecmp(p_fsalname, &(p_children[count].name));
      if(!cmp)
        break;
      /* maybe a sorted list could give better result */
    }

  switch (cmp)
    {
    case 0:
      /* Entry found : check consistency */

      if(fsal_posixdb_consistency_check(&(p_children[count].handle.data.info), p_infofs))
        {
          /* Entry not consistent */
          /* Delete the Handle entry, then add a new one (with a Parent entry) */
          stdb =
              fsal_posixdb_deleteHandle(p_context->p_conn, &(p_children[count].handle));

          if(FSAL_POSIXDB_IS_ERROR(stdb) && FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
            return st;

          /* don't break, add a new entry */

        }
      else
        {
          memcpy(p_object_handle, &(p_children[count].handle),
                 sizeof(posixfsal_handle_t));
          break;
        }

    default:
      /* not found ! Add it */
      st = fsal_internal_posixdb_add_entry(p_context->p_conn,
                                           p_fsalname,
                                           p_infofs,
                                           p_parent_dir_handle, p_object_handle);
      if(FSAL_IS_ERROR(st))
        return st;
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}