diff options
author | crupest <crupest@outlook.com> | 2021-06-24 17:21:13 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-06-24 17:21:13 +0800 |
commit | b96960d359114d87cb13faec676ce501be763e07 (patch) | |
tree | 0132817cb7a835f5519b50ad105efe28727abf88 /works/life | |
parent | 213363383b5864d236cfce711920f76a2450de07 (diff) | |
download | crupest-b96960d359114d87cb13faec676ce501be763e07.tar.gz crupest-b96960d359114d87cb13faec676ce501be763e07.tar.bz2 crupest-b96960d359114d87cb13faec676ce501be763e07.zip |
import(life): Add operating system course design.
Diffstat (limited to 'works/life')
-rw-r--r-- | works/life/operating-system-course-design/0001-crupesteam-fat-patch.patch | 163 | ||||
-rw-r--r-- | works/life/operating-system-course-design/Vagrantfile | 72 | ||||
-rw-r--r-- | works/life/operating-system-course-design/create-file.bash | 13 | ||||
-rw-r--r-- | works/life/operating-system-course-design/read-file.c | 25 | ||||
-rw-r--r-- | works/life/operating-system-course-design/魔改前.png | bin | 0 -> 1386574 bytes | |||
-rw-r--r-- | works/life/operating-system-course-design/魔改后.png | bin | 0 -> 1278348 bytes |
6 files changed, 273 insertions, 0 deletions
diff --git a/works/life/operating-system-course-design/0001-crupesteam-fat-patch.patch b/works/life/operating-system-course-design/0001-crupesteam-fat-patch.patch new file mode 100644 index 0000000..9f23ebb --- /dev/null +++ b/works/life/operating-system-course-design/0001-crupesteam-fat-patch.patch @@ -0,0 +1,163 @@ +From e88345bbb9a4027033254933ee2e1cad9feab6d6 Mon Sep 17 00:00:00 2001 +From: crupest <crupest@outlook.com> +Date: Thu, 24 Jun 2021 16:00:04 +0800 +Subject: [PATCH] crupesteam fat patch. + +--- + fs/fat/cache.c | 64 ++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 57 insertions(+), 7 deletions(-) + +diff --git a/fs/fat/cache.c b/fs/fat/cache.c +index 738e427e2d21..4f32bfee6d27 100644 +--- a/fs/fat/cache.c ++++ b/fs/fat/cache.c +@@ -15,11 +15,15 @@ + /* this must be > 0. */ + #define FAT_MAX_CACHE 8 + ++#define FAT_CACHE_PREV_CLUSTER_COUNT 8 ++ + struct fat_cache { + struct list_head cache_list; + int nr_contig; /* number of contiguous clusters */ + int fcluster; /* cluster number in the file. */ + int dcluster; /* cluster number on disk. */ ++ int prev_clusters_count; ++ int prev_clusters[FAT_CACHE_PREV_CLUSTER_COUNT]; + }; + + struct fat_cache_id { +@@ -27,6 +31,8 @@ struct fat_cache_id { + int nr_contig; + int fcluster; + int dcluster; ++ int prev_clusters_count; ++ int prev_clusters[FAT_CACHE_PREV_CLUSTER_COUNT]; + }; + + static inline int fat_max_cache(struct inode *inode) +@@ -84,10 +90,17 @@ static int fat_cache_lookup(struct inode *inode, int fclus, + static struct fat_cache nohit = { .fcluster = 0, }; + + struct fat_cache *hit = &nohit, *p; +- int offset = -1; ++ int offset = INT_MIN; + + spin_lock(&MSDOS_I(inode)->cache_lru_lock); + list_for_each_entry(p, &MSDOS_I(inode)->cache_lru, cache_list) { ++ if (p->fcluster > fclus && ++ p->fcluster - p->prev_clusters_count <= fclus) { ++ hit = p; ++ offset = fclus - hit->fcluster; ++ break; ++ } ++ + /* Find the cache of "fclus" or nearest cache. */ + if (p->fcluster <= fclus && hit->fcluster < p->fcluster) { + hit = p; +@@ -107,7 +120,11 @@ static int fat_cache_lookup(struct inode *inode, int fclus, + cid->fcluster = hit->fcluster; + cid->dcluster = hit->dcluster; + *cached_fclus = cid->fcluster + offset; +- *cached_dclus = cid->dcluster + offset; ++ ++ if (offset < 0) ++ *cached_dclus = hit->prev_clusters[hit->prev_clusters_count + offset]; ++ else ++ *cached_dclus = cid->dcluster + offset; + } + spin_unlock(&MSDOS_I(inode)->cache_lru_lock); + +@@ -145,6 +162,8 @@ static void fat_cache_add(struct inode *inode, struct fat_cache_id *new) + + cache = fat_cache_merge(inode, new); + if (cache == NULL) { ++ int i; ++ + if (MSDOS_I(inode)->nr_caches < fat_max_cache(inode)) { + MSDOS_I(inode)->nr_caches++; + spin_unlock(&MSDOS_I(inode)->cache_lru_lock); +@@ -172,6 +191,10 @@ static void fat_cache_add(struct inode *inode, struct fat_cache_id *new) + cache->fcluster = new->fcluster; + cache->dcluster = new->dcluster; + cache->nr_contig = new->nr_contig; ++ cache->prev_clusters_count = new->prev_clusters_count; ++ for (i = 0; i < new->prev_clusters_count; i++) { ++ cache->prev_clusters[i] = new->prev_clusters[i]; ++ } + } + out_update_lru: + fat_cache_update_lru(inode, cache); +@@ -220,6 +243,7 @@ static inline void cache_init(struct fat_cache_id *cid, int fclus, int dclus) + cid->fcluster = fclus; + cid->dcluster = dclus; + cid->nr_contig = 0; ++ cid->prev_clusters_count = 0; + } + + int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) +@@ -230,6 +254,10 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) + struct fat_entry fatent; + struct fat_cache_id cid; + int nr; ++ int offset; ++ int prev_cluster[FAT_CACHE_PREV_CLUSTER_COUNT]; ++ int prev_cluster_current = 0; ++ int prev_cluster_count = 0; + + BUG_ON(MSDOS_I(inode)->i_start == 0); + +@@ -244,12 +272,13 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) + if (cluster == 0) + return 0; + +- if (fat_cache_lookup(inode, cluster, &cid, fclus, dclus) < 0) { +- /* +- * dummy, always not contiguous +- * This is reinitialized by cache_init(), later. +- */ ++ offset = fat_cache_lookup(inode, cluster, &cid, fclus, dclus); ++ ++ if (offset == INT_MIN) { + cache_init(&cid, -1, -1); ++ } else if (offset < 0) { ++ nr = 0; ++ goto out; + } + + fatent_init(&fatent); +@@ -278,10 +307,31 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) + } + (*fclus)++; + *dclus = nr; ++ ++ prev_cluster[prev_cluster_current++] = *dclus; ++ if (prev_cluster_count < FAT_CACHE_PREV_CLUSTER_COUNT) { ++ prev_cluster_count++; ++ } ++ prev_cluster_current %= FAT_CACHE_PREV_CLUSTER_COUNT; ++ + if (!cache_contiguous(&cid, *dclus)) + cache_init(&cid, *fclus, *dclus); + } + nr = 0; ++ ++ if (cid.nr_contig + 1 < FAT_CACHE_PREV_CLUSTER_COUNT) { ++ int i; ++ int count = prev_cluster_count - cid.nr_contig - 1; ++ int start = ((prev_cluster_current - prev_cluster_count) ++ + FAT_CACHE_PREV_CLUSTER_COUNT) % FAT_CACHE_PREV_CLUSTER_COUNT; ++ ++ cid.prev_clusters_count = count; ++ ++ for (i = 0; i < count; i++) { ++ cid.prev_clusters[i] = prev_cluster[(start + i) % FAT_CACHE_PREV_CLUSTER_COUNT]; ++ } ++ } ++ + fat_cache_add(inode, &cid); + out: + fatent_brelse(&fatent); +-- +2.32.0 + diff --git a/works/life/operating-system-course-design/Vagrantfile b/works/life/operating-system-course-design/Vagrantfile new file mode 100644 index 0000000..8f4509f --- /dev/null +++ b/works/life/operating-system-course-design/Vagrantfile @@ -0,0 +1,72 @@ +# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# All Vagrant configuration is done below. The "2" in Vagrant.configure
+# configures the configuration version (we support older styles for
+# backwards compatibility). Please don't change it unless you know what
+# you're doing.
+Vagrant.configure("2") do |config|
+ # The most common configuration options are documented and commented below.
+ # For a complete reference, please see the online documentation at
+ # https://docs.vagrantup.com.
+
+ # Every Vagrant development environment requires a box. You can search for
+ # boxes at https://vagrantcloud.com/search.
+ config.vm.box = "archlinux/archlinux"
+
+ config.vm.disk :disk, size: "10GB", name: "fat_test"
+
+ # Disable automatic box update checking. If you disable this, then
+ # boxes will only be checked for updates when the user runs
+ # `vagrant box outdated`. This is not recommended.
+ # config.vm.box_check_update = false
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine. In the example below,
+ # accessing "localhost:8080" will access port 80 on the guest machine.
+ # NOTE: This will enable public access to the opened port
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine and only allow access
+ # via 127.0.0.1 to disable public access
+ # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
+
+ # Create a private network, which allows host-only access to the machine
+ # using a specific IP.
+ # config.vm.network "private_network", ip: "192.168.33.10"
+
+ # Create a public network, which generally matched to bridged network.
+ # Bridged networks make the machine appear as another physical device on
+ # your network.
+ # config.vm.network "public_network"
+
+ # Share an additional folder to the guest VM. The first argument is
+ # the path on the host to the actual folder. The second argument is
+ # the path on the guest to mount the folder. And the optional third
+ # argument is a set of non-required options.
+ # config.vm.synced_folder "../data", "/vagrant_data"
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ # Example for VirtualBox:
+ #
+ # config.vm.provider "virtualbox" do |vb|
+ # # Display the VirtualBox GUI when booting the machine
+ # vb.gui = true
+ #
+ # # Customize the amount of memory on the VM:
+ # vb.memory = "1024"
+ # end
+ #
+ # View the documentation for the provider you are using for more
+ # information on available options.
+
+ # Enable provisioning with a shell script. Additional provisioners such as
+ # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
+ # documentation for more information about their specific syntax and use.
+ # config.vm.provision "shell", inline: <<-SHELL
+ # apt-get update
+ # apt-get install -y apache2
+ # SHELL
+end
diff --git a/works/life/operating-system-course-design/create-file.bash b/works/life/operating-system-course-design/create-file.bash new file mode 100644 index 0000000..d9afec2 --- /dev/null +++ b/works/life/operating-system-course-design/create-file.bash @@ -0,0 +1,13 @@ +let file_count=2*1024*2; + +for iter in `seq $file_count`; do + truncate -s 512KB /mnt/fat-test/$iter; +done + +for iter in `seq $file_count`; do + if (($iter % 2 == 0)); then + rm /mnt/fat-test/$iter; + fi +done + +truncate -s 500MB /mnt/fat-test/big; diff --git a/works/life/operating-system-course-design/read-file.c b/works/life/operating-system-course-design/read-file.c new file mode 100644 index 0000000..fe71f94 --- /dev/null +++ b/works/life/operating-system-course-design/read-file.c @@ -0,0 +1,25 @@ +#include <bits/types.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> + +int main() { + int fd = open("/mnt/fat-test/big", O_RDONLY); + if (fd < 0) + return 1; + + __off_t size = lseek(fd, 0, SEEK_END); + if (size < 0) + return 2; + + for (__off_t i = 512; i <= size; i += 512) { + if (lseek(fd, size - i, SEEK_SET) < 0) + return 3; + char buffer[512]; + if (read(fd, buffer, 512) < 0) + return 4; + } + + return 0; +} diff --git a/works/life/operating-system-course-design/魔改前.png b/works/life/operating-system-course-design/魔改前.png Binary files differnew file mode 100644 index 0000000..8cc7c8c --- /dev/null +++ b/works/life/operating-system-course-design/魔改前.png diff --git a/works/life/operating-system-course-design/魔改后.png b/works/life/operating-system-course-design/魔改后.png Binary files differnew file mode 100644 index 0000000..6c4fc70 --- /dev/null +++ b/works/life/operating-system-course-design/魔改后.png |