Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit 7056569

Browse files
author
Bhavneet Singh
committedNov 2, 2014
Cleaned up a little
1 parent 38d535d commit 7056569

File tree

4 files changed

+110
-64
lines changed

4 files changed

+110
-64
lines changed
 

‎3600fs.c

+23-37
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ static int vfs_mkdir(const char *path, mode_t mode) {
335335
}
336336
}
337337

338-
// TODO: Out of memory message?
338+
// Out of memory message?
339339
return -1;
340340
}
341341

@@ -523,7 +523,6 @@ static int vfs_create(const char *path, mode_t mode, struct fuse_file_info *fi)
523523
}
524524
}
525525

526-
// TODO: Out of memory message?
527526
return -1;
528527
}
529528

@@ -825,7 +824,6 @@ file_loc get_file(char *abs_path, char *path, file_loc parent) {
825824
}
826825

827826
// Read data into a Dnode struct
828-
// TODO when implementing multi-directory, this will change
829827
dnode thisDnode = get_dnode(parent.node_block.block, buf);
830828

831829
// look at the right snippet of the path
@@ -977,8 +975,7 @@ int write_dnode(unsigned int b, char *buf, dnode d) {
977975
}
978976

979977
// Reads the inode at the given block number
980-
inode get_inode(unsigned int b) {
981-
char buf[BLOCKSIZE];
978+
inode get_inode(unsigned int b, char *buf) {
982979
// Allocate appropriate memory
983980
memset(buf, 0, BLOCKSIZE);
984981
// Read Dnode
@@ -990,6 +987,7 @@ inode get_inode(unsigned int b) {
990987
}
991988

992989
// Write the given inode (i) to disk at the given block (b)
990+
// The passed in buf should be of size BLOCKSIZE
993991
int write_inode(unsigned int b, char *buf, inode i) {
994992
// Allocate appropriate memory
995993
memset(buf, 0, BLOCKSIZE);
@@ -1004,6 +1002,7 @@ int write_inode(unsigned int b, char *buf, inode i) {
10041002
}
10051003

10061004
// Reads the db at the given block number into buf
1005+
// The passed in buf should be of size BLOCKSIZE
10071006
db get_db(unsigned int b, char *buf) {
10081007
// Allocate appropriate memory
10091008
memset(buf, 0, BLOCKSIZE);
@@ -1016,6 +1015,7 @@ db get_db(unsigned int b, char *buf) {
10161015
}
10171016

10181017
// Write the given db (d) to disk at the given block (b)
1018+
// The passed in buf should be of size BLOCKSIZE
10191019
int write_db(unsigned int b, char *buf, db d) {
10201020
// Allocate appropriate memory
10211021
memset(buf, 0, BLOCKSIZE);
@@ -1030,6 +1030,7 @@ int write_db(unsigned int b, char *buf, db d) {
10301030
}
10311031

10321032
// Reads the indirect at the given block number into buf
1033+
// The passed in buf should be of size BLOCKSIZE
10331034
indirect get_indirect2(unsigned int b, char *buf) {
10341035
// Allocate appropriate memory
10351036
memset(buf, 0, BLOCKSIZE);
@@ -1042,6 +1043,7 @@ indirect get_indirect2(unsigned int b, char *buf) {
10421043
}
10431044

10441045
// Write the given indirect (i) to disk at the given block (b)
1046+
// The passed in buf should be of size BLOCKSIZE
10451047
int write_indirect(unsigned int b, char *buf, indirect i) {
10461048
// Allocate appropriate memory
10471049
memset(buf, 0, BLOCKSIZE);
@@ -1095,6 +1097,7 @@ blocknum get_free() {
10951097
// If b is valid, it is the caller's responsibility to ensure that b is a
10961098
// blocknum to a dirent. The behavior if b is a valid blocknum to another
10971099
// structure type is undefined.
1100+
// The passed in buf should be of size BLOCKSIZE
10981101
file_loc get_inode_dirent(blocknum b, char *buf, const char *path) {
10991102

11001103
// the file_loc to return
@@ -1132,6 +1135,7 @@ file_loc get_inode_dirent(blocknum b, char *buf, const char *path) {
11321135
// Returns a file_loc to the file specified by path if it exists in the
11331136
// any dirent within the thisDnode.direct array. If not found, an invalid
11341137
// file_loc is returned.
1138+
// The passed in buf should be of size BLOCKSIZE
11351139
file_loc get_inode_direct_dirent(dnode *thisDnode, char *buf, const char *path) {
11361140

11371141
// the file_loc to return
@@ -1165,6 +1169,7 @@ file_loc get_inode_direct_dirent(dnode *thisDnode, char *buf, const char *path)
11651169
// If b is valid, it is the caller's responsibility to ensure that b is a
11661170
// blocknum to an indirect of dirents. The behavior if b is a valid blocknum
11671171
// to another structure type is undefined.
1172+
// The passed in buf should be of size BLOCKSIZE
11681173
file_loc get_inode_single_indirect_dirent(blocknum b, char *buf, const char *path) {
11691174

11701175
// the file_loc to return
@@ -1199,6 +1204,7 @@ file_loc get_inode_single_indirect_dirent(blocknum b, char *buf, const char *pat
11991204
// If b is valid, it is the caller's responsibility to ensure that b is a
12001205
// blocknum to an indirect of indirects of dirents. The behavior if b is a
12011206
// valid blocknum to another structure type is undefined.
1207+
// The passed in buf should be of size BLOCKSIZE
12021208
file_loc get_inode_double_indirect_dirent(blocknum b, char *buf, const char *path) {
12031209

12041210
// the file_loc to return
@@ -1227,18 +1233,6 @@ file_loc get_inode_double_indirect_dirent(blocknum b, char *buf, const char *pat
12271233
return loc;
12281234
}
12291235

1230-
// TODO: Multiple things have these structs.. can we abstract by passing a param???
1231-
// Access Single_indirect
1232-
blocknum get_single_block(int loc) {
1233-
// mod by 128 for single index
1234-
// divide by 128 for index in direct
1235-
}
1236-
// Access Double_indirect
1237-
blocknum get_double_block(int loc) {
1238-
// mod by 128 for index in double single index
1239-
// call get_single with loc/128
1240-
}
1241-
12421236
/*
12431237
* The function vfs_read provides the ability to read data from
12441238
* an absolute path 'path,' which should specify an existing file.
@@ -1264,11 +1258,10 @@ static int vfs_read(const char *path, char *buf, size_t size, off_t offset,
12641258
return -1;
12651259
}
12661260

1267-
// TODO use a helper function to get inode block
12681261
char tmp_buf[BLOCKSIZE];
12691262

12701263
// Get the inode
1271-
inode this_inode = get_inode(loc.node_block.block);
1264+
inode this_inode = get_inode(loc.node_block.block, tmp_buf);
12721265

12731266
// if the offset is larger than the size of the inode, no read possible
12741267
if (offset >= this_inode.size) {
@@ -1395,11 +1388,10 @@ static int vfs_write(const char *path, const char *buf, size_t size,
13951388
return -1;
13961389
}
13971390

1398-
// TODO use a helper function to get inode block
13991391
char tmp_buf[BLOCKSIZE];
14001392

14011393
// Get the inode
1402-
inode this_inode = get_inode(loc.node_block.block);
1394+
inode this_inode = get_inode(loc.node_block.block, tmp_buf);
14031395

14041396
// calculate the extra bytes we need to write to the file
14051397
int needed_bytes = offset + size;
@@ -1453,7 +1445,7 @@ static int vfs_write(const char *path, const char *buf, size_t size,
14531445
int loc_in_s = block_loc % indirect_blocks;
14541446
blocknum sing_blocknum = doub.blocks[s_loc];
14551447

1456-
// REMOVE THE NESCESSITY TO READ EVERYTIME
1448+
// REMOVE THE NECESSITY TO READ EVERYTIME
14571449
indirect new_sing = get_indirect2(sing_blocknum.block, tmp_buf);
14581450
all_blocks[i] = new_sing.blocks[loc_in_s];
14591451
}
@@ -1712,7 +1704,8 @@ static int vfs_delete(const char *path)
17121704
// Redult is stored in blocks array with size size.
17131705
void get_file_blocks(blocknum in, blocknum *blocks[], int *size) {
17141706
// Free the inode; free the inode's db blocks; free the inodes
1715-
inode this_inode = get_inode(in.block);
1707+
char tmp_buf[BLOCKSIZE];
1708+
inode this_inode = get_inode(in.block, tmp_buf);
17161709

17171710
// all the blocks; direct + single + double (single^2) + this file block
17181711
int all_blocks_size = NUM_DIRECT + NUM_INDIRECT_BLOCKS +
@@ -1794,15 +1787,15 @@ static int vfs_rename(const char *from, const char *to)
17941787
vfs_delete(to);
17951788

17961789
// Get the dirent and adjust the name...
1797-
// TODO: Should we abstarct this as well???
17981790
dirent this_dirent;
17991791
char buf[BLOCKSIZE];
18001792
dread(loc.dirent_block.block, buf);
18011793
memcpy(&this_dirent, buf, sizeof(dirent));
18021794

1795+
parent = get_root_dir();
1796+
file_loc to_loc = get_dir(to, to, &parent);
18031797
// Change the name at the proper direntry
1804-
// TODO: Change the +1
1805-
strncpy(this_dirent.entries[loc.direntry_idx].name, to+1, MAX_FILENAME_LEN);
1798+
strncpy(this_dirent.entries[loc.direntry_idx].name, to_loc.name, MAX_FILENAME_LEN);
18061799

18071800
// Write modified one to disk
18081801
memcpy(buf, &this_dirent, sizeof(dirent));
@@ -1814,7 +1807,6 @@ static int vfs_rename(const char *from, const char *to)
18141807
}
18151808

18161809
// No such file exists
1817-
// TODO: get this to work for directories
18181810
else {
18191811
return -1;
18201812
}
@@ -1841,14 +1833,10 @@ static int vfs_chmod(const char *file, mode_t mode)
18411833
// If the file exists, change mode
18421834
if (loc.valid) {
18431835
// Get the inode for the file
1844-
// TODO: Should we abstarct this as well???
1845-
inode this_inode;
18461836
char buf[BLOCKSIZE];
1847-
dread(loc.node_block.block, buf);
1848-
memcpy(&this_inode, buf, sizeof(inode));
1849-
1850-
// Change shit up
1851-
this_inode.mode = (mode_t) mode;
1837+
inode this_inode = get_inode(loc.node_block.block, buf);
1838+
//update the mode
1839+
this_inode.mode = (mode_t) mode;
18521840

18531841
// Write modified one to disk
18541842
memcpy(buf, &this_inode, sizeof(inode));
@@ -1858,7 +1846,6 @@ static int vfs_chmod(const char *file, mode_t mode)
18581846
}
18591847

18601848
// No such file exists
1861-
// TODO: get this to work for directories
18621849
else {
18631850
return -1;
18641851
}
@@ -1938,7 +1925,6 @@ static int vfs_utimens(const char *file, const struct timespec ts[2])
19381925
}
19391926

19401927
// No such file exists
1941-
// TODO: get this to work for directories
19421928
else {
19431929
return -1;
19441930
}
@@ -1966,7 +1952,7 @@ static int vfs_truncate(const char *file, off_t offset)
19661952

19671953
char tmp_buf[BLOCKSIZE];
19681954
// Get the inode
1969-
inode this_inode = get_inode(loc.node_block.block);
1955+
inode this_inode = get_inode(loc.node_block.block, tmp_buf);
19701956

19711957
// check if the offset exceeds the file size
19721958
if (this_inode.size - 1 < offset) {

‎3600fs.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ dnode get_dnode(unsigned int b, char *buf);
283283
int write_dnode(unsigned int b, char *buf, dnode d);
284284

285285
// Reads the inode at the given block number into buf
286-
inode get_inode(unsigned int b);
286+
inode get_inode(unsigned int b, char *buf);
287287

288288
// Write the given inode (i) to disk at the given block (b)
289289
int write_inode(unsigned int b, char *buf, inode i);

‎README

+84-4
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,88 @@ use Piazza to ask questions if you're stuck.
3737

3838

3939
******************************************************************************
40-
Reasoning/Approach
40+
Disk Layout/Choice:
41+
42+
We made an Inode file system; we chose this because it seemed like an
43+
interesting challenge, and the professor mentioned it would be easier
44+
to implement recursive directories.
45+
46+
47+
High Level Approach:
48+
49+
Abstract as much as possible and try to avoid writing repeat code.
50+
We made an awesome helper function called get_file and subsequently
51+
get_dir that abstracted much of the file navigation, and verification.
52+
53+
We established a virtual structure for linking filenames with their where they
54+
were stored in their containing dnode structure. This structure proved to be
55+
critical in keeping us sane.
56+
57+
A cache was created to improve lookups as well. So if we've already looked
58+
something up we would be aware of it. Whenever a change is made to the on-disk
59+
structure we also reflect that change in the cache.
60+
61+
We basically tried to follow the approach that was outlined in project 2.
62+
We used the data representations as they were provided in the Inode
63+
Implementation Notes.
64+
65+
Challenges:
66+
67+
We faced a lot of challenges with debugging. So we made a script that made
68+
debugging quicker. It's called disk_test. Supplying the -d flag runs the
69+
fs with gdb. You can look into the bash code more if you are curious;
70+
it's fairly simple.
71+
72+
Logically most of the project made sense, it was more tedious and
73+
time-consuming than we initially thought. There are pointers everywhere.
74+
75+
The codebase is pretty large, and the chance of there being an error is
76+
almost indefinite. Again, debugging was by far the biggest challenge.
77+
78+
Getting multiple directories to work was surprisingly easy. Read and
79+
Write were not bad, it was mostly the beginning of the project where we
80+
made all the abstractions that was the worst. Milestone 2 was where we
81+
faced most of the difficulty because we didn't know how FUSE worked.
82+
Getattr was greatly annoying because we had all our other code except
83+
for this working, but since FUSE almost always uses getattr in every
84+
other function call we didn't know what was actually working.
85+
Reading the project 2 notes helped here; up until this point we had
86+
forgotten to look at it.
87+
88+
Worst bug: arguments to a memcpy call were swapped. This literally
89+
took forever to find. This also happened multiple times.
90+
91+
Features:
92+
93+
- Cache for quick lookups without going to disk
94+
- Code abstraction (though there is so much more that we could have done)
95+
- The code is fairly readable, though I will let you be the judge of that.
96+
- Multiple directories pass the given tests.
97+
98+
Looking Back/Improvements:
99+
100+
We had so much more we wanted to do, but our time management skills for
101+
the project were less than stellar to say the least.
102+
103+
- Make changes only to the cache and only write to disk when the file
104+
system is unmounted or if a cache entry is being overwritten. This
105+
would have been huge!
106+
- A free block counter in our vcb could have improved performance because
107+
we could easily figure out if we had enough space before doing a write
108+
instead of writing, running out of disk space and rolling back.
109+
110+
What's Missing:
111+
112+
- Updating Access and Modification times when we read and write.
113+
114+
Tests:
115+
116+
We first approached testing with print statements. Ha.
117+
We switched to gdb, which was so much better ('target record' came in handy)
118+
We wrote a few additional stress tests. Unfortunately however, we did not
119+
get around to extensive testing.
120+
121+
41122
******************************************************************************
42-
We will be making an Inode file system; we chose this because it seemed
43-
like an interesting challenge, and it says it would be easier to implement
44-
recursive directories.
123+
124+

‎README.md

+2-22
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,6 @@
11
Project 2
22
=========
33

4-
#OUTLINE
5-
This readme outlines what we have left to do for the project. At a later point this
6-
will be updated to reflect what the project is about, the difficulties we faced,
7-
what we've learned, etcetera.
4+
#Outline
85

9-
#REFLECTION
10-
11-
#TOOLS
12-
13-
"./create_dir"
14-
use to create a 1000 block FS mounted at /tmp/NAME
15-
16-
17-
#TODO
18-
19-
- How should we handle "type" in DIRENT
20-
- Change pointers with stars to & in method signatures
21-
- Limit line length; line length = 80
22-
- Make sure tab indentation is consistent
23-
- Ensure that if conditions that are negated (!condition) work as expected (!1 != 0)
24-
- Logically order function declarations within each file
25-
- Ensure commenting is consistent, concise, and informative
26-
- File metadata (timestamps, users, groups) are incorrect
6+
This is a FUSE Inode based file system implementation.

0 commit comments

Comments
 (0)
This repository has been archived.