From a8c7fbaf2c96a683a3d5742a8aeafa4db1c238e2 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Fri, 9 Dec 2022 09:55:17 -0800 Subject: [PATCH 1/9] client: allow create on existing file --- client/src/unifyfs-sysio.c | 13 ----- client/src/unifyfs_api_file.c | 2 +- client/src/unifyfs_fid.c | 100 ++++++++++------------------------ 3 files changed, 31 insertions(+), 84 deletions(-) diff --git a/client/src/unifyfs-sysio.c b/client/src/unifyfs-sysio.c index 96805721c..8fa130b07 100644 --- a/client/src/unifyfs-sysio.c +++ b/client/src/unifyfs-sysio.c @@ -1115,11 +1115,6 @@ static int posix_create(char* upath, mode_t mode) int flags = O_WRONLY | O_CREAT | O_TRUNC; off_t pos; int rc = unifyfs_fid_open(posix_client, upath, flags, mode, &fid, &pos); - if (rc == EEXIST) { - /* POSIX allows O_CREAT on existing file */ - flags = O_WRONLY | O_TRUNC; - rc = unifyfs_fid_open(posix_client, upath, flags, mode, &fid, &pos); - } if (rc != UNIFYFS_SUCCESS) { errno = unifyfs_rc_errno(rc); return -1; @@ -1199,14 +1194,6 @@ int UNIFYFS_WRAP(open)(const char* path, int flags, ...) off_t pos; int rc = unifyfs_fid_open(posix_client, upath, flags, mode, &fid, &pos); - if (rc == EEXIST) { - /* POSIX allows O_CREAT on existing file */ - if ((flags & O_CREAT) && !(flags & O_EXCL)) { - flags -= O_CREAT; - rc = unifyfs_fid_open(posix_client, upath, flags, mode, - &fid, &pos); - } - } if (rc != UNIFYFS_SUCCESS) { errno = unifyfs_rc_errno(rc); return -1; diff --git a/client/src/unifyfs_api_file.c b/client/src/unifyfs_api_file.c index 394e24293..06cc5fbc1 100644 --- a/client/src/unifyfs_api_file.c +++ b/client/src/unifyfs_api_file.c @@ -83,7 +83,7 @@ unifyfs_rc unifyfs_create(unifyfs_handle fshdl, off_t filepos = -1; mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - int create_flags = O_CREAT; + int create_flags = O_CREAT | O_EXCL; int rc = unifyfs_fid_open(client, filepath, create_flags, mode, &fid, &filepos); if (UNIFYFS_SUCCESS == rc) { diff --git a/client/src/unifyfs_fid.c b/client/src/unifyfs_fid.c index 36c65709a..9bdecf58f 100644 --- a/client/src/unifyfs_fid.c +++ b/client/src/unifyfs_fid.c @@ -433,35 +433,31 @@ int unifyfs_fid_open( * if O_APPEND, set pos to file size */ - /* flag indicating whether file should be truncated */ - int need_truncate = 0; + /* allocate a fid structure and storage for the fid + * if we don't already have one */ + if (!found_local) { + /* initialize local metadata for this file */ + fid = unifyfs_fid_create_file(client, path, exclusive); + if (fid < 0) { + LOGERR("failed to create a new file %s", path); + return -fid; + } + + /* initialize local storage for this file */ + rc = fid_storage_alloc(client, fid); + if (rc != UNIFYFS_SUCCESS) { + LOGERR("failed to allocate storage space for file %s (fid=%d)", + path, fid); + unifyfs_fid_delete(client, fid); + return ENOMEM; + } + } /* determine whether we are creating a new file * or opening an existing one */ if (flags & O_CREAT) { /* user wants to create a new file, - * allocate a local file id structure if needed */ - if (!found_local) { - /* initialize local metadata for this file */ - fid = unifyfs_fid_create_file(client, path, exclusive); - if (fid < 0) { - LOGERR("failed to create a new file %s", path); - return -fid; - } - - /* initialize local storage for this file */ - rc = fid_storage_alloc(client, fid); - if (rc != UNIFYFS_SUCCESS) { - LOGERR("failed to allocate storage space for file %s (fid=%d)", - path, fid); - unifyfs_fid_delete(client, fid); - return ENOMEM; - } - - /* TODO: set meta->mode bits to mode variable */ - } - - /* create global file metadata */ + * create global file metadata */ unifyfs_file_attr_op_e op = UNIFYFS_FILE_ATTR_OP_CREATE; ret = unifyfs_set_global_file_meta_from_fid(client, fid, op); if (ret == EEXIST) { @@ -472,28 +468,13 @@ int unifyfs_fid_open( * Read its metadata to update our cache. */ rc = unifyfs_get_global_file_meta(client, gfid, &gfattr); if (rc == UNIFYFS_SUCCESS) { - /* check for truncate if the file exists already */ - if ((flags & O_TRUNC) && open_for_write) { - if (gfattr.is_laminated) { - ret = EROFS; - } else { - need_truncate = 1; - } - } - - /* append writes are ok on existing files too */ - if ((flags & O_APPEND) && open_for_write) { - ret = UNIFYFS_SUCCESS; - } - /* Successful in fetching metadata for existing file. * Update our local cache using that metadata. */ unifyfs_fid_update_file_meta(client, fid, &gfattr); - if (!found_local) { - /* it's ok if another client created the shared file */ - ret = UNIFYFS_SUCCESS; - } + /* O_CREAT is valid on an existing file, + * so long as O_EXCL is not set */ + ret = UNIFYFS_SUCCESS; } else { /* Failed to get metadata for a file that should exist. * Perhaps it was since deleted. We could try to create @@ -527,32 +508,15 @@ int unifyfs_fid_open( LOGDBG("file found locally, but seems to be deleted globally. " "invalidating the local cache."); unifyfs_fid_delete(client, fid); + } else if (!found_local) { + /* free fid resources we just allocated above, + * but don't do that by calling fid_unlink */ + unifyfs_fid_delete(client, fid); } - return ret; } - /* succeeded in global lookup for file, - * allocate a local file id structure if needed */ - if (!found_local) { - /* initialize local metadata for this file */ - fid = unifyfs_fid_create_file(client, path, 0); - if (fid < 0) { - LOGERR("failed to create a new file %s", path); - return -fid; - } - - /* initialize local storage for this file */ - ret = fid_storage_alloc(client, fid); - if (ret != UNIFYFS_SUCCESS) { - LOGERR("failed to allocate storage space for file %s (fid=%d)", - path, fid); - /* free fid we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); - return ret; - } - } else { + if (found_local) { /* TODO: already have a local entry for this path and found * a global entry, check that they are consistent */ } @@ -560,11 +524,6 @@ int unifyfs_fid_open( /* Successful in fetching metadata for existing file. * Update our local cache using that metadata. */ unifyfs_fid_update_file_meta(client, fid, &gfattr); - - /* check if we need to truncate the existing file */ - if ((flags & O_TRUNC) && open_for_write && !gfattr.is_laminated) { - need_truncate = 1; - } } /* if given O_DIRECTORY, the named file must be a directory */ @@ -606,7 +565,8 @@ int unifyfs_fid_open( } /* truncate the file, if we have to */ - if (need_truncate) { + /* check if we need to truncate the existing file */ + if ((flags & O_TRUNC) && open_for_write) { ret = unifyfs_fid_truncate(client, fid, 0); if (ret != UNIFYFS_SUCCESS) { LOGERR("Failed to truncate the file %s", path); From 49a1f01d9742c04d2c5e482356e0fcdf2159aab8 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 30 Jan 2023 12:19:36 -0800 Subject: [PATCH 2/9] config: add client_excl_private TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- client/src/unifyfs_api.c | 11 +++++++++++ client/src/unifyfs_api_internal.h | 1 + client/src/unifyfs_fid.c | 5 ++++- common/src/unifyfs_configurator.h | 1 + docs/configuration.rst | 1 + 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/client/src/unifyfs_api.c b/client/src/unifyfs_api.c index 080295fda..9e2b0a5c3 100644 --- a/client/src/unifyfs_api.c +++ b/client/src/unifyfs_api.c @@ -135,6 +135,17 @@ unifyfs_rc unifyfs_initialize(const char* mountpoint, } } + /* Create node-local private files, rather than globally shared files + * when given O_EXCL during file open/create operations. */ + client->use_excl_private = true; + cfgval = client_cfg->client_excl_private; + if (cfgval != NULL) { + rc = configurator_bool_val(cfgval, &b); + if (rc == 0) { + client->use_excl_private = (bool)b; + } + } + /* Determine whether we persist data to storage device on fsync(). * Turning this setting off speeds up fsync() by only syncing the * extent metadata, but it violates POSIX semanatics. */ diff --git a/client/src/unifyfs_api_internal.h b/client/src/unifyfs_api_internal.h index 0963b396e..fd18b61cb 100644 --- a/client/src/unifyfs_api_internal.h +++ b/client/src/unifyfs_api_internal.h @@ -65,6 +65,7 @@ typedef struct unifyfs_client { /* mountpoint configuration */ unifyfs_cfg_t cfg; /* user-provided configuration */ + bool use_excl_private; /* O_EXCL creates private files */ bool use_fsync_persist; /* persist data to storage on fsync() */ bool use_local_extents; /* enable tracking of local extents */ bool use_node_local_extents; /* enable tracking of extents within diff --git a/client/src/unifyfs_fid.c b/client/src/unifyfs_fid.c index 9bdecf58f..19af5bb3a 100644 --- a/client/src/unifyfs_fid.c +++ b/client/src/unifyfs_fid.c @@ -415,6 +415,9 @@ int unifyfs_fid_open( int exclusive = flags & O_EXCL; + /* whether to create shared or non-shared files */ + int private = (exclusive && client->use_excl_private); + /* struct to hold global metadata for file */ unifyfs_file_attr_t gfattr = { 0, }; @@ -437,7 +440,7 @@ int unifyfs_fid_open( * if we don't already have one */ if (!found_local) { /* initialize local metadata for this file */ - fid = unifyfs_fid_create_file(client, path, exclusive); + fid = unifyfs_fid_create_file(client, path, private); if (fid < 0) { LOGERR("failed to create a new file %s", path); return -fid; diff --git a/common/src/unifyfs_configurator.h b/common/src/unifyfs_configurator.h index bd5f39c5a..f85a7359b 100644 --- a/common/src/unifyfs_configurator.h +++ b/common/src/unifyfs_configurator.h @@ -69,6 +69,7 @@ UNIFYFS_CFG_CLI(unifyfs, daemonize, BOOL, off, "enable server daemonization", NULL, 'D', "on|off") \ UNIFYFS_CFG_CLI(unifyfs, mountpoint, STRING, /unifyfs, "mountpoint directory", NULL, 'm', "specify full path to desired mountpoint") \ UNIFYFS_CFG(client, cwd, STRING, NULLSTRING, "current working directory", NULL) \ + UNIFYFS_CFG(client, excl_private, BOOL, on, "create node-local private files when given O_EXCL", NULL) \ UNIFYFS_CFG(client, fsync_persist, BOOL, on, "persist written data to storage on fsync()", NULL) \ UNIFYFS_CFG(client, local_extents, BOOL, off, "use client-cached extents to service local reads without consulting local server", NULL) \ UNIFYFS_CFG(client, node_local_extents, BOOL, off, \ diff --git a/docs/configuration.rst b/docs/configuration.rst index c6bf5f364..a861168ff 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -69,6 +69,7 @@ a given section and key. Key Type Description ================== ====== ================================================================= cwd STRING effective starting current working directory + excl_private BOOL create node-local private files when given O_EXCL (default: on) fsync_persist BOOL persist data to storage on fsync() (default: on) local_extents BOOL service reads from local data (default: off) max_files INT maximum number of open files per client process (default: 128) From db70e8ec152d3373296723ae6d101d0f87bca701 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Tue, 31 Jan 2023 15:04:28 -0800 Subject: [PATCH 3/9] break fid_open into parts TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- client/src/unifyfs_api_file.c | 17 +- client/src/unifyfs_fid.c | 365 ++++++++++++++++++++++++++++++---- client/src/unifyfs_fid.h | 6 + 3 files changed, 330 insertions(+), 58 deletions(-) diff --git a/client/src/unifyfs_api_file.c b/client/src/unifyfs_api_file.c index 06cc5fbc1..4e91fac72 100644 --- a/client/src/unifyfs_api_file.c +++ b/client/src/unifyfs_api_file.c @@ -77,15 +77,9 @@ unifyfs_rc unifyfs_create(unifyfs_handle fshdl, /* NOTE: the 'flags' parameter is not currently used. it is reserved * for future indication of file-specific behavior */ - /* the output parameters of unifyfs_fid_open() are not used here, but - * must be provided */ - int fid = -1; - off_t filepos = -1; - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - int create_flags = O_CREAT | O_EXCL; - int rc = unifyfs_fid_open(client, filepath, create_flags, mode, - &fid, &filepos); + int create_flags = O_CREAT; + int rc = unifyfs_fid_open2(client, filepath, create_flags, mode); if (UNIFYFS_SUCCESS == rc) { *gfid = unifyfs_generate_gfid(filepath); } @@ -112,13 +106,8 @@ unifyfs_rc unifyfs_open(unifyfs_handle fshdl, return (unifyfs_rc)EINVAL; } - /* the output parameters of unifyfs_fid_open() are not used here, but - * must be provided */ - int fid = -1; - off_t filepos = -1; - mode_t mode = 0; - int rc = unifyfs_fid_open(client, filepath, flags, mode, &fid, &filepos); + int rc = unifyfs_fid_open2(client, filepath, flags, mode); if (UNIFYFS_SUCCESS == rc) { *gfid = unifyfs_generate_gfid(filepath); } diff --git a/client/src/unifyfs_fid.c b/client/src/unifyfs_fid.c index 19af5bb3a..bccb0e8d0 100644 --- a/client/src/unifyfs_fid.c +++ b/client/src/unifyfs_fid.c @@ -371,6 +371,157 @@ int unifyfs_fid_delete(unifyfs_client* client, return UNIFYFS_SUCCESS; } +/* Given a file name, allocate a gfid entry on the server for the file. */ +static int unifyfs_gfid_create( + unifyfs_client* client, + const char* path, /* path of file to be created */ + int exclusive, /* return EEXIST if gfid already exists */ + int private, /* create node-local (non-shared) file */ + int truncate, /* truncate file to 0 length if already exists */ + mode_t mode) /* mode bits as from open(2) */ +{ + /* check that pathname is within bounds */ + size_t pathlen = strlen(path) + 1; + if (pathlen > UNIFYFS_MAX_FILENAME) { + return ENAMETOOLONG; + } + + int gfid = unifyfs_generate_gfid(path); + + /* initialize file attributes */ + unifyfs_file_attr_t gfattr = { 0, }; + unifyfs_file_attr_set_invalid(&gfattr); + + gfattr.gfid = gfid; + gfattr.size = 0; + gfattr.mode = mode; + gfattr.is_laminated = 0; + gfattr.is_shared = !private; + gfattr.filename = (char*) path; + + /* use client user/group */ + gfattr.uid = getuid(); + gfattr.gid = getgid(); + + /* use current time for atime/mtime/ctime */ + struct timespec tp = {0}; + clock_gettime(CLOCK_REALTIME, &tp); + gfattr.atime = tp; + gfattr.mtime = tp; + gfattr.ctime = tp; + + /* TODO: process O_CREAT, O_EXCL, and O_TRUNC at server */ + + /* Attempt to create gfid entry for file on server */ + unifyfs_file_attr_op_e op = UNIFYFS_FILE_ATTR_OP_CREATE; + int ret = unifyfs_set_global_file_meta(client, gfid, op, &gfattr); + if (ret == EEXIST) { + LOGINFO("Attempt to create existing file %s (gfid:%d)", path, gfid); + if (!exclusive) { + ret = UNIFYFS_SUCCESS; + } else { + LOGERR("Failed create of existing private/exclusive file %s", + path); + } + } + if (ret != UNIFYFS_SUCCESS) { + return ret; + } + +#if 0 + /* TODO: If we allow truncate on create, and if file is already + * laminated, return an error. It will be easier to check this + * status on the server. */ + if (truncate) { + ret = invoke_client_truncate_rpc(client, gfid, 0); + if (ret != UNIFYFS_SUCCESS) { + LOGERR("Failed to truncate file %s", path); + } + } +#endif + + return ret; +} + +/* Given a file name, this fetches the metadata for the corresponding gfid. + * If a local entry already exists, it updates the local entry. + * Otherwise, it allocates a local fid and caches the metadata. + * Returns UNIFYFS error code. + */ +static int unifyfs_fid_fetch( + unifyfs_client* client, + const char* path) +{ + int ret = UNIFYFS_SUCCESS; + + /* check that pathname is within bounds */ + size_t pathlen = strlen(path) + 1; + if (pathlen > UNIFYFS_MAX_FILENAME) { + return ENAMETOOLONG; + } + + /* + * TODO: The test of file existence involves both local and global checks. + * However, the testing below does not seem to cover all cases. For + * instance, a globally unlinked file might be still cached locally because + * the broadcast for cache invalidation has not been implemented, yet. + */ + + int gfid = unifyfs_generate_gfid(path); + + /* test whether we have info for file in our local file list */ + int fid = unifyfs_fid_from_path(client, path); + int found_local = (fid >= 0); + + LOGDBG("unifyfs_fid_from_path() gave %d (gfid = %d)", fid, gfid); + + /* fetch metadata for file */ + unifyfs_file_attr_t gfattr = { 0, }; + ret = unifyfs_get_global_file_meta(client, gfid, &gfattr); + if (ret != UNIFYFS_SUCCESS) { + /* bail out if we failed to find global file */ + if (found_local) { + /* Have a local entry, but there is no global entry. + * Perhaps global file was unlinked? + * Invalidate our local entry. */ + LOGDBG("file found locally, but seems to be deleted globally. " + "invalidating the local cache."); + unifyfs_fid_delete(client, fid); + } + return ret; + } + + /* allocate a fid structure and storage for the fid + * if we don't already have one */ + if (!found_local) { + /* initialize local metadata for this file */ + int private = !(gfattr.is_shared); + fid = unifyfs_fid_create_file(client, path, private); + if (fid < 0) { + LOGERR("failed to create a new file %s", path); + return -fid; + } + + /* initialize local storage for this file */ + ret = fid_storage_alloc(client, fid); + if (ret != UNIFYFS_SUCCESS) { + LOGERR("failed to allocate storage space for file %s (fid=%d)", + path, fid); + unifyfs_fid_delete(client, fid); + return ENOMEM; + } + } else { + /* TODO: already have a local entry for this path and found + * a global entry, check that they are consistent */ + } + + /* Successful in fetching metadata for existing file. + * Update our local cache using that metadata. */ + unifyfs_fid_update_file_meta(client, fid, &gfattr); + + return UNIFYFS_SUCCESS; +} + /* opens a new file id with specified path, access flags, and permissions, * fills outfid with file id and outpos with position for current file pointer, * returns UNIFYFS error code @@ -383,11 +534,109 @@ int unifyfs_fid_open( int* outfid, /* allocated local file id if open is successful */ off_t* outpos) /* initial file position if open is successful */ { - int rc; int ret = UNIFYFS_SUCCESS; - /* set the pointer to the start of the file */ + /* check that pathname is within bounds */ + size_t pathlen = strlen(path) + 1; + if (pathlen > UNIFYFS_MAX_FILENAME) { + return ENAMETOOLONG; + } + + int gfid = unifyfs_generate_gfid(path); + + /* attempt to create file if requested */ + if (flags & O_CREAT) { + int exclusive = (flags & O_EXCL); + int private = (exclusive && client->use_excl_private); + int truncate = (flags & O_TRUNC); + ret = unifyfs_gfid_create(client, path, + exclusive, private, truncate, mode); + if (ret != UNIFYFS_SUCCESS) { + return ret; + } + } + + /* File should exist at this point, + * update our cache with its metadata. */ + ret = unifyfs_fid_fetch(client, path); + if (ret != UNIFYFS_SUCCESS) { + /* Failed to get metadata for a file that should exist. + * Perhaps it was since deleted. We could try to create + * it again and loop through these steps, but for now + * consider this situation to be an error. */ + LOGERR("Failed to get metadata on existing file %s", path); + return ret; + } + + int fid = unifyfs_fid_from_path(client, path); + LOGDBG("unifyfs_fid_from_path() gave %d (gfid = %d)", fid, gfid); + + /* if given O_DIRECTORY, the named file must be a directory */ + if ((flags & O_DIRECTORY) && !unifyfs_fid_is_dir(client, fid)) { + /* delete entry from cache, + * but don't do that by calling fid_unlink */ + unifyfs_fid_delete(client, fid); + return ENOTDIR; + } + + /* TODO: does O_DIRECTORY really have to be given to open a directory? */ + if (!(flags & O_DIRECTORY) && unifyfs_fid_is_dir(client, fid)) { + /* delete entry from cache, + * but don't do that by calling fid_unlink */ + unifyfs_fid_delete(client, fid); + return EISDIR; + } + + /* Catch any case where we could potentially want to write to a laminated + * file. */ + if (unifyfs_fid_is_laminated(client, fid) && + ((flags & (O_CREAT | O_TRUNC | O_APPEND | O_WRONLY)) || + ((mode & 0222) && (flags != O_RDONLY)))) { + LOGDBG("Can't open laminated file %s with a writable flag.", path); + /* free fid we just allocated above, + * but don't do that by calling fid_unlink */ + unifyfs_fid_delete(client, fid); + return EROFS; + } + + /* determine whether any write flags are specified */ + int open_for_write = flags & (O_RDWR | O_WRONLY); + + /* check if we need to truncate the existing file */ + /* Note: even if supported in gfid_create, + * we may need to truncate local data for file. */ + if ((flags & O_TRUNC) && open_for_write) { + ret = unifyfs_fid_truncate(client, fid, 0); + if (ret != UNIFYFS_SUCCESS) { + LOGERR("Failed to truncate the file %s", path); + return ret; + } + } + + /* for append mode, set starting position to EOF */ off_t pos = 0; + if ((flags & O_APPEND) && open_for_write) { + pos = unifyfs_fid_logical_size(client, fid); + } + + /* return local file id and starting file position */ + *outfid = fid; + *outpos = pos; + + return UNIFYFS_SUCCESS; +} + +/* opens a new file id with specified path, access flags, and permissions, + * returns UNIFYFS error code + */ +int unifyfs_fid_open2( + unifyfs_client* client, + const char* path, /* path of file to be opened */ + int flags, /* flags bits as from open(2) */ + mode_t mode) /* mode bits as from open(2) */ +{ + int rc; + int ret = UNIFYFS_SUCCESS; /* check that pathname is within bounds */ size_t pathlen = strlen(path) + 1; @@ -415,9 +664,6 @@ int unifyfs_fid_open( int exclusive = flags & O_EXCL; - /* whether to create shared or non-shared files */ - int private = (exclusive && client->use_excl_private); - /* struct to hold global metadata for file */ unifyfs_file_attr_t gfattr = { 0, }; @@ -436,31 +682,35 @@ int unifyfs_fid_open( * if O_APPEND, set pos to file size */ - /* allocate a fid structure and storage for the fid - * if we don't already have one */ - if (!found_local) { - /* initialize local metadata for this file */ - fid = unifyfs_fid_create_file(client, path, private); - if (fid < 0) { - LOGERR("failed to create a new file %s", path); - return -fid; - } - - /* initialize local storage for this file */ - rc = fid_storage_alloc(client, fid); - if (rc != UNIFYFS_SUCCESS) { - LOGERR("failed to allocate storage space for file %s (fid=%d)", - path, fid); - unifyfs_fid_delete(client, fid); - return ENOMEM; - } - } + /* flag indicating whether file should be truncated */ + int need_truncate = 0; /* determine whether we are creating a new file * or opening an existing one */ if (flags & O_CREAT) { /* user wants to create a new file, - * create global file metadata */ + * allocate a local file id structure if needed */ + if (!found_local) { + /* initialize local metadata for this file */ + fid = unifyfs_fid_create_file(client, path, exclusive); + if (fid < 0) { + LOGERR("failed to create a new file %s", path); + return -fid; + } + + /* initialize local storage for this file */ + rc = fid_storage_alloc(client, fid); + if (rc != UNIFYFS_SUCCESS) { + LOGERR("failed to allocate storage space for file %s (fid=%d)", + path, fid); + unifyfs_fid_delete(client, fid); + return ENOMEM; + } + + /* TODO: set meta->mode bits to mode variable */ + } + + /* create global file metadata */ unifyfs_file_attr_op_e op = UNIFYFS_FILE_ATTR_OP_CREATE; ret = unifyfs_set_global_file_meta_from_fid(client, fid, op); if (ret == EEXIST) { @@ -471,13 +721,28 @@ int unifyfs_fid_open( * Read its metadata to update our cache. */ rc = unifyfs_get_global_file_meta(client, gfid, &gfattr); if (rc == UNIFYFS_SUCCESS) { + /* check for truncate if the file exists already */ + if ((flags & O_TRUNC) && open_for_write) { + if (gfattr.is_laminated) { + ret = EROFS; + } else { + need_truncate = 1; + } + } + + /* append writes are ok on existing files too */ + if ((flags & O_APPEND) && open_for_write) { + ret = UNIFYFS_SUCCESS; + } + /* Successful in fetching metadata for existing file. * Update our local cache using that metadata. */ unifyfs_fid_update_file_meta(client, fid, &gfattr); - /* O_CREAT is valid on an existing file, - * so long as O_EXCL is not set */ - ret = UNIFYFS_SUCCESS; + if (!found_local) { + /* it's ok if another client created the shared file */ + ret = UNIFYFS_SUCCESS; + } } else { /* Failed to get metadata for a file that should exist. * Perhaps it was since deleted. We could try to create @@ -511,15 +776,32 @@ int unifyfs_fid_open( LOGDBG("file found locally, but seems to be deleted globally. " "invalidating the local cache."); unifyfs_fid_delete(client, fid); - } else if (!found_local) { - /* free fid resources we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); } + return ret; } - if (found_local) { + /* succeeded in global lookup for file, + * allocate a local file id structure if needed */ + if (!found_local) { + /* initialize local metadata for this file */ + fid = unifyfs_fid_create_file(client, path, 0); + if (fid < 0) { + LOGERR("failed to create a new file %s", path); + return -fid; + } + + /* initialize local storage for this file */ + ret = fid_storage_alloc(client, fid); + if (ret != UNIFYFS_SUCCESS) { + LOGERR("failed to allocate storage space for file %s (fid=%d)", + path, fid); + /* free fid we just allocated above, + * but don't do that by calling fid_unlink */ + unifyfs_fid_delete(client, fid); + return ret; + } + } else { /* TODO: already have a local entry for this path and found * a global entry, check that they are consistent */ } @@ -527,6 +809,11 @@ int unifyfs_fid_open( /* Successful in fetching metadata for existing file. * Update our local cache using that metadata. */ unifyfs_fid_update_file_meta(client, fid, &gfattr); + + /* check if we need to truncate the existing file */ + if ((flags & O_TRUNC) && open_for_write && !gfattr.is_laminated) { + need_truncate = 1; + } } /* if given O_DIRECTORY, the named file must be a directory */ @@ -568,8 +855,7 @@ int unifyfs_fid_open( } /* truncate the file, if we have to */ - /* check if we need to truncate the existing file */ - if ((flags & O_TRUNC) && open_for_write) { + if (need_truncate) { ret = unifyfs_fid_truncate(client, fid, 0); if (ret != UNIFYFS_SUCCESS) { LOGERR("Failed to truncate the file %s", path); @@ -577,15 +863,6 @@ int unifyfs_fid_open( } } - /* for appends, update position to EOF */ - if ((flags & O_APPEND) && open_for_write) { - pos = unifyfs_fid_logical_size(client, fid); - } - - /* return local file id and starting file position */ - *outfid = fid; - *outpos = pos; - return UNIFYFS_SUCCESS; } diff --git a/client/src/unifyfs_fid.h b/client/src/unifyfs_fid.h index 2ea56e987..04e3871db 100644 --- a/client/src/unifyfs_fid.h +++ b/client/src/unifyfs_fid.h @@ -52,6 +52,12 @@ int unifyfs_fid_open(unifyfs_client* client, int* outfid, off_t* outpos); +/* Opens a file with specified path, access flags, and permissions. */ +int unifyfs_fid_open2(unifyfs_client* client, + const char* path, + int flags, + mode_t mode); + /* Close file with given file id */ int unifyfs_fid_close(unifyfs_client* client, int fid); From 228eb6698431665de3a31792ca0b778d9594f52f Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Tue, 31 Jan 2023 15:44:22 -0800 Subject: [PATCH 4/9] test: enable fopen(w) EEXIST tests TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- t/std/fopen-fclose.c | 4 ---- t/std/size.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/t/std/fopen-fclose.c b/t/std/fopen-fclose.c index 6362786fe..f08a61204 100644 --- a/t/std/fopen-fclose.c +++ b/t/std/fopen-fclose.c @@ -108,24 +108,20 @@ int fopen_fclose_test(char* unifyfs_root) diag("Finished UNIFYFS_WRAP(fopen/fclose) tests"); /* Verify we can open an existing file for writing */ - todo("fopen(w) fails with EEXIST on existing files."); errno = 0; fd = fopen(path, "w"); err = errno; ok(fd != NULL && err == 0, "%s:%d fopen existing file %s w/ mode w: %s", __FILE__, __LINE__, path, strerror(err)); - end_todo; /* Verify close succeeds. */ - skip(fd == NULL, 1, "fopen(w) fails with EEXIST on existing files."); errno = 0; rc = fclose(fd); err = errno; ok(rc == 0 && err == 0, "%s:%d fclose existing file: %s", __FILE__, __LINE__, strerror(err)); - end_skip; return 0; } diff --git a/t/std/size.c b/t/std/size.c index a117b59ec..58bc6b959 100644 --- a/t/std/size.c +++ b/t/std/size.c @@ -192,19 +192,15 @@ int truncate_on_open(char* unifyfs_root) __FILE__, __LINE__, global, strerror(errno)); /* Opening an existing file for writing with fopen should truncate file */ - todo("fopen(w) fails with EEXIST on existing file."); fp = fopen(path, "w"); ok(fp != NULL, "%s:%d fopen(%s): %s", __FILE__, __LINE__, path, strerror(errno)); - end_todo; - skip(fp == NULL, 2, "enable when fopen(w) EEXIST is fixed."); ok(fclose(fp) == 0, "%s:%d fclose(): %s", __FILE__, __LINE__, strerror(errno)); testutil_get_size(path, &global); ok(global == 0, "%s:%d global size after fopen(%s, \"w\") = %d: %s", __FILE__, __LINE__, path, global, strerror(errno)); - end_skip; diag("Finished truncate on fopen tests"); From 96e324905ecaeb649a0861f2d9f15b53d11741d6 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 20 Mar 2023 10:23:52 -0700 Subject: [PATCH 5/9] move open2 logic to client api TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- client/src/unifyfs_api_file.c | 39 +++++- client/src/unifyfs_fid.c | 244 +--------------------------------- client/src/unifyfs_fid.h | 23 +++- 3 files changed, 50 insertions(+), 256 deletions(-) diff --git a/client/src/unifyfs_api_file.c b/client/src/unifyfs_api_file.c index 4e91fac72..a91f3ec7b 100644 --- a/client/src/unifyfs_api_file.c +++ b/client/src/unifyfs_api_file.c @@ -77,13 +77,17 @@ unifyfs_rc unifyfs_create(unifyfs_handle fshdl, /* NOTE: the 'flags' parameter is not currently used. it is reserved * for future indication of file-specific behavior */ + int exclusive = 1; + int private = ((flags & O_EXCL) && client->use_excl_private); + int truncate = 0; mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - int create_flags = O_CREAT; - int rc = unifyfs_fid_open2(client, filepath, create_flags, mode); - if (UNIFYFS_SUCCESS == rc) { - *gfid = unifyfs_generate_gfid(filepath); + int ret = unifyfs_gfid_create(client, filepath, + exclusive, private, truncate, mode); + if (UNIFYFS_SUCCESS != ret) { + return (unifyfs_rc)ret; } - return (unifyfs_rc)rc; + + return unifyfs_open(fshdl, flags, filepath, gfid); } /* Open an existing file in UnifyFS */ @@ -106,10 +110,31 @@ unifyfs_rc unifyfs_open(unifyfs_handle fshdl, return (unifyfs_rc)EINVAL; } - mode_t mode = 0; - int rc = unifyfs_fid_open2(client, filepath, flags, mode); + /* check that pathname is within bounds */ + size_t pathlen = strlen(filepath) + 1; + if (pathlen > UNIFYFS_MAX_FILENAME) { + return (unifyfs_rc)ENAMETOOLONG; + } + + /* Ensure that only read/write access flags are set. + * In particular, do not allow flag like: + * O_CREAT, O_EXCL, O_TRUNC, O_DIRECTORY */ + int allowed = O_RDONLY | O_RDWR | O_WRONLY; + int remaining = flags & ~(allowed); + if (remaining) { + LOGERR("Valid flags limited to {O_RDONLY, O_RDWR, O_WRONLY} %s", + filepath); + return (unifyfs_rc)EINVAL; + } + + /* File should exist at this point, + * update our cache with its metadata. */ + int rc = unifyfs_fid_fetch(client, filepath); if (UNIFYFS_SUCCESS == rc) { *gfid = unifyfs_generate_gfid(filepath); + } else { + LOGERR("Failed to get metadata on file %s", + filepath); } return (unifyfs_rc)rc; } diff --git a/client/src/unifyfs_fid.c b/client/src/unifyfs_fid.c index bccb0e8d0..54d0de57f 100644 --- a/client/src/unifyfs_fid.c +++ b/client/src/unifyfs_fid.c @@ -372,7 +372,7 @@ int unifyfs_fid_delete(unifyfs_client* client, } /* Given a file name, allocate a gfid entry on the server for the file. */ -static int unifyfs_gfid_create( +int unifyfs_gfid_create( unifyfs_client* client, const char* path, /* path of file to be created */ int exclusive, /* return EEXIST if gfid already exists */ @@ -448,7 +448,7 @@ static int unifyfs_gfid_create( * Otherwise, it allocates a local fid and caches the metadata. * Returns UNIFYFS error code. */ -static int unifyfs_fid_fetch( +int unifyfs_fid_fetch( unifyfs_client* client, const char* path) { @@ -626,246 +626,6 @@ int unifyfs_fid_open( return UNIFYFS_SUCCESS; } -/* opens a new file id with specified path, access flags, and permissions, - * returns UNIFYFS error code - */ -int unifyfs_fid_open2( - unifyfs_client* client, - const char* path, /* path of file to be opened */ - int flags, /* flags bits as from open(2) */ - mode_t mode) /* mode bits as from open(2) */ -{ - int rc; - int ret = UNIFYFS_SUCCESS; - - /* check that pathname is within bounds */ - size_t pathlen = strlen(path) + 1; - if (pathlen > UNIFYFS_MAX_FILENAME) { - return ENAMETOOLONG; - } - - /* - * TODO: The test of file existence involves both local and global checks. - * However, the testing below does not seem to cover all cases. For - * instance, a globally unlinked file might be still cached locally because - * the broadcast for cache invalidation has not been implemented, yet. - */ - - /* look for local and global file ids */ - int fid = unifyfs_fid_from_path(client, path); - int gfid = unifyfs_generate_gfid(path); - LOGDBG("unifyfs_fid_from_path() gave %d (gfid = %d)", fid, gfid); - - /* test whether we have info for file in our local file list */ - int found_local = (fid >= 0); - - /* determine whether any write flags are specified */ - int open_for_write = flags & (O_RDWR | O_WRONLY); - - int exclusive = flags & O_EXCL; - - /* struct to hold global metadata for file */ - unifyfs_file_attr_t gfattr = { 0, }; - - /* if O_CREAT, - * if not local, allocate fid and storage - * create local fid meta - * attempt to create global inode - * if EEXIST and O_EXCL, error and release fid/storage - * lookup global meta - * check that local and global info are consistent - * if O_TRUNC and not laminated, truncate - * else - * lookup global meta - * if not found, error - * check that local and global info are consistent - * if O_APPEND, set pos to file size - */ - - /* flag indicating whether file should be truncated */ - int need_truncate = 0; - - /* determine whether we are creating a new file - * or opening an existing one */ - if (flags & O_CREAT) { - /* user wants to create a new file, - * allocate a local file id structure if needed */ - if (!found_local) { - /* initialize local metadata for this file */ - fid = unifyfs_fid_create_file(client, path, exclusive); - if (fid < 0) { - LOGERR("failed to create a new file %s", path); - return -fid; - } - - /* initialize local storage for this file */ - rc = fid_storage_alloc(client, fid); - if (rc != UNIFYFS_SUCCESS) { - LOGERR("failed to allocate storage space for file %s (fid=%d)", - path, fid); - unifyfs_fid_delete(client, fid); - return ENOMEM; - } - - /* TODO: set meta->mode bits to mode variable */ - } - - /* create global file metadata */ - unifyfs_file_attr_op_e op = UNIFYFS_FILE_ATTR_OP_CREATE; - ret = unifyfs_set_global_file_meta_from_fid(client, fid, op); - if (ret == EEXIST) { - LOGINFO("Attempt to create existing file %s (fid:%d)", path, fid); - if (!exclusive) { - /* File didn't exist before, but now it does. - * Another process beat us to the punch in creating it. - * Read its metadata to update our cache. */ - rc = unifyfs_get_global_file_meta(client, gfid, &gfattr); - if (rc == UNIFYFS_SUCCESS) { - /* check for truncate if the file exists already */ - if ((flags & O_TRUNC) && open_for_write) { - if (gfattr.is_laminated) { - ret = EROFS; - } else { - need_truncate = 1; - } - } - - /* append writes are ok on existing files too */ - if ((flags & O_APPEND) && open_for_write) { - ret = UNIFYFS_SUCCESS; - } - - /* Successful in fetching metadata for existing file. - * Update our local cache using that metadata. */ - unifyfs_fid_update_file_meta(client, fid, &gfattr); - - if (!found_local) { - /* it's ok if another client created the shared file */ - ret = UNIFYFS_SUCCESS; - } - } else { - /* Failed to get metadata for a file that should exist. - * Perhaps it was since deleted. We could try to create - * it again and loop through these steps, but for now - * consider this situation to be an error. */ - LOGERR("Failed to get metadata on existing file %s", path); - } - } else { - LOGERR("Failed create of existing private/exclusive file %s", - path); - } - } - if (ret != UNIFYFS_SUCCESS) { - if (!found_local) { - /* free fid resources we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); - } - return ret; - } - } else { - /* trying to open without creating, file must already exist, - * lookup global metadata for file */ - ret = unifyfs_get_global_file_meta(client, gfid, &gfattr); - if (ret != UNIFYFS_SUCCESS) { - /* bail out if we failed to find global file */ - if (found_local && ret == ENOENT) { - /* Have a local entry, but there is no global entry. - * Perhaps global file was unlinked? - * Invalidate our local entry. */ - LOGDBG("file found locally, but seems to be deleted globally. " - "invalidating the local cache."); - unifyfs_fid_delete(client, fid); - } - - return ret; - } - - /* succeeded in global lookup for file, - * allocate a local file id structure if needed */ - if (!found_local) { - /* initialize local metadata for this file */ - fid = unifyfs_fid_create_file(client, path, 0); - if (fid < 0) { - LOGERR("failed to create a new file %s", path); - return -fid; - } - - /* initialize local storage for this file */ - ret = fid_storage_alloc(client, fid); - if (ret != UNIFYFS_SUCCESS) { - LOGERR("failed to allocate storage space for file %s (fid=%d)", - path, fid); - /* free fid we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); - return ret; - } - } else { - /* TODO: already have a local entry for this path and found - * a global entry, check that they are consistent */ - } - - /* Successful in fetching metadata for existing file. - * Update our local cache using that metadata. */ - unifyfs_fid_update_file_meta(client, fid, &gfattr); - - /* check if we need to truncate the existing file */ - if ((flags & O_TRUNC) && open_for_write && !gfattr.is_laminated) { - need_truncate = 1; - } - } - - /* if given O_DIRECTORY, the named file must be a directory */ - if ((flags & O_DIRECTORY) && !unifyfs_fid_is_dir(client, fid)) { - if (!found_local) { - /* free fid we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); - } - return ENOTDIR; - } - - /* TODO: does O_DIRECTORY really have to be given to open a directory? */ - if (!(flags & O_DIRECTORY) && unifyfs_fid_is_dir(client, fid)) { - if (!found_local) { - /* free fid we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); - } - return EISDIR; - } - - /* - * Catch any case where we could potentially want to write to a laminated - * file. - */ - if (gfattr.is_laminated && - ((flags & (O_CREAT | O_TRUNC | O_APPEND | O_WRONLY)) || - ((mode & 0222) && (flags != O_RDONLY)))) { - LOGDBG("Can't open laminated file %s with a writable flag.", path); - /* TODO: free fid we just allocated above, - * but don't do that by calling fid_unlink */ - if (!found_local) { - /* free fid we just allocated above, - * but don't do that by calling fid_unlink */ - unifyfs_fid_delete(client, fid); - } - return EROFS; - } - - /* truncate the file, if we have to */ - if (need_truncate) { - ret = unifyfs_fid_truncate(client, fid, 0); - if (ret != UNIFYFS_SUCCESS) { - LOGERR("Failed to truncate the file %s", path); - return ret; - } - } - - return UNIFYFS_SUCCESS; -} - int unifyfs_fid_close(unifyfs_client* client, int fid) { diff --git a/client/src/unifyfs_fid.h b/client/src/unifyfs_fid.h index 04e3871db..4adb84716 100644 --- a/client/src/unifyfs_fid.h +++ b/client/src/unifyfs_fid.h @@ -52,12 +52,6 @@ int unifyfs_fid_open(unifyfs_client* client, int* outfid, off_t* outpos); -/* Opens a file with specified path, access flags, and permissions. */ -int unifyfs_fid_open2(unifyfs_client* client, - const char* path, - int flags, - mode_t mode); - /* Close file with given file id */ int unifyfs_fid_close(unifyfs_client* client, int fid); @@ -76,6 +70,13 @@ int unifyfs_fid_unlink(unifyfs_client* client, int unifyfs_fid_delete(unifyfs_client* client, int fid); +/* Given a file name, this fetches the metadata for the corresponding gfid. + * If a local entry already exists, it updates the local entry. + * Otherwise, it allocates a local fid and caches the metadata. + * Returns UNIFYFS error code. */ +int unifyfs_fid_fetch(unifyfs_client* client, + const char* path); + /* Use local file metadata to update global metadata */ int unifyfs_set_global_file_meta_from_fid(unifyfs_client* client, int fid, @@ -159,6 +160,14 @@ int unifyfs_fid_sync_data(unifyfs_client* client, int unifyfs_fid_sync_extents(unifyfs_client* client, int fid); - +/* Given a file name, allocate a gfid entry on the server for the file. + * Returns UNIFYFS_SUCCESS if successful. */ +int unifyfs_gfid_create( + unifyfs_client* client, + const char* path, /* path of file to be created */ + int exclusive, /* return EEXIST if gfid already exists */ + int private, /* create node-local (non-shared) file */ + int truncate, /* truncate file to 0 length if already exists */ + mode_t mode); /* mode bits as from open(2) */ #endif /* UNIFYFS_FID_H */ From a0088cbd2741462740198b0216967e7fe4c5dc84 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 20 Mar 2023 12:15:20 -0700 Subject: [PATCH 6/9] add regular file bit TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- client/src/unifyfs_api_file.c | 2 +- client/src/unifyfs_fid.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/client/src/unifyfs_api_file.c b/client/src/unifyfs_api_file.c index a91f3ec7b..c563ce48f 100644 --- a/client/src/unifyfs_api_file.c +++ b/client/src/unifyfs_api_file.c @@ -80,7 +80,7 @@ unifyfs_rc unifyfs_create(unifyfs_handle fshdl, int exclusive = 1; int private = ((flags & O_EXCL) && client->use_excl_private); int truncate = 0; - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + mode_t mode = UNIFYFS_STAT_DEFAULT_FILE_MODE; int ret = unifyfs_gfid_create(client, filepath, exclusive, private, truncate, mode); if (UNIFYFS_SUCCESS != ret) { diff --git a/client/src/unifyfs_fid.c b/client/src/unifyfs_fid.c index 54d0de57f..a82a28e9e 100644 --- a/client/src/unifyfs_fid.c +++ b/client/src/unifyfs_fid.c @@ -546,6 +546,15 @@ int unifyfs_fid_open( /* attempt to create file if requested */ if (flags & O_CREAT) { + /* Ensure that we're only creating a regular file. */ + int type = mode & S_IFMT; + if (type & ~S_IFREG) { + LOGERR("Only regular files can be created %s S_IFMT bits %x", + path, type); + return EINVAL; + } + mode |= S_IFREG; + int exclusive = (flags & O_EXCL); int private = (exclusive && client->use_excl_private); int truncate = (flags & O_TRUNC); From ec15a6f18274a13d2a123ba6fe8b788ac62723d3 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 20 Mar 2023 12:36:58 -0700 Subject: [PATCH 7/9] path length checked in fid_fetch TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- client/src/unifyfs_api_file.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/client/src/unifyfs_api_file.c b/client/src/unifyfs_api_file.c index c563ce48f..8d62dd9b1 100644 --- a/client/src/unifyfs_api_file.c +++ b/client/src/unifyfs_api_file.c @@ -110,12 +110,6 @@ unifyfs_rc unifyfs_open(unifyfs_handle fshdl, return (unifyfs_rc)EINVAL; } - /* check that pathname is within bounds */ - size_t pathlen = strlen(filepath) + 1; - if (pathlen > UNIFYFS_MAX_FILENAME) { - return (unifyfs_rc)ENAMETOOLONG; - } - /* Ensure that only read/write access flags are set. * In particular, do not allow flag like: * O_CREAT, O_EXCL, O_TRUNC, O_DIRECTORY */ From eb3b930343629578da7183111fcbfb13d0502691 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 20 Mar 2023 13:05:50 -0700 Subject: [PATCH 8/9] test: check unifyfs_open with O_TRUNC fails TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- t/api/create-open-remove.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/t/api/create-open-remove.c b/t/api/create-open-remove.c index 06ebd4eb8..57ffed1ce 100644 --- a/t/api/create-open-remove.c +++ b/t/api/create-open-remove.c @@ -55,11 +55,18 @@ int api_create_open_remove_test(char* unifyfs_root, diag("Starting API open tests"); + int invalid_flags = O_WRONLY | O_TRUNC; int rdwr_flags = O_RDWR; int rd_flags = O_RDONLY; + unifyfs_gfid dummy2_gfid = UNIFYFS_INVALID_GFID; unifyfs_gfid t3_gfid = UNIFYFS_INVALID_GFID; unifyfs_gfid t4_gfid = UNIFYFS_INVALID_GFID; + rc = unifyfs_open(*fshdl, invalid_flags, testfile1, &dummy2_gfid); + ok(rc != UNIFYFS_SUCCESS && dummy2_gfid == UNIFYFS_INVALID_GFID, + "%s:%d unifyfs_open(%s) with O_TRUNC fails: rc=%d (%s)", + __FILE__, __LINE__, testfile1, rc, unifyfs_rc_enum_description(rc)); + rc = unifyfs_open(*fshdl, rdwr_flags, testfile1, &t3_gfid); ok(rc == UNIFYFS_SUCCESS && t3_gfid == t1_gfid, "%s:%d unifyfs_open(%s) is successful: rc=%d (%s)", From 4ae473d44eb594ccd99e16041b61c2e3a8fbaa97 Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 27 Mar 2023 11:05:04 -0700 Subject: [PATCH 9/9] drop #if 0 code block in gfid_create TEST_CHECKPATCH_SKIP_FILES="common/src/unifyfs_configurator.h" --- client/src/unifyfs_fid.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/client/src/unifyfs_fid.c b/client/src/unifyfs_fid.c index a82a28e9e..c9df554df 100644 --- a/client/src/unifyfs_fid.c +++ b/client/src/unifyfs_fid.c @@ -428,18 +428,6 @@ int unifyfs_gfid_create( return ret; } -#if 0 - /* TODO: If we allow truncate on create, and if file is already - * laminated, return an error. It will be easier to check this - * status on the server. */ - if (truncate) { - ret = invoke_client_truncate_rpc(client, gfid, 0); - if (ret != UNIFYFS_SUCCESS) { - LOGERR("Failed to truncate file %s", path); - } - } -#endif - return ret; }