Skip to content

Commit cbd9d85

Browse files
committed
lxfs: partial implementation of open()
1 parent 2f5b720 commit cbd9d85

File tree

3 files changed

+109
-6
lines changed

3 files changed

+109
-6
lines changed

fs/lxfs/src/dirtree.c

+85-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
/* pathDepth(): helper function to calculate the depth of a path
1414
* params: path - full qualified path
15-
* returns: maximum depth of the path
15+
* returns: maximum depth of the path, zero for root directory, ONE-BASED elsewhere
1616
*/
1717

1818
int pathDepth(const char *path) {
1919
if(!path || !strlen(path) || strlen(path) == 1) return 0;
2020

21-
int c = 0;
21+
int c = 1;
2222
for(int i = 0; i < strlen(path); i++) {
2323
if(path[i] == '/') c++;
2424
}
@@ -37,6 +37,11 @@ char *pathComponent(char *dest, const char *path, int n) {
3737
int depth = pathDepth(path);
3838
if(n > depth) return NULL;
3939

40+
if(depth <= 1) {
41+
// special case for files on the root directory
42+
return strcpy(dest, path);
43+
}
44+
4045
int c = 0;
4146
int len = 0;
4247
for(int i = 0; i < strlen(path); i++) {
@@ -65,5 +70,82 @@ char *pathComponent(char *dest, const char *path, int n) {
6570
*/
6671

6772
LXFSDirectoryEntry *lxfsFind(LXFSDirectoryEntry *dest, Mountpoint *mp, const char *path) {
68-
return NULL; // stub
73+
// special case for the root directory because it does not have a true
74+
// directory entry within the file system itself
75+
if((strlen(path) == 1) && (path[0] == '/')) {
76+
if(lxfsReadBlock(mp, mp->root, mp->dataBuffer)) return NULL;
77+
78+
LXFSDirectoryHeader *root = (LXFSDirectoryHeader *) mp->dataBuffer;
79+
dest->size = root->sizeEntries;
80+
dest->accessTime = root->accessTime;
81+
dest->createTime = root->createTime;
82+
dest->modTime = root->modTime;
83+
dest->name[0] = 0;
84+
dest->flags = LXFS_DIR_VALID | (LXFS_DIR_TYPE_DIR << LXFS_DIR_TYPE_SHIFT);
85+
dest->block = mp->root;
86+
87+
// root directory is owned by root:root and its mode is rwxr-xr-x
88+
dest->owner = 0;
89+
dest->group = 0;
90+
dest->permissions = LXFS_PERMS_OWNER_R | LXFS_PERMS_OWNER_W | LXFS_PERMS_OWNER_X | LXFS_PERMS_GROUP_R | LXFS_PERMS_GROUP_X | LXFS_PERMS_OTHER_R | LXFS_PERMS_OTHER_X;
91+
92+
return dest;
93+
}
94+
95+
// for everything else we will need to traverse the file system starting
96+
// at the root directory
97+
LXFSDirectoryEntry *dir;
98+
uint64_t next = mp->root;
99+
int depth = pathDepth(path);
100+
char component[MAX_FILE_PATH];
101+
102+
int i = 0;
103+
104+
traverse:
105+
while(i < depth) {
106+
// iterate over each component in the path and search for it in the directory
107+
if(!pathComponent(component, path, i)) return NULL;
108+
109+
next = lxfsReadNextBlock(mp, next, mp->dataBuffer);
110+
if(!next) return NULL;
111+
112+
// read two blocks at a time for entries that cross boundaries
113+
if(next != LXFS_BLOCK_EOF)
114+
lxfsReadNextBlock(mp, next, mp->dataBuffer + mp->blockSizeBytes);
115+
116+
dir = (LXFSDirectoryEntry *)((uintptr_t)mp->dataBuffer + sizeof(LXFSDirectoryHeader));
117+
off_t offset = sizeof(LXFSDirectoryHeader);
118+
119+
while(offset < mp->blockSizeBytes) {
120+
if((dir->flags & LXFS_DIR_VALID) && !strcmp((const char *) dir->name, component)) {
121+
if(i == depth-1) {
122+
// found the file we're looking for
123+
return (LXFSDirectoryEntry *) memcpy(dest, dir, dir->entrySize);
124+
} else {
125+
// found a parent directory
126+
i++;
127+
luxLogf(KPRINT_LEVEL_WARNING, "TODO: implement directory trees\n");
128+
}
129+
}
130+
131+
// advance to the next entry
132+
dir = (LXFSDirectoryEntry *)((uintptr_t)dir + dir->entrySize);
133+
offset += dir->entrySize;
134+
135+
if((offset >= mp->blockSizeBytes) && (next != LXFS_BLOCK_EOF)) {
136+
// copy the second block to the first block
137+
offset -= mp->blockSizeBytes;
138+
dir = (LXFSDirectoryEntry *)((uintptr_t)dir - mp->blockSizeBytes);
139+
memmove(mp->dataBuffer, mp->dataBuffer+mp->blockSizeBytes, mp->blockSizeBytes);
140+
141+
if(!dir->entrySize) return NULL;
142+
143+
// and read the next block
144+
next = lxfsReadNextBlock(mp, next, mp->dataBuffer);
145+
if(!next) return NULL;
146+
}
147+
}
148+
}
149+
150+
return NULL;
69151
}

fs/lxfs/src/mount.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void lxfsMount(MountCommand *cmd) {
9292
return;
9393
}
9494

95-
void *buffer2 = malloc(blockSizeBytes);
95+
void *buffer2 = malloc(blockSizeBytes*2);
9696
if(!buffer2) {
9797
cmd->header.header.status = -ENOMEM;
9898
close(fd);

fs/lxfs/src/open.c

+23-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ void lxfsOpen(OpenCommand *ocmd) {
2323
ocmd->header.header.response = 1;
2424
ocmd->header.header.length = sizeof(OpenCommand);
2525

26-
luxLogf(KPRINT_LEVEL_DEBUG, "opening %s on %s\n", ocmd->path, ocmd->device);
27-
2826
Mountpoint *mp = findMP(ocmd->device);
2927
if(!mp) {
3028
ocmd->header.header.status = -EIO; // device doesn't exist
@@ -38,4 +36,27 @@ void lxfsOpen(OpenCommand *ocmd) {
3836
luxSendDependency(ocmd);
3937
return;
4038
}
39+
40+
// ensure this is a file
41+
if(((entry.flags >> LXFS_DIR_TYPE_SHIFT) & LXFS_DIR_TYPE_MASK) != LXFS_DIR_TYPE_FILE) {
42+
luxLogf(KPRINT_LEVEL_DEBUG, "ISNT FILE\n");
43+
ocmd->header.header.status = -EISDIR;
44+
luxSendDependency(ocmd);
45+
return;
46+
}
47+
48+
// and that the requester has appropriate permissions
49+
ocmd->header.header.status = 0;
50+
if(ocmd->uid == entry.owner) {
51+
if((ocmd->flags & O_RDONLY) && !(entry.permissions & LXFS_PERMS_OWNER_R)) ocmd->header.header.status = -EACCES;
52+
if((ocmd->flags & O_WRONLY) && !(entry.permissions & LXFS_PERMS_OWNER_W)) ocmd->header.header.status = -EACCES;
53+
} else if(ocmd->gid == entry.group) {
54+
if((ocmd->flags & O_RDONLY) && !(entry.permissions & LXFS_PERMS_GROUP_R)) ocmd->header.header.status = -EACCES;
55+
if((ocmd->flags & O_WRONLY) && !(entry.permissions & LXFS_PERMS_GROUP_W)) ocmd->header.header.status = -EACCES;
56+
} else {
57+
if((ocmd->flags & O_RDONLY) && !(entry.permissions & LXFS_PERMS_OTHER_R)) ocmd->header.header.status = -EACCES;
58+
if((ocmd->flags & O_WRONLY) && !(entry.permissions & LXFS_PERMS_OTHER_W)) ocmd->header.header.status = -EACCES;
59+
}
60+
61+
luxSendDependency(ocmd);
4162
}

0 commit comments

Comments
 (0)