Skip to content

Commit

Permalink
feat(mount,master): Add fs_inode_from_path feature
Browse files Browse the repository at this point in the history
This commit adds the correspoding changes to add a new function to be
used in the client module so that it can directly request a given inode
from its path from the master server.

Signed-off-by: rolysr <rolysr@leil.io>
  • Loading branch information
rolysr committed Jan 17, 2025
1 parent c1f6c26 commit de66ef9
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 34 deletions.
38 changes: 38 additions & 0 deletions src/master/filesystem_operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,44 @@ uint8_t fs_full_path_by_inode(const FsContext &context, uint32_t initial_inode,
return SAUNAFS_STATUS_OK;
}

uint8_t fs_inode_from_path(const FsContext &context, std::string fullPath,
uint32_t &inode) {
uint32_t current_inode = context.rootinode();
FSNode *current_node = fsnodes_id_to_node(current_inode);
std::string current_name = "";
int current_path_len = 0;
int current_name_len = 0;
int full_path_len = fullPath.length();
inode = 0;

if (fullPath[0] != '/') {
current_path_len = 1;
}

while (current_path_len != full_path_len) {

if (fullPath[current_path_len] != '/' && current_path_len != full_path_len) {
current_name += fullPath[current_path_len];
current_path_len++;
current_name_len++;
} else {
HString hname = HString(current_name.c_str(), current_name_len);
if (fsnodes_namecheck(hname) < 0) { return SAUNAFS_ERROR_EINVAL; }
current_node = fsnodes_lookup(
static_cast<FSNodeDirectory *>(current_node), hname);
current_inode = current_node->id;
current_name = "";
current_name_len = 0;
if (current_path_len != full_path_len) {
current_path_len++;
}
}
}

inode = current_inode;
return SAUNAFS_STATUS_OK;
}

