summaryrefslogtreecommitdiff
path: root/user
diff options
context:
space:
mode:
authorSanjit Bhat <[email protected]>2023-10-30 14:39:45 -0500
committerSanjit Bhat <[email protected]>2023-10-30 14:39:45 -0500
commit5464552a43916f6336787bafd1149ce2aa30f6af (patch)
treed2310242409742778c059cc60869849debf038d8 /user
parent74c1eba516fdb0ec1a17b16be7e76613ccba92bf (diff)
downloadxv6-labs-5464552a43916f6336787bafd1149ce2aa30f6af.tar.gz
xv6-labs-5464552a43916f6336787bafd1149ce2aa30f6af.tar.bz2
xv6-labs-5464552a43916f6336787bafd1149ce2aa30f6af.zip
fs: release lab
Diffstat (limited to 'user')
-rw-r--r--user/bigfile.c58
-rw-r--r--user/symlinktest.c188
2 files changed, 246 insertions, 0 deletions
diff --git a/user/bigfile.c b/user/bigfile.c
new file mode 100644
index 0000000..0755700
--- /dev/null
+++ b/user/bigfile.c
@@ -0,0 +1,58 @@
+#include "kernel/types.h"
+#include "kernel/stat.h"
+#include "user/user.h"
+#include "kernel/fcntl.h"
+#include "kernel/fs.h"
+
+int
+main()
+{
+ char buf[BSIZE];
+ int fd, i, blocks;
+
+ fd = open("big.file", O_CREATE | O_WRONLY);
+ if(fd < 0){
+ printf("bigfile: cannot open big.file for writing\n");
+ exit(-1);
+ }
+
+ blocks = 0;
+ while(1){
+ *(int*)buf = blocks;
+ int cc = write(fd, buf, sizeof(buf));
+ if(cc <= 0)
+ break;
+ blocks++;
+ if (blocks % 100 == 0)
+ printf(".");
+ }
+
+ printf("\nwrote %d blocks\n", blocks);
+ if(blocks != 65803) {
+ printf("bigfile: file is too small\n");
+ exit(-1);
+ }
+
+ close(fd);
+ fd = open("big.file", O_RDONLY);
+ if(fd < 0){
+ printf("bigfile: cannot re-open big.file for reading\n");
+ exit(-1);
+ }
+ for(i = 0; i < blocks; i++){
+ int cc = read(fd, buf, sizeof(buf));
+ if(cc <= 0){
+ printf("bigfile: read error at block %d\n", i);
+ exit(-1);
+ }
+ if(*(int*)buf != i){
+ printf("bigfile: read the wrong data (%d) for block %d\n",
+ *(int*)buf, i);
+ exit(-1);
+ }
+ }
+
+ printf("bigfile done; ok\n");
+
+ exit(0);
+}
diff --git a/user/symlinktest.c b/user/symlinktest.c
new file mode 100644
index 0000000..ac6e31c
--- /dev/null
+++ b/user/symlinktest.c
@@ -0,0 +1,188 @@
+#include "kernel/param.h"
+#include "kernel/types.h"
+#include "kernel/stat.h"
+#include "kernel/riscv.h"
+#include "kernel/fcntl.h"
+#include "kernel/spinlock.h"
+#include "kernel/sleeplock.h"
+#include "kernel/fs.h"
+#include "kernel/file.h"
+#include "user/user.h"
+
+#define fail(msg) do {printf("FAILURE: " msg "\n"); failed = 1; goto done;} while (0);
+static int failed = 0;
+
+static void testsymlink(void);
+static void concur(void);
+static void cleanup(void);
+
+int
+main(int argc, char *argv[])
+{
+ cleanup();
+ testsymlink();
+ concur();
+ exit(failed);
+}
+
+static void
+cleanup(void)
+{
+ unlink("/testsymlink/a");
+ unlink("/testsymlink/b");
+ unlink("/testsymlink/c");
+ unlink("/testsymlink/1");
+ unlink("/testsymlink/2");
+ unlink("/testsymlink/3");
+ unlink("/testsymlink/4");
+ unlink("/testsymlink/z");
+ unlink("/testsymlink/y");
+ unlink("/testsymlink");
+}
+
+// stat a symbolic link using O_NOFOLLOW
+static int
+stat_slink(char *pn, struct stat *st)
+{
+ int fd = open(pn, O_RDONLY | O_NOFOLLOW);
+ if(fd < 0)
+ return -1;
+ if(fstat(fd, st) != 0)
+ return -1;
+ return 0;
+}
+
+static void
+testsymlink(void)
+{
+ int r, fd1 = -1, fd2 = -1;
+ char buf[4] = {'a', 'b', 'c', 'd'};
+ char c = 0, c2 = 0;
+ struct stat st;
+
+ printf("Start: test symlinks\n");
+
+ mkdir("/testsymlink");
+
+ fd1 = open("/testsymlink/a", O_CREATE | O_RDWR);
+ if(fd1 < 0) fail("failed to open a");
+
+ r = symlink("/testsymlink/a", "/testsymlink/b");
+ if(r < 0)
+ fail("symlink b -> a failed");
+
+ if(write(fd1, buf, sizeof(buf)) != 4)
+ fail("failed to write to a");
+
+ if (stat_slink("/testsymlink/b", &st) != 0)
+ fail("failed to stat b");
+ if(st.type != T_SYMLINK)
+ fail("b isn't a symlink");
+
+ fd2 = open("/testsymlink/b", O_RDWR);
+ if(fd2 < 0)
+ fail("failed to open b");
+ read(fd2, &c, 1);
+ if (c != 'a')
+ fail("failed to read bytes from b");
+
+ unlink("/testsymlink/a");
+ if(open("/testsymlink/b", O_RDWR) >= 0)
+ fail("Should not be able to open b after deleting a");
+
+ r = symlink("/testsymlink/b", "/testsymlink/a");
+ if(r < 0)
+ fail("symlink a -> b failed");
+
+ r = open("/testsymlink/b", O_RDWR);
+ if(r >= 0)
+ fail("Should not be able to open b (cycle b->a->b->..)\n");
+
+ r = symlink("/testsymlink/nonexistent", "/testsymlink/c");
+ if(r != 0)
+ fail("Symlinking to nonexistent file should succeed\n");
+
+ r = symlink("/testsymlink/2", "/testsymlink/1");
+ if(r) fail("Failed to link 1->2");
+ r = symlink("/testsymlink/3", "/testsymlink/2");
+ if(r) fail("Failed to link 2->3");
+ r = symlink("/testsymlink/4", "/testsymlink/3");
+ if(r) fail("Failed to link 3->4");
+
+ close(fd1);
+ close(fd2);
+
+ fd1 = open("/testsymlink/4", O_CREATE | O_RDWR);
+ if(fd1<0) fail("Failed to create 4\n");
+ fd2 = open("/testsymlink/1", O_RDWR);
+ if(fd2<0) fail("Failed to open 1\n");
+
+ c = '#';
+ r = write(fd2, &c, 1);
+ if(r!=1) fail("Failed to write to 1\n");
+ r = read(fd1, &c2, 1);
+ if(r!=1) fail("Failed to read from 4\n");
+ if(c!=c2)
+ fail("Value read from 4 differed from value written to 1\n");
+
+ printf("test symlinks: ok\n");
+done:
+ close(fd1);
+ close(fd2);
+}
+
+static void
+concur(void)
+{
+ int pid, i;
+ int fd;
+ struct stat st;
+ int nchild = 2;
+
+ printf("Start: test concurrent symlinks\n");
+
+ fd = open("/testsymlink/z", O_CREATE | O_RDWR);
+ if(fd < 0) {
+ printf("FAILED: open failed");
+ exit(1);
+ }
+ close(fd);
+
+ for(int j = 0; j < nchild; j++) {
+ pid = fork();
+ if(pid < 0){
+ printf("FAILED: fork failed\n");
+ exit(1);
+ }
+ if(pid == 0) {
+ int m = 0;
+ unsigned int x = (pid ? 1 : 97);
+ for(i = 0; i < 100; i++){
+ x = x * 1103515245 + 12345;
+ if((x % 3) == 0) {
+ symlink("/testsymlink/z", "/testsymlink/y");
+ if (stat_slink("/testsymlink/y", &st) == 0) {
+ m++;
+ if(st.type != T_SYMLINK) {
+ printf("FAILED: not a symbolic link\n", st.type);
+ exit(1);
+ }
+ }
+ } else {
+ unlink("/testsymlink/y");
+ }
+ }
+ exit(0);
+ }
+ }
+
+ int r;
+ for(int j = 0; j < nchild; j++) {
+ wait(&r);
+ if(r != 0) {
+ printf("test concurrent symlinks: failed\n");
+ exit(1);
+ }
+ }
+ printf("test concurrent symlinks: ok\n");
+}