WIP Remove special meaning of root directory inode
Test / buildenv (push) Successful in 12s Details
Test / build (push) Successful in 2m57s Details
Test / test_cas (push) Successful in 10s Details
Test / make_test (push) Successful in 37s Details
Test / test_change_pg_size (push) Successful in 9s Details
Test / test_change_pg_count (push) Successful in 44s Details
Test / test_change_pg_count_ec (push) Successful in 38s Details
Test / test_create_nomaxid (push) Successful in 8s Details
Test / test_etcd_fail (push) Successful in 1m8s Details
Test / test_interrupted_rebalance_imm (push) Successful in 1m53s Details
Test / test_add_osd (push) Successful in 2m47s Details
Test / test_failure_domain (push) Successful in 36s Details
Test / test_snapshot (push) Successful in 24s Details
Test / test_interrupted_rebalance_ec_imm (push) Successful in 1m23s Details
Test / test_interrupted_rebalance_ec (push) Successful in 2m16s Details
Test / test_snapshot_ec (push) Successful in 27s Details
Test / test_minsize_1 (push) Successful in 17s Details
Test / test_rm (push) Successful in 14s Details
Test / test_move_reappear (push) Successful in 21s Details
Test / test_snapshot_down (push) Successful in 27s Details
Test / test_snapshot_down_ec (push) Successful in 25s Details
Test / test_splitbrain (push) Successful in 17s Details
Test / test_snapshot_chain (push) Successful in 2m1s Details
Test / test_snapshot_chain_ec (push) Successful in 2m55s Details
Test / test_rebalance_verify (push) Successful in 3m16s Details
Test / test_rebalance_verify_imm (push) Successful in 3m24s Details
Test / test_write (push) Successful in 43s Details
Test / test_interrupted_rebalance (push) Failing after 10m8s Details
Test / test_rebalance_verify_ec (push) Successful in 3m32s Details
Test / test_write_no_same (push) Successful in 19s Details
Test / test_write_xor (push) Successful in 59s Details
Test / test_rebalance_verify_ec_imm (push) Successful in 4m50s Details
Test / test_heal_pg_size_2 (push) Successful in 4m12s Details
Test / test_heal_ec (push) Successful in 4m41s Details
Test / test_heal_csum_32k_dmj (push) Successful in 4m25s Details
Test / test_heal_csum_32k_dj (push) Successful in 6m3s Details
Test / test_heal_csum_32k (push) Successful in 6m34s Details
Test / test_heal_csum_4k_dmj (push) Successful in 6m24s Details
Test / test_heal_csum_4k_dj (push) Successful in 6m22s Details
Test / test_scrub (push) Successful in 36s Details
Test / test_scrub_zero_osd_2 (push) Successful in 44s Details
Test / test_scrub_xor (push) Successful in 43s Details
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 1m2s Details
Test / test_scrub_ec (push) Successful in 1m0s Details
Test / test_scrub_pg_size_3 (push) Failing after 1m59s Details
Test / test_heal_csum_4k (push) Successful in 5m27s Details

Vitaliy Filippov 2024-01-14 14:12:51 +03:00
parent 7e1ec1af72
commit 88d33d234f
1 changed files with 55 additions and 84 deletions

View File

