Commit a8c749cf authored by Genaro Juan Sánchez Gallegos's avatar Genaro Juan Sánchez Gallegos Committed by Javier Garcia Blas
Browse files

Add improvements when moving a regular file to the same destination.

No related merge requests found
Showing with 135 additions and 60 deletions
+135 -60
......@@ -263,6 +263,12 @@ int imss_refresh(const char *path)
return 0;
}
/**
* @brief Method to retrieve the file attributes of a given path.
* @param path Path to the file.
* @param stbuf Pointer to the stat structure where the file attributes will be stored.AF_APPLETALK
* @return 0 on success, negative errno value on error.
*/
int imss_getattr(char *path, struct stat *stbuf)
{
// Needed variables for the call
......@@ -2605,18 +2611,25 @@ int imss_rename(char *old_path, char *new_path)
int file_desc_o, file_desc_n;
int fd = 0;
char *old_rpath = old_path; //(char *)calloc(MAX_PATH, sizeof(char));
//get_iuri(old_path, old_rpath);
// get_iuri(old_path, old_rpath);
char *new_rpath = new_path;//(char *)calloc(MAX_PATH, sizeof(char));
//get_iuri(new_path, new_rpath);
char *new_rpath = new_path; //(char *)calloc(MAX_PATH, sizeof(char));
// get_iuri(new_path, new_rpath);
// CHECKING IF IS MV DIR TO DIR
// check old_path if it is a directory if it is add / at the end
int res = imss_getattr(old_path, &ds_stat_n);
slog_debug("[imss_rename] after imss_getattr=%d, st_nlink=%lu", res, ds_stat_n.st_nlink);
if (res == 0)
int ret = imss_getattr(old_path, &ds_stat_n);
slog_debug("after imss_getattr=%d, st_nlink=%lu", ret, ds_stat_n.st_nlink);
if (ret == 0)
{
slog_debug("[imss_rename] is_dir? =%d", S_ISDIR(ds_stat_n.st_mode));
// check if new_path is the same as old_path
if (!strcmp(old_path, new_path))
{
ret = -EPERM;
return ret;
}
slog_debug("%s is_dir? =%d", old_path, S_ISDIR(ds_stat_n.st_mode));
if (S_ISDIR(ds_stat_n.st_mode))
{
......@@ -2637,7 +2650,7 @@ int imss_rename(char *old_path, char *new_path)
{
slog_error("HERCULES_ERR_IMSS_RENAME_CANNOT_OPEN_DATASET");
//free(new_rpath);
// free(new_rpath);
return -ENOENT;
}
......@@ -2658,8 +2671,8 @@ int imss_rename(char *old_path, char *new_path)
char *rdir_dest = (char *)calloc(MAX_PATH, sizeof(char));
get_iuri(dir_dest, rdir_dest);
res = imss_getattr(dir_dest, &ds_stat_n);
if (res == 0)
ret = imss_getattr(dir_dest, &ds_stat_n);
if (ret == 0)
{
if (S_ISDIR(ds_stat_n.st_mode))
{
......@@ -2677,8 +2690,8 @@ int imss_rename(char *old_path, char *new_path)
rename_dataset_srv_worker_dir_dir(old_rpath, new_rpath, file_desc_o, 0);
free(dir_dest);
free(rdir_dest);
//free(old_rpath);
//free(new_rpath);
// free(old_rpath);
// free(new_rpath);
return 0;
}
}
......@@ -2705,45 +2718,50 @@ int imss_rename(char *old_path, char *new_path)
if (file_desc_o < 0)
{
slog_error("Cannot open dataset, old_rpath=%s", old_rpath);
//free(old_rpath);
//free(new_rpath);
return -ENOENT;
}
res = imss_getattr(new_path, &ds_stat_n);
slog_debug("After imss_getattr, new_path=%s, res=%d", new_path, res);
if (res == 0)
ret = imss_getattr(new_path, &ds_stat_n);
slog_debug("After imss_getattr, new_path=%s, ret=%d", new_path, ret);
if (ret == 0)
{
// fprintf(stderr, "**************EXISTE EL DESTINO=%s\n", new_path);
// printf("new_path[last]=%c\n",new_path[strlen(new_path) -1]);
slog_debug("is_dir? =%d", S_ISDIR(ds_stat_n.st_mode));
slog_debug("%s is_dir? =%d", new_path, S_ISDIR(ds_stat_n.st_mode));
if (S_ISDIR(ds_stat_n.st_mode))
{
// create the new path for the origin file.
// create the new path for the origin file because it will be moved to a directory.
int pos = 0;
for (int c = 0; c < strlen(old_path); ++c)
for (int c = 0; c < strlen(old_rpath); ++c)
{
if (old_path[c] == '/')
if (old_rpath[c] == '/')
{
if (c + 1 < strlen(old_path))
if (c + 1 < strlen(old_rpath))
pos = c;
}
}
char full_path[PATH_MAX], name[PATH_MAX];
strncpy(name,old_path+pos+1,strlen(old_path)-pos);
strcpy(full_path,new_path);
strcat(full_path,name);
printf("%d, %s\n", pos, full_path);
slog_debug("%d, new_pat=%s, old_path=%s\n", pos, full_path, old_path);
strncpy(name, old_rpath + pos + 1, strlen(old_rpath) - pos);
strcpy(full_path, new_path);
strcat(full_path, name);
//printf("%d, %s\n", pos, full_path);
slog_debug("%d, full_path=%s, old_rpath=%s\n", pos, full_path, old_rpath);
if (!strcmp(old_rpath, full_path))
{
ret = -EPERM;
return ret;
}
// printf("old_rpath=%s, new_rpath=%s\n",old_rpath, new_rpath);
// TODO map_rename_prefetch(map_prefetch, old_rpath, new_rpath);
// RENAME LOCAL_IMSS(GARRAY), SRV_STAT(MAP & TREE)
res = rename_dataset_metadata(old_rpath, full_path);
if(res < 0) {
errno = EEXIST;
return res;
ret = rename_dataset_metadata(old_rpath, full_path);
if (ret < 0)
{
// errno = EEXIST;
return ret;
}
// RENAME SRV_WORKER(MAP)
rename_dataset_srv_worker(old_rpath, full_path, fd, 0);
......@@ -2757,10 +2775,11 @@ int imss_rename(char *old_path, char *new_path)
// printf("old_rpath=%s, new_rpath=%s\n",old_rpath, new_rpath);
// TODO map_rename_prefetch(map_prefetch, old_rpath, new_rpath);
// RENAME LOCAL_IMSS(GARRAY), SRV_STAT(MAP & TREE)
res = rename_dataset_metadata(old_rpath, new_rpath);
if(res < 0) {
ret = rename_dataset_metadata(old_rpath, new_rpath);
if (ret < 0)
{
errno = EEXIST;
return res;
return ret;
}
// RENAME SRV_WORKER(MAP)
rename_dataset_srv_worker(old_rpath, new_rpath, fd, 0);
......@@ -2772,21 +2791,43 @@ int imss_rename(char *old_path, char *new_path)
/// fprintf(stderr, "**************NO EXISTE EL DESTINO=%s\n", new_path);
slog_error("HERCULES_ERR_IMSS_RENAME_DEST_DOES_NOT_EXIST");
// printf("old_rpath=%s, new_rpath=%s\n",old_rpath, new_rpath);
// TODO map_rename_prefetch(map_prefetch, old_rpath, new_rpath);
// RENAME LOCAL_IMSS(GARRAY), SRV_STAT(MAP & TREE)
res = rename_dataset_metadata(old_rpath, new_rpath);
if(res < 0) {
errno = EEXIST;
return res;
// TODO map_rename_prefetch(map_prefetch, old_rpath, new_rpath);
// RENAME LOCAL_IMSS(GARRAY), SRV_STAT(MAP & TREE)
char last_parent_dir[URI_];
int last_parent_offset = find_last_parent_dir((char *)new_path, last_parent_dir);
slog_debug("last_parent_dir=%s, last_parent_offset=%d", last_parent_dir, last_parent_offset);
if (strncmp(last_parent_dir, old_rpath, strlen(last_parent_dir)) && last_parent_offset > 0)
{ // parent and old_rpath are not the same.
// last_parent_offset == 0 means the new_path is on the root directory.
// Due origin file (old_rpath) will be moved to a new directory
// we check if the new parent directoy exists.
ret = imss_getattr(last_parent_dir, &ds_stat_n);
if (ret != 0)
{
slog_error("HERCULES_ERROR_RENAME_DEST_PARENT_DIR_DOES_NOT_EXIST");
return ret;
}
// RENAME SRV_WORKER(MAP)
rename_dataset_srv_worker(old_rpath, new_rpath, fd, 0);
map_rename(map, old_rpath, new_rpath);
}
if (!strcmp(old_rpath, new_path))
{
ret = -EPERM;
return ret;
}
ret = rename_dataset_metadata(old_rpath, new_rpath);
if (ret < 0)
{
// errno = EEXIST;
return ret;
}
// RENAME SRV_WORKER(MAP)
rename_dataset_srv_worker(old_rpath, new_rpath, fd, 0);
map_rename(map, old_rpath, new_rpath);
// return res;
}
//free(old_rpath);
//free(new_rpath);
// free(old_rpath);
// free(new_rpath);
return 0;
}
......@@ -43,7 +43,7 @@
#define TYPE_METADATA_SERVER 'm'
// File types.
#define TYPE_HERCULES_INSTANCE 'I' // for regular files
#define TYPE_HERCULES_INSTANCE 'I' // for Hercules instances
#define TYPE_REGULAR_FILE 'R' // for regular files
#define TYPE_DIRECTORY 'D' // for directories
......
......@@ -643,6 +643,8 @@ RETURNS: 0 - Resources were released successfully.
void close_ucx_endpoint(ucp_worker_h worker, ucp_ep_h ep);
int find_first_parent_dir(const char *dataset_uri, char *first_parent_dir);
int find_last_parent_dir(const char *dataset_uri, char *last_parent_dir);
/**
* Compares two paths regardless of if one of them has a slash '/' at the end of the string.
......
......@@ -338,6 +338,8 @@ int32_t stat_init(char *stat_hostfile,
len_client_node = strlen(client_node);
struct hostent *host_entry;
// TO CHECK: The gethostbyname*(), gethostbyaddr*(), herror(), and hstrerror() functions are obsolete.
// https://www.man7.org/linux/man-pages/man3/gethostbyname.3.html
if ((host_entry = gethostbyname(client_node)) == NULL)
{
perror("HERCULES_ERR_GETHOSTBYNAME");
......@@ -3968,6 +3970,36 @@ int find_first_parent_dir(const char *dataset_uri, char *first_parent_dir)
return first_parent_offset;
}
int find_last_parent_dir(const char *dataset_uri, char *last_parent_dir)
{
int last_parent_offset = 0;
size_t uri_len = strlen(dataset_uri);
// for (int j = strlen("imss://"); j < uri_len; ++j)
for (int j = uri_len; j > strlen("imss://"); --j)
{
if (dataset_uri[j] == '/')
{
// mnt/hercules/dir/subdir/ must return the offset to get /mnt/hercules/dir/subdir/
// mnt/hercules/dir/subdir/file.txt must return the offset to get /mnt/hercules/dir/subdir/
{ // Search for the last directory offset on the path.
last_parent_offset = j;
// break;
}
}
}
if (last_parent_offset > 0)
{
strncpy(last_parent_dir, dataset_uri, last_parent_offset);
last_parent_dir[last_parent_offset] = '\0'; // To ensure null-termination.
}
else
{
strcpy(last_parent_dir, dataset_uri);
}
return last_parent_offset;
}
// Method specifying the type (DATASET or IMSS INSTANCE) of a provided URI.
char get_type(const char *uri)
{
......
......@@ -447,11 +447,10 @@ extern "C"
else
{
// slog_live("[HERCULES] after resolve path, pathname=%s, real_pathname=%s", pathname, real_pathname);
// new_path = convert_path(pathname);
ret = ResolvePath(pathname, absolute_pathname);
// fprintf(stderr, "[IMSS] last option, pathname=%s, absolute_pathname_len=%d, workdir=%s\n", pathname, ret, workdir);
//fprintf(stderr, "[IMSS] last option, pathname=%s, absolute_pathname=%s, absolute_pathname_len=%d, workdir=%s\n", pathname, absolute_pathname, ret, workdir);
if (ret > 0)
{
{ // absolute path.
// slog_live("[IMSS] absolute_pathname=%s", absolute_pathname);
new_path = convert_path(absolute_pathname);
}
......@@ -460,7 +459,7 @@ extern "C"
new_path = convert_path(pathname);
}
// slog_live("[HERCULES] pathname=%s, realpath=%s, new_path=%s", pathname, real_pathname, new_path);
//slog_live("[HERCULES] pathname=%s, absolute_pathname=%s, new_path=%s", pathname, absolute_pathname,new_path);
// free(real_pathname);
}
}
......@@ -520,6 +519,7 @@ extern "C"
char *new_path = (char *)calloc(PATH_MAX, sizeof(char));
strcpy(path, name);
//fprintf(stderr, "Received name=%s\n", name);
size_t len = strlen(MOUNT_POINT);
// remove MOUNT_POINT prefix from the path.
if (len > 0)
......@@ -531,7 +531,7 @@ extern "C"
}
}
// fprintf(stderr, "name=%s, path=%s\n", name, path);
//fprintf(stderr, "name=%s, path=%s\n", name, path);
// seeks initial slashes "/" in the path.
len = strlen(path);
......@@ -2700,7 +2700,6 @@ extern "C"
slog_live("[POSIX]. Calling Hercules 'mkdir', path=%s, new_path=%s", path, new_path);
// char *new_path;
// new_path = convert_path(path, MOUNT_POINT);
ret = imss_mkdir(new_path, mode);
if (ret < 0)
{
......@@ -2758,8 +2757,6 @@ extern "C"
if (new_path_1 != NULL && new_path_2 != NULL)
{
slog_live("[POSIX]. Both new_path_1=%s, new_path_2=%s", new_path_1, new_path_2);
// new_path_1 = convert_path(name1, MOUNT_POINT);
// new_path_2 = convert_path(name2, MOUNT_POINT);
ret = imss_symlinkat(new_path_1, new_path_2, 0);
free(new_path_1);
free(new_path_2);
......@@ -2771,7 +2768,6 @@ extern "C"
slog_live("[POSIX]. Only second new_path_2=%s", new_path_2);
// new_path_1 = name1;
strcpy(new_path_1, name1);
// new_path_2 = convert_path(name2, MOUNT_POINT);
ret = imss_symlinkat(new_path_1, new_path_2, 1);
// free(new_path_1) ?
free(new_path_2);
......
......@@ -29,6 +29,7 @@
/* Last Update: 15/Dec/2023 */
#include "resolvepath.h"
#include <stdio.h>
/*
* int ResolvePath(const char *path_, char *resolved)
......@@ -97,6 +98,7 @@ int ResolvePath(const char *path_, char *resolved)
left_len -= s - left;
if (p != NULL)
memmove(left, s + 1, left_len + 1);
// fprintf(stderr, "resolved=%c\t", resolved[resolved_len - 1]);
if (resolved[resolved_len - 1] != '/')
{
if (resolved_len + 1 >= PATH_MAX)
......@@ -107,7 +109,9 @@ int ResolvePath(const char *path_, char *resolved)
}
resolved[resolved_len++] = '/';
resolved[resolved_len] = '\0';
//fprintf(stderr, "resolved now=%s\n", resolved);
}
if (next_token[0] == '\0')
continue;
else if (strcmp(next_token, ".") == 0)
......@@ -151,9 +155,9 @@ int ResolvePath(const char *path_, char *resolved)
* Remove trailing slash except when the resolved pathname
* is a single "/".
*/
if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
{
resolved[resolved_len - 1] = '\0';
}
// if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
// {
// resolved[resolved_len - 1] = '\0';
// }
return resolved_len;
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment