aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-06-24 17:21:13 +0800
committercrupest <crupest@outlook.com>2021-06-24 17:21:13 +0800
commitb96960d359114d87cb13faec676ce501be763e07 (patch)
tree0132817cb7a835f5519b50ad105efe28727abf88 /works/life
parent213363383b5864d236cfce711920f76a2450de07 (diff)
downloadcrupest-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.patch163
-rw-r--r--works/life/operating-system-course-design/Vagrantfile72
-rw-r--r--works/life/operating-system-course-design/create-file.bash13
-rw-r--r--works/life/operating-system-course-design/read-file.c25
-rw-r--r--works/life/operating-system-course-design/魔改前.pngbin0 -> 1386574 bytes
-rw-r--r--works/life/operating-system-course-design/魔改后.pngbin0 -> 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
new file mode 100644
index 0000000..8cc7c8c
--- /dev/null
+++ b/works/life/operating-system-course-design/魔改前.png
Binary files differ
diff --git a/works/life/operating-system-course-design/魔改后.png b/works/life/operating-system-course-design/魔改后.png
new file mode 100644
index 0000000..6c4fc70
--- /dev/null
+++ b/works/life/operating-system-course-design/魔改后.png
Binary files differ