@ -38,22 +38,6 @@ static int nfs3_null_proc(void *opaque, rpc_op_t *rop)
return 0;
}
static fattr3 get_root_attributes(nfs_client_t *self)
{
return (fattr3){
.type = NF3DIR,
.mode = 0755,
.nlink = 1,
.uid = (uint32_t)self->parent->root_uid,
.gid = (uint32_t)self->parent->root_gid,
.size = 4096,
.used = 4096,
.rdev = (specdata3){ 0 },
.fsid = self->parent->fsid,
.fileid = 1,
};
}
static nfstime3 nfstime_from_str(const std::string & s)
{
nfstime3 t;
@ -94,9 +78,11 @@ static fattr3 get_kv_attributes(nfs_client_t *self, uint64_t ino, json11::Json a
.nlink = (nlink == 0 ? 1 : (uint32_t)nlink),
.uid = (uint32_t)attrs["uid"].uint64_value(),
.gid = (uint32_t)attrs["gid"].uint64_value(),
.size = attrs["size"].uint64_value(),
.used = attrs["alloc"].uint64_value(),
.rdev = (specdata3){ (uint32_t)attrs["major"].uint64_value(), (uint32_t)attrs["minor"].uint64_value() },
.size = (type == NF3DIR ? 4096 : attrs["size"].uint64_value()),
.used = (type == NF3DIR ? 4096 : attrs["alloc"].uint64_value()),
.rdev = (type == NF3BLK || type == NF3CHR
? (specdata3){ (uint32_t)attrs["major"].uint64_value(), (uint32_t)attrs["minor"].uint64_value() }
: (specdata3){}),
.fsid = self->parent->fsid,
.fileid = ino,
.atime = atime,
@ -118,7 +104,11 @@ static std::string kv_direntry_key(uint64_t dir_ino, const std::string & filenam
return (char*)key + filename;
}
static const std::string kv_next_id_key = "id";
static uint64_t kv_root_inode = 1;
static const char *kv_next_id_key = "id";
static const char *kv_root_handle = "R";
static std::string kv_direntry_filename(const std::string & key)
{
@ -161,12 +151,7 @@ static uint64_t kv_fh_inode(const std::string & fh)
static bool kv_fh_valid(const std::string & fh)
{
return fh == "R" || fh.size() == 9 && fh[0] == 'S' || fh.size() > 17 && fh[0] == 'I';
}
static bool kv_fh_is_root(const std::string & fh)
{
return fh == "R";
return fh == kv_root_handle || fh.size() == 9 && fh[0] == 'S' || fh.size() > 17 && fh[0] == 'I';
}
// Attributes are always stored in the inode
@ -176,6 +161,12 @@ static void kv_read_inode(nfs_client_t *self, uint64_t ino,
auto key = kv_inode_key(ino);
self->parent->db->get(key, [=](int res, const std::string & value)
{
if (ino == kv_root_inode && res == -ENOENT)
{
// Allow root inode to not exist
cb(0, "", json11::Json(json11::Json::object{ { "type", NF3DIR } }));
return;
}
if (res < 0)
{
if (res != -ENOENT)
@ -206,18 +197,6 @@ static int nfs3_getattr_proc(void *opaque, rpc_op_t *rop)
rpc_queue_reply(rop);
return 0;
}
if (kv_fh_is_root(fh))
{
// Root entry
*reply = (GETATTR3res){
.status = NFS3_OK,
.resok = (GETATTR3resok){
.obj_attributes = get_root_attributes(self),
},
};
rpc_queue_reply(rop);
return 0;
}
auto ino = kv_fh_inode(fh);
kv_read_inode(self, ino, [=](int res, const std::string & value, json11::Json attrs)
{
@ -306,7 +285,7 @@ resume_1:
}, [st](int res, const std::string & cas_value)
{
st->cas_res = res;
return res == 0 && cas_value == st->ientry_text;
return (res == 0 || res == -ENOENT && st->ino == kv_root_inode) && cas_value == st->ientry_text;
});
return;
resume_2:
@ -367,14 +346,6 @@ static int nfs3_setattr_proc(void *opaque, rpc_op_t *rop)
delete st;
return 0;
}
if (kv_fh_is_root(fh))
{
// Root entry - silently ignore changes
*reply = (SETATTR3res){ .status = NFS3_OK };
rpc_queue_reply(rop);
delete st;
return 0;
}
st->ino = kv_fh_inode(fh);
if (args->new_attributes.size.set_it)
st->set_attrs["size"] = args->new_attributes.size.size;
@ -493,7 +464,7 @@ static int nfs3_readlink_proc(void *opaque, rpc_op_t *rop)
nfs_client_t *self = (nfs_client_t*)opaque;
READLINK3args *args = (READLINK3args*)rop->request;
READLINK3res *reply = (READLINK3res*)rop->reply;
if (!kv_fh_valid(args->symlink) || kv_fh_is_root(args->symlink))
if (!kv_fh_valid(args->symlink) || args->symlink == kv_root_handle)
{
// Invalid filehandle or trying to read symlink from root entry
*reply = (READLINK3res){ .status = NFS3ERR_INVAL };
@ -579,6 +550,7 @@ static int nfs3_read_proc(void *opaque, rpc_op_t *rop)
return 1;
}
// FIXME: Pack small files into "common inodes"
static void nfs_resize_write(nfs_client_t *self, rpc_op_t *rop, uint64_t inode, uint64_t new_size, uint64_t offset, uint64_t count, void *buf);
static int nfs3_write_proc(void *opaque, rpc_op_t *rop)
@ -1603,7 +1575,6 @@ static int nfs3_rename_proc(void *opaque, rpc_op_t *rop)
st->new_dir_ino = kv_fh_inode(args->to.dir);
st->old_name = args->from.name;
st->new_name = args->to.name;
// FIXME: 0 = root ino?
if (!st->old_dir_ino || !st->new_dir_ino || st->old_name == "" || st->new_name == "")
{
RENAME3res *reply = (RENAME3res*)rop->reply;
@ -1949,30 +1920,32 @@ resume_2:
cb(st->res);
return;
}
auto fh = kv_fh(st->parent_ino);
auto entry_size = 20 + 4/*len_pad4("..")*/ + (st->is_plus ? 8 + 88 + len_pad4(fh.size()) : 0);
if (st->reply_size + entry_size > st->maxcount)
{
st->eof = false;
auto cb = std::move(st->cb);
cb(0);
return;
}
entryplus3 dotdot;
dotdot.name = xdr_copy_string(st->rop->xdrs, "..");
dotdot.fileid = st->dir_ino;
dotdot.name_attributes = (post_op_attr){
// FIXME: maybe do not read parent attributes and leave them to a GETATTR?
.attributes_follow = 1,
.attributes = get_kv_attributes(st->self, st->parent_ino, st->parent_ientry),
};
dotdot.name_handle = (post_op_fh3){
.handle_follows = 1,
.handle = xdr_copy_string(st->rop->xdrs, fh),
};
st->entries.push_back(dotdot);
st->reply_size += entry_size;
}
auto fh = kv_fh(st->parent_ino);
auto entry_size = 20 + 4/*len_pad4("..")*/ + (st->is_plus ? 8 + 88 + len_pad4(fh.size()) : 0);
if (st->reply_size + entry_size > st->maxcount)
{
st->eof = false;
auto cb = std::move(st->cb);
cb(0);
return;
}
entryplus3 dotdot;
dotdot.name = xdr_copy_string(st->rop->xdrs, "..");
dotdot.fileid = st->dir_ino;
dotdot.name_attributes = (post_op_attr){
// FIXME: maybe do not read parent attributes and leave them to a GETATTR?
.attributes_follow = 1,
.attributes = get_kv_attributes(st->self,
st->parent_ino ? st->parent_ino : st->dir_ino,
st->parent_ino ? st->parent_ientry : st->ientry),
};
dotdot.name_handle = (post_op_fh3){
.handle_follows = 1,
.handle = xdr_copy_string(st->rop->xdrs, fh),
};
st->entries.push_back(dotdot);
st->reply_size += entry_size;
}
st->prefix = kv_direntry_key(st->dir_ino, "");
st->eof = true;
@ -2181,8 +2154,8 @@ static int nfs3_fsstat_proc(void *opaque, rpc_op_t *rop)
.status = NFS3_OK,
.resok = (FSSTAT3resok){
.obj_attributes = {
.attributes_follow = 1,
.attributes = get_root_attributes(self),
.attributes_follow = 0,
//.attributes = get_root_attributes(self),
},
.tbytes = tbytes, // total bytes
.fbytes = fbytes, // free bytes
@ -2199,12 +2172,11 @@ static int nfs3_fsstat_proc(void *opaque, rpc_op_t *rop)
static int nfs3_fsinfo_proc(void *opaque, rpc_op_t *rop)
{
nfs_client_t *self = (nfs_client_t*)opaque;
//nfs_client_t *self = (nfs_client_t*)opaque;
FSINFO3args *args = (FSINFO3args*)rop->request;
FSINFO3res *reply = (FSINFO3res*)rop->reply;
if (args->fsroot != "roothandle")
if (args->fsroot != kv_root_handle)
{
// Example error
*reply = (FSINFO3res){ .status = NFS3ERR_INVAL };
}
else
@ -2214,8 +2186,8 @@ static int nfs3_fsinfo_proc(void *opaque, rpc_op_t *rop)
.status = NFS3_OK,
.resok = (FSINFO3resok){
.obj_attributes = {
.attributes_follow = 1,
.attributes = get_root_attributes(self),
.attributes_follow = 0,
//.attributes = get_root_attributes(self),
},
.rtmax = 128*1024*1024,
.rtpref = 128*1024*1024,
@ -2242,15 +2214,13 @@ static int nfs3_pathconf_proc(void *opaque, rpc_op_t *rop)
//nfs_client_t *self = (nfs_client_t*)opaque;
PATHCONF3args *args = (PATHCONF3args*)rop->request;
PATHCONF3res *reply = (PATHCONF3res*)rop->reply;
if (args->object != "roothandle")
if (args->object != kv_root_handle)
{
// Example error
*reply = (PATHCONF3res){ .status = NFS3ERR_INVAL };
}
else
{
// Fill info
bool_t x = FALSE;
*reply = (PATHCONF3res){
.status = NFS3_OK,
.resok = (PATHCONF3resok){
@ -2258,7 +2228,8 @@ static int nfs3_pathconf_proc(void *opaque, rpc_op_t *rop)
// Without at least one reference to a non-constant value (local variable or something else),
// with gcc 8 we get "internal compiler error: side-effects element in no-side-effects CONSTRUCTOR" here
// FIXME: get rid of this after raising compiler requirement
.attributes_follow = x,
.attributes_follow = 0,
//.attributes = get_root_attributes(self),
},
.linkmax = 0,
.name_max = 255,
@ -2298,7 +2269,7 @@ static int mount3_mnt_proc(void *opaque, rpc_op_t *rop)
nfs_mountres3 *reply = (nfs_mountres3*)rop->reply;
u_int flavor = RPC_AUTH_NONE;
reply->fhs_status = MNT3_OK;
reply->mountinfo.fhandle = xdr_copy_string(rop->xdrs, "roothandle");
reply->mountinfo.fhandle = xdr_copy_string(rop->xdrs, kv_root_handle);
reply->mountinfo.auth_flavors.auth_flavors_len = 1;
reply->mountinfo.auth_flavors.auth_flavors_val = (u_int*)xdr_copy_string(rop->xdrs, (char*)&flavor, sizeof(u_int)).data;
rpc_queue_reply(rop);