uint8_t fs_getattr(const FsContext &context, uint32_t inode, Attributes &attr) {
FSNode *p;

Expand Down
29 changes: 29 additions & 0 deletions src/master/matoclserv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,32 @@ void matoclserv_sau_full_path_by_inode(matoclserventry *eptr, const uint8_t *dat
eptr->sesdata->currentopstats[3]++;
}

void matoclserv_sau_inode_from_path(matoclserventry *eptr, const uint8_t *data,
uint32_t length) {
uint32_t msgid;
uint32_t inode;
std::string fullPath;
uint32_t uid, gid;
uint8_t status = SAUNAFS_STATUS_OK;

cltoma::inodeFromPath::deserialize(data, length, msgid, fullPath, uid, gid);

status = matoclserv_check_group_cache(eptr, gid);
if (status == SAUNAFS_STATUS_OK) {
FsContext context = matoclserv_get_context(eptr, uid, gid);
status = fs_inode_from_path(context, fullPath, inode);
}

if (status != SAUNAFS_STATUS_OK) {
matoclserv_createpacket(eptr,
matocl::inodeFromPath::build(msgid, status));
} else {
matoclserv_createpacket(
eptr, matocl::inodeFromPath::build(msgid, inode));
}
eptr->sesdata->currentopstats[3]++;
}

void matoclserv_fuse_lookup(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
uint32_t inode,uid,gid;
uint8_t nleng;
Expand Down Expand Up @@ -5128,6 +5154,9 @@ void matoclserv_gotpacket(matoclserventry *eptr,uint32_t type,const uint8_t *dat
case SAU_CLTOMA_FULL_PATH_BY_INODE:
matoclserv_sau_full_path_by_inode(eptr, data, length);
break;
case SAU_CLTOMA_INODE_FROM_PATH:
matoclserv_sau_inode_from_path(eptr, data, length);
break;
case SAU_CLTOMA_CSERV_LIST:
matoclserv_sau_cserv_list(eptr, data, length);
break;
Expand Down
2 changes: 0 additions & 2 deletions src/mount/fuse/sfs_meta_fuse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ static Attributes masterinfoattr={{'f', 0x01,0x24, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,
(SAUNAFS_PACKAGE_VERSION_MINOR)*1000 + \
(SAUNAFS_PACKAGE_VERSION_MICRO))

#define IS_SPECIAL_INODE(inode) ((inode)>=SPECIAL_INODE_BASE || (inode)==SPECIAL_INODE_ROOT)

static int debug_mode = 0;
static double entry_cache_timeout = 0.0;
static double attr_cache_timeout = 1.0;
Expand Down
52 changes: 52 additions & 0 deletions src/mount/mastercomm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2807,6 +2807,58 @@ uint8_t fs_fullpath(uint32_t inode, uint32_t uid,
}
}

uint8_t fs_inode_from_path(std::string fullPath, uint32_t uid, uint32_t gid,
uint32_t &inode) {
uint32_t nleng;
nleng = strlen(fullPath.c_str());
if (nleng > SFS_NAME_MAX) {
return SAUNAFS_ERROR_ENAMETOOLONG;
}

uint32_t ino = SaunaClient::getSpecialInodeByName(fullPath.c_str());
if (IS_SPECIAL_INODE(ino)) {
inode = ino;
return SAUNAFS_STATUS_OK;
}

threc *rec = fs_get_my_threc();
auto message =
cltoma::inodeFromPath::build(rec->packetId, fullPath, uid, gid);
if (!fs_saucreatepacket(rec, message)) { return SAUNAFS_ERROR_IO; }
if (!fs_sausendandreceive(rec, SAU_MATOCL_INODE_FROM_PATH, message)) {
return SAUNAFS_ERROR_IO;
}
try {
uint32_t msgid;
PacketVersion packet_version;
deserializePacketVersionNoHeader(message, packet_version);
if (packet_version == matocl::inodeFromPath::kStatusPacketVersion) {
uint8_t status;
matocl::inodeFromPath::deserialize(message, msgid, status);
if (status == SAUNAFS_STATUS_OK) {
fs_got_inconsistent("SAU_MATOCL_INODE_FROM_PATH",
message.size(),
"version 0 and SAUNAFS_STATUS_OK");
return SAUNAFS_ERROR_IO;
}
return status;
} else if (packet_version ==
matocl::inodeFromPath::kResponsePacketVersion) {
matocl::inodeFromPath::deserialize(message, msgid, inode);
return SAUNAFS_STATUS_OK;
} else {
fs_got_inconsistent(
"SAU_MATOCL_INODE_FROM_PATH", message.size(),
"unknown version " + std::to_string(packet_version));
return SAUNAFS_ERROR_IO;
}
} catch (Exception &ex) {
fs_got_inconsistent("SAU_MATOCL_INODE_FROM_PATH", message.size(),
ex.what());
return SAUNAFS_ERROR_IO;
}
}

static uint32_t* msgIdPtr(const MessageBuffer& buffer) {
PacketHeader header;
deserializePacketHeader(buffer, header);
Expand Down
1 change: 1 addition & 0 deletions src/mount/mastercomm.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ uint8_t fs_getacl(uint32_t inode, uint32_t uid, uint32_t gid, RichACL& acl, uint
uint8_t fs_setacl(uint32_t inode, uint32_t uid, uint32_t gid, const RichACL& acl);
uint8_t fs_setacl(uint32_t inode, uint32_t uid, uint32_t gid, AclType type, const AccessControlList& acl);
uint8_t fs_fullpath(uint32_t inode, uint32_t uid, uint32_t gid, std::string &fullPath);
uint8_t fs_inode_from_path(std::string fullPath, uint32_t uid, uint32_t gid, uint32_t &inode);

uint8_t fs_getreserved(const uint8_t **dbuff,uint32_t *dbuffsize);
uint8_t fs_getreserved(SaunaClient::NamedInodeOffset off, SaunaClient::NamedInodeOffset max_entries,
Expand Down
32 changes: 0 additions & 32 deletions src/mount/sauna_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,6 @@ namespace SaunaClient {
// 0x01b6 == 0666
// static uint8_t masterattr[35]={'f', 0x01,0xB6, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0,0,0,0,0};

#define IS_SPECIAL_INODE(ino) ((ino)>=SPECIAL_INODE_BASE)
#define IS_SPECIAL_NAME(name) ((name)[0]=='.' && (strcmp(SPECIAL_FILE_NAME_STATS,(name))==0 \
|| strcmp(SPECIAL_FILE_NAME_MASTERINFO,(name))==0 || strcmp(SPECIAL_FILE_NAME_OPLOG,(name))==0 \
|| strcmp(SPECIAL_FILE_NAME_OPHISTORY,(name))==0 || strcmp(SPECIAL_FILE_NAME_TWEAKS,(name))==0 \
|| strcmp(SPECIAL_FILE_NAME_FILE_BY_INODE,(name))==0 || strcmp(SPECIAL_FILE_NAME_PATH_BY_INODE,(name))==0))

static GroupCache gGroupCache;

struct ReaddirSession {
Expand Down Expand Up @@ -176,32 +170,6 @@ static void registerGroupsInMaster(Context &ctx) {
}
}

Inode getSpecialInodeByName(const char *name) {
assert(name);

while (name[0] == '/') {
++name;
}

if (strcmp(name, SPECIAL_FILE_NAME_MASTERINFO) == 0) {
return SPECIAL_INODE_MASTERINFO;
} else if (strcmp(name, SPECIAL_FILE_NAME_STATS) == 0) {
return SPECIAL_INODE_STATS;
} else if (strcmp(name, SPECIAL_FILE_NAME_TWEAKS) == 0) {
return SPECIAL_INODE_TWEAKS;
} else if (strcmp(name, SPECIAL_FILE_NAME_OPLOG) == 0) {
return SPECIAL_INODE_OPLOG;
} else if (strcmp(name, SPECIAL_FILE_NAME_OPHISTORY) == 0) {
return SPECIAL_INODE_OPHISTORY;
} else if (strcmp(name, SPECIAL_FILE_NAME_FILE_BY_INODE) == 0) {
return SPECIAL_INODE_FILE_BY_INODE;
} else if (strcmp(name, SPECIAL_FILE_NAME_PATH_BY_INODE) == 0) {
return SPECIAL_INODE_PATH_BY_INODE;
} else {
return MAX_REGULAR_INODE;
}
}

bool isSpecialInode(Inode ino) {
return IS_SPECIAL_INODE(ino);
}
Expand Down
33 changes: 33 additions & 0 deletions src/mount/sauna_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include "common/chunk_with_address_and_label.h"
#include "common/exception.h"
#include "common/special_inode_defs.h"
#include "mount/group_cache.h"
#include "mount/sauna_client_context.h"
#include "mount/readdata_cache.h"
Expand All @@ -45,6 +46,12 @@
#define USE_LOCAL_ID -1
#endif

#define IS_SPECIAL_INODE(ino) ((ino)>=SPECIAL_INODE_BASE || (ino)==SPECIAL_INODE_ROOT)
#define IS_SPECIAL_NAME(name) ((name)[0]=='.' && (strcmp(SPECIAL_FILE_NAME_STATS,(name))==0 \
|| strcmp(SPECIAL_FILE_NAME_MASTERINFO,(name))==0 || strcmp(SPECIAL_FILE_NAME_OPLOG,(name))==0 \
|| strcmp(SPECIAL_FILE_NAME_OPHISTORY,(name))==0 || strcmp(SPECIAL_FILE_NAME_TWEAKS,(name))==0 \
|| strcmp(SPECIAL_FILE_NAME_FILE_BY_INODE,(name))==0 || strcmp(SPECIAL_FILE_NAME_PATH_BY_INODE,(name))==0))

namespace SaunaClient {

typedef uint32_t Inode;
Expand Down Expand Up @@ -470,4 +477,30 @@ std::vector<ChunkserverListEntry> getchunkservers();
void fs_init(FsInitParams &params);
void fs_term();

inline Inode getSpecialInodeByName(const char *name) {
assert(name);

while (name[0] == '/') {
++name;
}

if (strcmp(name, SPECIAL_FILE_NAME_MASTERINFO) == 0) {
return SPECIAL_INODE_MASTERINFO;
} else if (strcmp(name, SPECIAL_FILE_NAME_STATS) == 0) {
return SPECIAL_INODE_STATS;
} else if (strcmp(name, SPECIAL_FILE_NAME_TWEAKS) == 0) {
return SPECIAL_INODE_TWEAKS;
} else if (strcmp(name, SPECIAL_FILE_NAME_OPLOG) == 0) {
return SPECIAL_INODE_OPLOG;
} else if (strcmp(name, SPECIAL_FILE_NAME_OPHISTORY) == 0) {
return SPECIAL_INODE_OPHISTORY;
} else if (strcmp(name, SPECIAL_FILE_NAME_FILE_BY_INODE) == 0) {
return SPECIAL_INODE_FILE_BY_INODE;
} else if (strcmp(name, SPECIAL_FILE_NAME_PATH_BY_INODE) == 0) {
return SPECIAL_INODE_PATH_BY_INODE;
} else {
return MAX_REGULAR_INODE;
}
}

}
6 changes: 6 additions & 0 deletions src/protocol/SFSCommunication.h
Original file line number Diff line number Diff line change
Expand Up @@ -1749,6 +1749,12 @@ enum class SugidClearMode {
// 0x646
#define SAU_MATOCL_FULL_PATH_BY_INODE (1000U + 606U)

// 0x647
#define SAU_CLTOMA_INODE_FROM_PATH (1000U + 607U)

// 0x648
#define SAU_MATOCL_INODE_FROM_PATH (1000U + 608U)

// CHUNKSERVER STATS

// 0x0258
Expand Down
6 changes: 6 additions & 0 deletions src/protocol/cltoma.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,12 @@ SAUNAFS_DEFINE_PACKET_SERIALIZATION(cltoma, fullPathByInode, SAU_CLTOMA_FULL_PAT
uint32_t, uid,
uint32_t, gid)

SAUNAFS_DEFINE_PACKET_SERIALIZATION(cltoma, inodeFromPath, SAU_CLTOMA_INODE_FROM_PATH, 0,
uint32_t, messageId,
std::string, fullPath,
uint32_t, uid,
uint32_t, gid)

SAUNAFS_DEFINE_PACKET_SERIALIZATION(
cltoma, recursiveRemove, SAU_CLTOMA_RECURSIVE_REMOVE, 0,
uint32_t, msgid,
Expand Down
14 changes: 14 additions & 0 deletions src/protocol/matocl.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,20 @@ SAUNAFS_DEFINE_PACKET_SERIALIZATION(
uint32_t, messageId,
std::string, fullPath)

// SAU_MATOCL_INODE_FROM_PATH
SAUNAFS_DEFINE_PACKET_VERSION(matocl, inodeFromPath, kStatusPacketVersion, 0)
SAUNAFS_DEFINE_PACKET_VERSION(matocl, inodeFromPath, kResponsePacketVersion, 1)

SAUNAFS_DEFINE_PACKET_SERIALIZATION(
matocl, inodeFromPath, SAU_MATOCL_INODE_FROM_PATH, kStatusPacketVersion,
uint32_t, messageId,
uint8_t, status)

SAUNAFS_DEFINE_PACKET_SERIALIZATION(
matocl, inodeFromPath, SAU_MATOCL_INODE_FROM_PATH, kResponsePacketVersion,
uint32_t, messageId,
uint32_t, inode)

SAUNAFS_DEFINE_PACKET_SERIALIZATION(
matocl, recursiveRemove, SAU_MATOCL_RECURSIVE_REMOVE, 0,
uint32_t, msgid,
Expand Down

0 comments on commit de66ef9

Please sign in to comment.