create for regular file; mknod for spcial file. include simplified fuse_common.h to register file descriptor

This commit is contained in:
Victor 2023-11-24 13:12:42 -08:00
parent 88a15eb1a8
commit 39d6ab26ff
4 changed files with 121 additions and 6 deletions

View File

@ -1,5 +1,6 @@
#include <sys/types.h>
#include <fs.h>
#include "fuse_common.h"
#include "direntry.h"
class FilesOperation {
@ -20,7 +21,8 @@ class FilesOperation {
u_int64_t disk_namei(const char* path);
u_int64_t namei(const char* path);
int fischl_mkdir(const char*, mode_t);
int fischl_mknod(const char*, mode_t);
int fischl_mknod(const char*, mode_t, dev_t);//for special file
int fischl_create(const char *, mode_t, struct fuse_file_info *);//for regular file
//int fischl_readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags);
int fischl_unlink (const char *);
//int fischl_open (const char *, struct fuse_file_info *);

82
include/fuse_common.h Normal file
View File

@ -0,0 +1,82 @@
#ifndef FUSE_COMMON_H_
#define FUSE_COMMON_H_
#include <stdint.h>
#include <sys/types.h>
/**
* Information about an open file.
*
* File Handles are created by the open, opendir, and create methods and closed
* by the release and releasedir methods. Multiple file handles may be
* concurrently open for the same file. Generally, a client will create one
* file handle per file descriptor, though in some cases multiple file
* descriptors can share a single file handle.
*/
struct fuse_file_info {
/** Open flags. Available in open() and release() */
int flags;
/** In case of a write operation indicates if this was caused
by a delayed write from the page cache. If so, then the
context's pid, uid, and gid fields will not be valid, and
the *fh* value may not match the *fh* value that would
have been sent with the corresponding individual write
requests if write caching had been disabled. */
unsigned int writepage : 1;
/** Can be filled in by open/create, to use direct I/O on this file. */
unsigned int direct_io : 1;
/** Can be filled in by open and opendir. It signals the kernel that any
currently cached data (ie., data that the filesystem provided the
last time the file/directory was open) need not be invalidated when
the file/directory is closed. */
unsigned int keep_cache : 1;
/** Can be filled by open/create, to allow parallel direct writes on this
* file */
unsigned int parallel_direct_writes : 1;
/** Indicates a flush operation. Set in flush operation, also
maybe set in highlevel lock operation and lowlevel release
operation. */
unsigned int flush : 1;
/** Can be filled in by open, to indicate that the file is not
seekable. */
unsigned int nonseekable : 1;
/* Indicates that flock locks for this file should be
released. If set, lock_owner shall contain a valid value.
May only be set in ->release(). */
unsigned int flock_release : 1;
/** Can be filled in by opendir. It signals the kernel to
enable caching of entries returned by readdir(). Has no
effect when set in other contexts (in particular it does
nothing when set by open()). */
unsigned int cache_readdir : 1;
/** Can be filled in by open, to indicate that flush is not needed
on close. */
unsigned int noflush : 1;
/** Padding. Reserved for future use*/
unsigned int padding : 23;
unsigned int padding2 : 32;
/** File handle id. May be filled in by filesystem in create,
* open, and opendir(). Available in most other file operations on the
* same file handle. */
uint64_t fh;
/** Lock owner id. Available in locking operations and flush */
uint64_t lock_owner;
/** Requested poll events. Available in ->poll. Only set on kernels
which support it. If unsupported, this field is set to zero. */
uint32_t poll_events;
};
#endif /* FUSE_COMMON_H_ */

View File

@ -281,8 +281,10 @@ int FilesOperation::fischl_mkdir(const char* path, mode_t mode) {
delete pathdup;
return 0;//SUCCESS
}
int FilesOperation::fischl_mknod(const char* path, mode_t mode) {
/*
special file
*/
int FilesOperation::fischl_mknod(const char* path, mode_t mode, dev_t dev) {
//check path
char *pathdup = strdup(path);
char *lastSlash = strrchr(pathdup, '/');
@ -305,6 +307,34 @@ int FilesOperation::fischl_mknod(const char* path, mode_t mode) {
delete pathdup;
return 0;//SUCESS
}
/*
regular file
*/
int FilesOperation::fischl_create(const char* path, mode_t mode, struct fuse_file_info* fi) {
//check path
char *pathdup = strdup(path);
char *lastSlash = strrchr(pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
char *newFilename = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take <parent path> only
// fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__, ParentPath, strlen(ParentPath));
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
if (parent_filenode == NULL) {
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
delete pathdup;
return -1;
}
u_int64_t parent_inode_number = parent_filenode->inode_number;
//make new inode
INode* ret = create_new_inode(parent_inode_number, newFilename, mode);
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
//make new node in RAM
fischl_add_entry(parent_filenode->subdirectory, ret->block_number, newFilename, ret);
//directly give inode number rather than create file descriptor table
fi->fh = ret->block_number;//assign file descriptor as inode number to fuse system
delete pathdup;
return 0;//SUCESS
}
void FilesOperation::unlink_inode(u_int64_t inode_number) {
INode inode;

View File

@ -37,14 +37,15 @@ int total_free_file = 0;
TEST(FileOperationTest, MkdirnodTest) {
fsop->initialize_rootinode();
struct fuse_file_info fi;
mode_t mode;//set mode
mode = S_IRWXU | S_IRWXG | S_IRWXO;//future should test permission
//S_IRWXU(S_IRUSR | S_IWUSR | S_IXUSR) (owner), S_IRWXG(S_IRGRP | S_IWGRP | S_IXGRP) (group), S_IRWXO(S_IROTH | S_IWOTH | S_IXOTH)
EXPECT_EQ(fsop->fischl_mknod("/test", mode), 0); // mode here is not used yet
EXPECT_EQ(fsop->fischl_create("/test", mode, &fi), 0); // mode here is not used yet
EXPECT_EQ(fsop->fischl_mkdir("/foo", mode), 0);
EXPECT_EQ(fsop->fischl_mkdir("/foo/bar", mode),0);
EXPECT_EQ(fsop->fischl_mknod("/foo/bar/baz", mode), 0);
EXPECT_EQ(fsop->fischl_create("/foo/bar/baz", mode, &fi), 0);
// the following three testcases will fail
EXPECT_TRUE(fsop->fischl_mkdir("foo/bar", mode) < 0);
EXPECT_TRUE(fsop->fischl_mkdir("/doesnt_exist/bar", mode) < 0);