mirror of
https://github.com/XTXMarkets/ternfs.git
synced 2025-12-21 10:40:04 -06:00
NFS support in kmod
This commit is contained in:
committed by
Francesco Mazzoli
parent
3eb784b1cf
commit
40afc8183e
@@ -6,6 +6,7 @@ obj-m += eggsfs.o
|
||||
eggsfs-objs += \
|
||||
dir.o \
|
||||
err.o \
|
||||
export.o \
|
||||
file.o \
|
||||
inode.o \
|
||||
kmod.o \
|
||||
|
||||
@@ -443,6 +443,7 @@ struct file_operations eggsfs_dir_operations = {
|
||||
.iterate = eggsfs_dir_read,
|
||||
.iterate_shared = eggsfs_dir_read,
|
||||
.release = eggsfs_dir_close,
|
||||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
int __init eggsfs_dir_init(void) {
|
||||
|
||||
133
kmod/export.c
Normal file
133
kmod/export.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "export.h"
|
||||
#include "inode.h"
|
||||
#include "metadata.h"
|
||||
#include <linux/exportfs.h>
|
||||
|
||||
enum eggsfs_fid_type {
|
||||
EGGSFS_FILEID_ROOT = 0,
|
||||
EGGSFS_FILEID_GEN = 1,
|
||||
EGGSFS_FILEID_GEN_PARENT = 2,
|
||||
};
|
||||
|
||||
struct eggsfs_fid64 {
|
||||
u64 ino;
|
||||
u64 parent_ino;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int eggsfs_fileid_length(int fileid_type) {
|
||||
switch (fileid_type) {
|
||||
case EGGSFS_FILEID_GEN:
|
||||
return 3;
|
||||
case EGGSFS_FILEID_GEN_PARENT:
|
||||
return 6;
|
||||
}
|
||||
return FILEID_INVALID;
|
||||
}
|
||||
|
||||
static int eggsfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, struct inode *parent) {
|
||||
struct eggsfs_fid64* fid64 = (struct eggsfs_fid64 *)fh;
|
||||
int fileid_type;
|
||||
int len;
|
||||
|
||||
if (!parent) {
|
||||
fileid_type = EGGSFS_FILEID_GEN;
|
||||
} else {
|
||||
fileid_type = EGGSFS_FILEID_GEN_PARENT;
|
||||
}
|
||||
|
||||
len = eggsfs_fileid_length(fileid_type);
|
||||
if (*max_len < len) {
|
||||
*max_len = len;
|
||||
return FILEID_INVALID;
|
||||
}
|
||||
*max_len = len;
|
||||
|
||||
switch (fileid_type) {
|
||||
case EGGSFS_FILEID_GEN_PARENT:
|
||||
fid64->parent_ino = EGGSFS_I(parent)->inode.i_ino;
|
||||
/*FALLTHRU*/
|
||||
case EGGSFS_FILEID_GEN:
|
||||
fid64->ino = EGGSFS_I(inode)->inode.i_ino;
|
||||
break;
|
||||
}
|
||||
|
||||
return fileid_type;
|
||||
}
|
||||
|
||||
static struct inode * eggsfs_nfs_get_inode(struct super_block *sb, u64 ino) {
|
||||
// NFS can sometimes send requests for ino 0. Fail them gracefully.
|
||||
if (ino == 0) {
|
||||
return ERR_PTR(-ESTALE);
|
||||
}
|
||||
|
||||
struct inode *inode = eggsfs_get_inode(sb, NULL, ino);
|
||||
if (IS_ERR(inode)) {
|
||||
eggsfs_info("returning error %ld as ESTALE", PTR_ERR(inode));
|
||||
return ERR_PTR(-ESTALE);
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
||||
static struct dentry * eggsfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fileid_type) {
|
||||
struct eggsfs_fid64 *fid64 = (struct eggsfs_fid64 *)fid;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
if (fh_len < eggsfs_fileid_length(fileid_type)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (fileid_type) {
|
||||
case EGGSFS_FILEID_GEN_PARENT:
|
||||
case EGGSFS_FILEID_GEN:
|
||||
inode = eggsfs_nfs_get_inode(sb, fid64->ino);
|
||||
break;
|
||||
}
|
||||
|
||||
return d_obtain_alias(inode);
|
||||
}
|
||||
|
||||
static struct dentry * eggsfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fileid_type) {
|
||||
struct eggsfs_fid64 *fid64 = (struct eggsfs_fid64 *)fid;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
if (fh_len < eggsfs_fileid_length(fileid_type)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (fileid_type) {
|
||||
case EGGSFS_FILEID_GEN_PARENT:
|
||||
inode = eggsfs_nfs_get_inode(sb, fid64->parent_ino);
|
||||
break;
|
||||
}
|
||||
|
||||
return d_obtain_alias(inode);
|
||||
}
|
||||
|
||||
static struct dentry * eggsfs_get_parent(struct dentry *child) {
|
||||
int err;
|
||||
u64 mtime;
|
||||
u64 owner;
|
||||
struct eggsfs_policy_body block_policy;
|
||||
struct eggsfs_policy_body span_policy;
|
||||
struct eggsfs_policy_body stripe_policy;
|
||||
err = eggsfs_shard_getattr_dir(
|
||||
(struct eggsfs_fs_info *)child->d_inode->i_sb->s_fs_info,
|
||||
child->d_inode->i_ino,
|
||||
&mtime,
|
||||
&owner,
|
||||
&block_policy,
|
||||
&span_policy,
|
||||
&stripe_policy
|
||||
);
|
||||
if (err != 0 ) {
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
return d_obtain_alias(eggsfs_nfs_get_inode(child->d_sb, owner));
|
||||
}
|
||||
|
||||
struct export_operations eggsfs_export_ops = {
|
||||
.encode_fh = eggsfs_encode_fh,
|
||||
.fh_to_dentry = eggsfs_fh_to_dentry,
|
||||
.fh_to_parent = eggsfs_fh_to_parent,
|
||||
.get_parent = eggsfs_get_parent,
|
||||
};
|
||||
8
kmod/export.h
Normal file
8
kmod/export.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _EGGSFS_EXPORT_H
|
||||
#define _EGGSFS_EXPORT_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
extern struct export_operations eggsfs_export_ops;
|
||||
|
||||
#endif /* _EGGSFS_EXPORT_H */
|
||||
22
kmod/inode.c
22
kmod/inode.c
@@ -91,6 +91,7 @@ again: // progress: whoever wins the lock won't try again
|
||||
bool has_atime = false;
|
||||
u64 atime;
|
||||
if (S_ISDIR(enode->inode.i_mode)) {
|
||||
u64 owner;
|
||||
struct eggsfs_policy_body block_policy;
|
||||
struct eggsfs_policy_body span_policy;
|
||||
struct eggsfs_policy_body stripe_policy;
|
||||
@@ -98,6 +99,7 @@ again: // progress: whoever wins the lock won't try again
|
||||
(struct eggsfs_fs_info*)enode->inode.i_sb->s_fs_info,
|
||||
enode->inode.i_ino,
|
||||
&mtime,
|
||||
&owner,
|
||||
&block_policy,
|
||||
&span_policy,
|
||||
&stripe_policy
|
||||
@@ -178,6 +180,12 @@ static struct eggsfs_inode* eggsfs_create_internal(struct inode* parent, int ity
|
||||
|
||||
BUG_ON(dentry->d_inode);
|
||||
|
||||
if (current->group_leader->mm == NULL) {
|
||||
// internal-repo/blob/main/docs/kmod-file-tracking.md
|
||||
eggsfs_warn("current->group_leader->mm = NULL, called from kernel thread?");
|
||||
return(ERR_PTR(-EIO));
|
||||
}
|
||||
|
||||
struct eggsfs_inode* parent_enode = EGGSFS_I(parent);
|
||||
|
||||
if (dentry->d_name.len > EGGSFS_MAX_FILENAME) { return ERR_PTR(-ENAMETOOLONG); }
|
||||
@@ -424,10 +432,16 @@ struct inode* eggsfs_get_inode(struct super_block* sb, struct eggsfs_inode* pare
|
||||
enode->span_policy = parent->span_policy;
|
||||
enode->stripe_policy = parent->stripe_policy;
|
||||
} else {
|
||||
BUG_ON(ino != EGGSFS_ROOT_INODE);
|
||||
enode->block_policy = NULL;
|
||||
enode->span_policy = NULL;
|
||||
enode->stripe_policy = NULL;
|
||||
if (ino != EGGSFS_ROOT_INODE) {
|
||||
struct eggsfs_inode* root = EGGSFS_I(sb->s_root->d_inode);
|
||||
enode->block_policy = root->block_policy;
|
||||
enode->span_policy = root->span_policy;
|
||||
enode->stripe_policy = root->stripe_policy;
|
||||
} else {
|
||||
enode->block_policy = NULL;
|
||||
enode->span_policy = NULL;
|
||||
enode->stripe_policy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unlock_new_inode(inode);
|
||||
|
||||
@@ -482,6 +482,7 @@ int eggsfs_shard_getattr_dir(
|
||||
struct eggsfs_fs_info* info,
|
||||
u64 dir,
|
||||
u64* mtime,
|
||||
u64* owner,
|
||||
struct eggsfs_policy_body* block_policies,
|
||||
struct eggsfs_policy_body* span_policies,
|
||||
struct eggsfs_policy_body* stripe_policy
|
||||
@@ -508,8 +509,8 @@ int eggsfs_shard_getattr_dir(
|
||||
PREPARE_SHARD_RESP_CTX();
|
||||
eggsfs_stat_directory_resp_get_start(&ctx, start);
|
||||
eggsfs_stat_directory_resp_get_mtime(&ctx, start, resp_mtime);
|
||||
eggsfs_stat_directory_resp_get_owner(&ctx, resp_mtime, owner);
|
||||
eggsfs_stat_directory_resp_get_info(&ctx, owner, resp_info);
|
||||
eggsfs_stat_directory_resp_get_owner(&ctx, resp_mtime, resp_owner);
|
||||
eggsfs_stat_directory_resp_get_info(&ctx, resp_owner, resp_info);
|
||||
eggsfs_directory_info_get_entries(&ctx, resp_info, entries);
|
||||
int i;
|
||||
for (i = 0; i < entries.len; i++) {
|
||||
@@ -536,6 +537,7 @@ int eggsfs_shard_getattr_dir(
|
||||
eggsfs_stat_directory_resp_get_finish(&ctx, end);
|
||||
FINISH_RESP();
|
||||
*mtime = resp_mtime.x;
|
||||
*owner = resp_owner.x;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -26,6 +26,7 @@ int eggsfs_shard_getattr_dir(
|
||||
struct eggsfs_fs_info* info,
|
||||
u64 file,
|
||||
u64* mtime,
|
||||
u64* owner,
|
||||
struct eggsfs_policy_body* block_policies,
|
||||
struct eggsfs_policy_body* span_policies,
|
||||
struct eggsfs_policy_body* stripe_policy
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "inode.h"
|
||||
#include "export.h"
|
||||
#include "metadata.h"
|
||||
#include "dentry.h"
|
||||
#include "net.h"
|
||||
@@ -337,6 +338,7 @@ static struct dentry* eggsfs_mount(struct file_system_type* fs_type, int flags,
|
||||
|
||||
sb->s_op = &eggsfs_super_ops;
|
||||
sb->s_d_op = &eggsfs_dentry_ops;
|
||||
sb->s_export_op = &eggsfs_export_ops;
|
||||
|
||||
sb->s_time_gran = 1;
|
||||
sb->s_time_min = 0;
|
||||
|
||||
Reference in New Issue
Block a user