From b96960d359114d87cb13faec676ce501be763e07 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 24 Jun 2021 17:21:13 +0800 Subject: import(life): Add operating system course design. --- .../0001-crupesteam-fat-patch.patch | 163 +++++++++++++++++++++ .../operating-system-course-design/Vagrantfile | 72 +++++++++ .../create-file.bash | 13 ++ .../operating-system-course-design/read-file.c | 25 ++++ .../\351\255\224\346\224\271\345\211\215.png" | Bin 0 -> 1386574 bytes .../\351\255\224\346\224\271\345\220\216.png" | Bin 0 -> 1278348 bytes 6 files changed, 273 insertions(+) create mode 100644 works/life/operating-system-course-design/0001-crupesteam-fat-patch.patch create mode 100644 works/life/operating-system-course-design/Vagrantfile create mode 100644 works/life/operating-system-course-design/create-file.bash create mode 100644 works/life/operating-system-course-design/read-file.c create mode 100644 "works/life/operating-system-course-design/\351\255\224\346\224\271\345\211\215.png" create mode 100644 "works/life/operating-system-course-design/\351\255\224\346\224\271\345\220\216.png" 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 +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 +#include +#include +#include +#include + +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/\351\255\224\346\224\271\345\211\215.png" "b/works/life/operating-system-course-design/\351\255\224\346\224\271\345\211\215.png" new file mode 100644 index 0000000..8cc7c8c Binary files /dev/null and "b/works/life/operating-system-course-design/\351\255\224\346\224\271\345\211\215.png" differ diff --git "a/works/life/operating-system-course-design/\351\255\224\346\224\271\345\220\216.png" "b/works/life/operating-system-course-design/\351\255\224\346\224\271\345\220\216.png" new file mode 100644 index 0000000..6c4fc70 Binary files /dev/null and "b/works/life/operating-system-course-design/\351\255\224\346\224\271\345\220\216.png" differ -- cgit v1.2.3