Store mvnode in vector instead of manual linked list (#2312)
This simplifies code and avoids manual memory management. References #2261.
This commit is contained in:
parent
f493cb5846
commit
01189e99fc
|
@ -35,7 +35,6 @@ s3fs_SOURCES = \
|
|||
s3fs_xml.cpp \
|
||||
metaheader.cpp \
|
||||
mpu_util.cpp \
|
||||
mvnode.cpp \
|
||||
curl.cpp \
|
||||
curl_handlerpool.cpp \
|
||||
curl_multi.cpp \
|
||||
|
|
139
src/mvnode.cpp
139
src/mvnode.cpp
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* s3fs - FUSE-based file system backed by Amazon S3
|
||||
*
|
||||
* Copyright(C) 2007 Takeshi Nakatani <ggtakec.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "s3fs.h"
|
||||
#include "mvnode.h"
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utility functions for moving objects
|
||||
//-------------------------------------------------------------------
|
||||
MVNODE *create_mvnode(const char *old_path, const char *new_path, bool is_dir, bool normdir)
|
||||
{
|
||||
MVNODE *p;
|
||||
char *p_old_path;
|
||||
char *p_new_path;
|
||||
|
||||
if(nullptr == (p_old_path = strdup(old_path))){
|
||||
printf("create_mvnode: could not allocation memory for p_old_path\n");
|
||||
S3FS_FUSE_EXIT();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(nullptr == (p_new_path = strdup(new_path))){
|
||||
free(p_old_path);
|
||||
printf("create_mvnode: could not allocation memory for p_new_path\n");
|
||||
S3FS_FUSE_EXIT();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
p = new MVNODE();
|
||||
p->old_path = p_old_path;
|
||||
p->new_path = p_new_path;
|
||||
p->is_dir = is_dir;
|
||||
p->is_normdir = normdir;
|
||||
p->prev = nullptr;
|
||||
p->next = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
//
|
||||
// Add sorted MVNODE data(Ascending order)
|
||||
//
|
||||
MVNODE *add_mvnode(MVNODE** head, MVNODE** tail, const char *old_path, const char *new_path, bool is_dir, bool normdir)
|
||||
{
|
||||
if(!head || !tail){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MVNODE* cur;
|
||||
MVNODE* mvnew;
|
||||
for(cur = *head; cur; cur = cur->next){
|
||||
if(cur->is_dir == is_dir){
|
||||
int nResult = strcmp(cur->old_path, old_path);
|
||||
if(0 == nResult){
|
||||
// Found same old_path.
|
||||
return cur;
|
||||
|
||||
}else if(0 > nResult){
|
||||
// next check.
|
||||
// ex: cur("abc"), mvnew("abcd")
|
||||
// ex: cur("abc"), mvnew("abd")
|
||||
continue;
|
||||
|
||||
}else{
|
||||
// Add into before cur-pos.
|
||||
// ex: cur("abc"), mvnew("ab")
|
||||
// ex: cur("abc"), mvnew("abb")
|
||||
if(nullptr == (mvnew = create_mvnode(old_path, new_path, is_dir, normdir))){
|
||||
return nullptr;
|
||||
}
|
||||
if(cur->prev){
|
||||
(cur->prev)->next = mvnew;
|
||||
}else{
|
||||
*head = mvnew;
|
||||
}
|
||||
mvnew->prev = cur->prev;
|
||||
mvnew->next = cur;
|
||||
cur->prev = mvnew;
|
||||
|
||||
return mvnew;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add into tail.
|
||||
if(nullptr == (mvnew = create_mvnode(old_path, new_path, is_dir, normdir))){
|
||||
return nullptr;
|
||||
}
|
||||
mvnew->prev = (*tail);
|
||||
if(*tail){
|
||||
(*tail)->next = mvnew;
|
||||
}
|
||||
(*tail) = mvnew;
|
||||
if(!(*head)){
|
||||
(*head) = mvnew;
|
||||
}
|
||||
return mvnew;
|
||||
}
|
||||
|
||||
void free_mvnodes(MVNODE *head)
|
||||
{
|
||||
MVNODE *my_head;
|
||||
MVNODE *next;
|
||||
|
||||
for(my_head = head, next = nullptr; my_head; my_head = next){
|
||||
next = my_head->next;
|
||||
free(my_head->old_path);
|
||||
free(my_head->new_path);
|
||||
delete my_head;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: expandtab sw=4 ts=4 fdm=marker
|
||||
* vim<600: expandtab sw=4 ts=4
|
||||
*/
|
53
src/mvnode.h
53
src/mvnode.h
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* s3fs - FUSE-based file system backed by Amazon S3
|
||||
*
|
||||
* Copyright(C) 2007 Randy Rizun <rrizun@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef S3FS_MVNODE_H_
|
||||
#define S3FS_MVNODE_H_
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Structure
|
||||
//-------------------------------------------------------------------
|
||||
typedef struct mvnode
|
||||
{
|
||||
char* old_path;
|
||||
char* new_path;
|
||||
bool is_dir;
|
||||
bool is_normdir;
|
||||
struct mvnode* prev;
|
||||
struct mvnode* next;
|
||||
} MVNODE;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utility functions for moving objects
|
||||
//-------------------------------------------------------------------
|
||||
MVNODE *create_mvnode(const char *old_path, const char *new_path, bool is_dir, bool normdir = false);
|
||||
MVNODE *add_mvnode(MVNODE** head, MVNODE** tail, const char *old_path, const char *new_path, bool is_dir, bool normdir = false);
|
||||
void free_mvnodes(MVNODE *head);
|
||||
|
||||
#endif // S3FS_MVNODE_H_
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: expandtab sw=4 ts=4 fdm=marker
|
||||
* vim<600: expandtab sw=4 ts=4
|
||||
*/
|
42
src/s3fs.cpp
42
src/s3fs.cpp
|
@ -18,6 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <errno.h>
|
||||
|
@ -39,7 +40,6 @@
|
|||
#include "curl_multi.h"
|
||||
#include "s3objlist.h"
|
||||
#include "cache.h"
|
||||
#include "mvnode.h"
|
||||
#include "addhead.h"
|
||||
#include "sighandlers.h"
|
||||
#include "s3fs_xml.h"
|
||||
|
@ -1736,9 +1736,7 @@ static int rename_directory(const char* from, const char* to)
|
|||
std::string nowcache; // now cache path(not used)
|
||||
dirtype DirType;
|
||||
bool normdir;
|
||||
MVNODE* mn_head = nullptr;
|
||||
MVNODE* mn_tail = nullptr;
|
||||
MVNODE* mn_cur;
|
||||
std::vector<mvnode> mvnodes;
|
||||
struct stat stbuf;
|
||||
int result;
|
||||
bool is_dir;
|
||||
|
@ -1746,7 +1744,7 @@ static int rename_directory(const char* from, const char* to)
|
|||
S3FS_PRN_INFO1("[from=%s][to=%s]", from, to);
|
||||
|
||||
//
|
||||
// Initiate and Add base directory into MVNODE struct.
|
||||
// Initiate and Add base directory into mvnode struct.
|
||||
//
|
||||
strto += "/";
|
||||
if(0 == chk_dir_object_type(from, newpath, strfrom, nowcache, nullptr, &DirType) && dirtype::UNKNOWN != DirType){
|
||||
|
@ -1756,9 +1754,7 @@ static int rename_directory(const char* from, const char* to)
|
|||
normdir = true;
|
||||
strfrom = from; // from directory is not removed, but from directory attr is needed.
|
||||
}
|
||||
if(nullptr == (add_mvnode(&mn_head, &mn_tail, strfrom.c_str(), strto.c_str(), true, normdir))){
|
||||
return -ENOMEM;
|
||||
}
|
||||
mvnodes.emplace_back(strfrom, strto, true, normdir);
|
||||
}else{
|
||||
// Something wrong about "from" directory.
|
||||
}
|
||||
|
@ -1806,20 +1802,20 @@ static int rename_directory(const char* from, const char* to)
|
|||
}
|
||||
|
||||
// push this one onto the stack
|
||||
if(nullptr == add_mvnode(&mn_head, &mn_tail, from_name.c_str(), to_name.c_str(), is_dir, normdir)){
|
||||
return -ENOMEM;
|
||||
}
|
||||
mvnodes.emplace_back(from_name, to_name, is_dir, normdir);
|
||||
}
|
||||
|
||||
std::sort(mvnodes.begin(), mvnodes.end(), [](const mvnode& a, const mvnode& b) { return a.old_path < b.old_path; });
|
||||
|
||||
//
|
||||
// rename
|
||||
//
|
||||
// rename directory objects.
|
||||
for(mn_cur = mn_head; mn_cur; mn_cur = mn_cur->next){
|
||||
if(mn_cur->is_dir && mn_cur->old_path && '\0' != mn_cur->old_path[0]){
|
||||
for(auto mn_cur = mvnodes.cbegin(); mn_cur != mvnodes.cend(); ++mn_cur){
|
||||
if(mn_cur->is_dir && !mn_cur->old_path.empty()){
|
||||
std::string xattrvalue;
|
||||
const char* pxattrvalue;
|
||||
if(get_meta_xattr_value(mn_cur->old_path, xattrvalue)){
|
||||
if(get_meta_xattr_value(mn_cur->old_path.c_str(), xattrvalue)){
|
||||
pxattrvalue = xattrvalue.c_str();
|
||||
}else{
|
||||
pxattrvalue = nullptr;
|
||||
|
@ -1829,9 +1825,8 @@ static int rename_directory(const char* from, const char* to)
|
|||
// The ctime is updated only for the top (from) directory.
|
||||
// Other than that, it will not be updated.
|
||||
//
|
||||
if(0 != (result = clone_directory_object(mn_cur->old_path, mn_cur->new_path, (strfrom == mn_cur->old_path), pxattrvalue))){
|
||||
if(0 != (result = clone_directory_object(mn_cur->old_path.c_str(), mn_cur->new_path.c_str(), (strfrom == mn_cur->old_path), pxattrvalue))){
|
||||
S3FS_PRN_ERR("clone_directory_object returned an error(%d)", result);
|
||||
free_mvnodes(mn_head);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1839,28 +1834,26 @@ static int rename_directory(const char* from, const char* to)
|
|||
|
||||
// iterate over the list - copy the files with rename_object
|
||||
// does a safe copy - copies first and then deletes old
|
||||
for(mn_cur = mn_head; mn_cur; mn_cur = mn_cur->next){
|
||||
for(auto mn_cur = mvnodes.begin(); mn_cur != mvnodes.end(); ++mn_cur){
|
||||
if(!mn_cur->is_dir){
|
||||
if(!nocopyapi && !norenameapi){
|
||||
result = rename_object(mn_cur->old_path, mn_cur->new_path, false); // keep ctime
|
||||
result = rename_object(mn_cur->old_path.c_str(), mn_cur->new_path.c_str(), false); // keep ctime
|
||||
}else{
|
||||
result = rename_object_nocopy(mn_cur->old_path, mn_cur->new_path, false); // keep ctime
|
||||
result = rename_object_nocopy(mn_cur->old_path.c_str(), mn_cur->new_path.c_str(), false); // keep ctime
|
||||
}
|
||||
if(0 != result){
|
||||
S3FS_PRN_ERR("rename_object returned an error(%d)", result);
|
||||
free_mvnodes(mn_head);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over old the directories, bottoms up and remove
|
||||
for(mn_cur = mn_tail; mn_cur; mn_cur = mn_cur->prev){
|
||||
if(mn_cur->is_dir && mn_cur->old_path && '\0' != mn_cur->old_path[0]){
|
||||
for(auto mn_cur = mvnodes.rbegin(); mn_cur != mvnodes.rend(); ++mn_cur){
|
||||
if(mn_cur->is_dir && !mn_cur->old_path.empty()){
|
||||
if(!(mn_cur->is_normdir)){
|
||||
if(0 != (result = s3fs_rmdir(mn_cur->old_path))){
|
||||
if(0 != (result = s3fs_rmdir(mn_cur->old_path.c_str()))){
|
||||
S3FS_PRN_ERR("s3fs_rmdir returned an error(%d)", result);
|
||||
free_mvnodes(mn_head);
|
||||
return result;
|
||||
}
|
||||
}else{
|
||||
|
@ -1869,7 +1862,6 @@ static int rename_directory(const char* from, const char* to)
|
|||
}
|
||||
}
|
||||
}
|
||||
free_mvnodes(mn_head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
17
src/types.h
17
src/types.h
|
@ -322,6 +322,23 @@ inline off_t total_mp_part_list(const mp_part_list_t& mplist)
|
|||
return size;
|
||||
}
|
||||
|
||||
//
|
||||
// Rename directory struct
|
||||
//
|
||||
struct mvnode
|
||||
{
|
||||
mvnode(std::string old_path, std::string new_path, bool is_dir, bool is_normdir)
|
||||
: old_path(std::move(old_path))
|
||||
, new_path(std::move(new_path))
|
||||
, is_dir(is_dir)
|
||||
, is_normdir(is_normdir)
|
||||
{}
|
||||
std::string old_path;
|
||||
std::string new_path;
|
||||
bool is_dir;
|
||||
bool is_normdir;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// mimes_t
|
||||
//-------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue