Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Documentation/teaching/labs/filesystems_part2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ In the minix case, the function is ``minix_lookup``.
This function is called indirectly when information about the inode associated with an entry in a directory is needed.
Such a function performs the following operations:

#. Searces in the directory indicated by ``dir`` the entry having the name ``dentry->d_name.name``.
#. Searches in the directory indicated by ``dir`` the entry having the name ``dentry->d_name.name``.
#. If the entry is found, it will return ``NULL`` and associate the inode with the name using the :c:func:`d_add` function.
#. Otherwise, returns ``ERR_PTR``.

Expand Down
144 changes: 144 additions & 0 deletions Documentation/teaching/so2/assign-collaboration.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
=============
Collaboration
=============

Collaboration is essential in open source world and we encourage you
to pick a team partner to work on selected assignments.

Here is a simple guide to get you started:

1. Use Github / Gitlab
----------------------

Best way to share your work inside the team is to use a version control system (VCS)
in order to track each change. Mind that you must make your repo private and only allow
read/write access rights to team members.

2. Start with a skeleton for the assignment
-------------------------------------------

Add `init`/`exit` functions, driver operations and global structures that you driver might need.

.. code-block:: c

// SPDX-License-Identifier: GPL-2.0
/*
* uart16550.c - UART16550 driver
*
* Author: John Doe <john.doe@mail.com>
* Author: Ionut Popescu <ionut.popescu@mail.com>
*/
struct uart16550_dev {
struct cdev cdev;
/*TODO */
};

static struct uart16550_dev devs[MAX_NUMBER_DEVICES];

static int uart16550_open(struct inode *inode, struct file *file)
{
/*TODO */
return 0;
}

static int uart16550_release(struct inode *inode, struct file *file)
{
/*TODO */
return 0;
}

static ssize_t uart16550_read(struct file *file, char __user *user_buffer,
size_t size, loff_t *offset)
{
/*TODO */
}

static ssize_t uart16550_write(struct file *file,
const char __user *user_buffer,
size_t size, loff_t *offset)
{
/*TODO */
}

static long
uart16550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
/*TODO */
return 0;
}

static const struct file_operations uart16550_fops = {
.owner = THIS_MODULE,
.open = uart16550_open,
.release = uart16550_release,
.read = uart16550_read,
.write = uart16550_write,
.unlocked_ioctl = uart16550_ioctl
};

static int __init uart16550_init(void)
{
/* TODO: */
}

static void __exit uart16550_exit(void)
{
/* TODO: */
}

module_init(uart16550_init);
module_exit(uart16550_exit);

MODULE_DESCRIPTION("UART16550 Driver");
MODULE_AUTHOR("John Doe <john.doe@mail.com");
MODULE_AUTHOR("Ionut Popescu <ionut.popescu@mail.com");

3. Add a commit for each individual change
------------------------------------------

First commit must always be the skeleton file. And the rest of the code should be on top of skeleton file.
Please write a good commit mesage. Explain briefly what the commit does and *why* it is necessary.

Follow the seven rules of writing a good commit message: https://cbea.ms/git-commit/#seven-rules

.. code-block:: console

Commit 3c92a02cc52700d2cd7c50a20297eef8553c207a (HEAD -> tema2)
Author: John Doe <john.doe@mail.com>
Date: Mon Apr 4 11:54:39 2022 +0300

uart16550: Add initial skeleton for ssignment #2

This adds simple skeleton file for uart16550 assignment. Notice
module init/exit callbacks and file_operations dummy implementation
for open/release/read/write/ioctl.

Signed-off-by: John Doe <john.doe@mail.com>

4. Split the work inside the team
---------------------------------

Add `TODOs` with each team member tasks. Try to split the work evenly.

Before starting to code, make a plan. On top of your skeleton file, add TODOs with each member tasks. Agree on global
structures and the overlall driver design. Then start coding.

5. Do reviews
-------------

Create Pull Requests with your commits and go through review rounds with your team members. You can follow `How to create a PR` `video <https://www.youtube.com/watch?v=YvoHJJWvn98>`_.

6. Merge the work
-----------------

The final work is the result of merging all the pull requests. Following the commit messages
one should clearly understand the progress of the code and how the work was managed inside the team.

.. code-block:: console

f5118b873294 uart16550: Add uart16550_interrupt implementation
2115503fc3e3 uart16550: Add uart16550_ioctl implementation
b31a257fd8b8 uart16550: Add uart16550_write implementation
ac1af6d88a25 uart16550: Add uart16550_read implementation
9f680e8136bf uart16550: Add uart16550_open/release implementation
3c92a02cc527 uart16550: Add skeleton for SO2 assignment #2
1 change: 1 addition & 0 deletions Documentation/teaching/so2/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Operating Systems 2
:caption: Assignments
:maxdepth: 1

assign-collaboration.rst
assign0-kernel-api.rst
assign1-kprobe-based-tracer.rst
assign2-driver-uart.rst
Expand Down
95 changes: 95 additions & 0 deletions tools/labs/skels/filesystems/Lab08.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Laborator 8

## myfs
### Exercitiul 1
Structura `file_system_type` a fost initializata pentru sistemul de fisiere virtual `myfs`. In functia de mount specifica acestuia am folosit `mount_nodev` intrucat filesystem-ul este virtual si nu are nevoie de suport fizic. In functiile de init si exit ale modulului am inregistrat/eliminat sistemul de fisiere.

Corectitudinea implementarii am verificat-o prin urmatoarea serie de comenzi in masina virtuala:

```
root@qemux86:~/skels/filesystems/myfs# insmod myfs.ko
myfs: loading out-of-tree module taints kernel.
register_filesystem successful
root@qemux86:~/skels/filesystems/myfs# cat /proc/filesystems | grep myfs
nodev myfs
root@qemux86:~/skels/filesystems/myfs# mkdir -p /mnt/myfs
root@qemux86:~/skels/filesystems/myfs# mount -t myfs none /mnt/myfs
root inode has 1 link(s)
mount: mounting none on /mnt/myfs failed: Not a directory

```

### Exercitiul 2
In structura de tipul `super_operations` am definit functiile superblock-ului utilizandu-le pe cele generice `generic_delete_inode()` si `simple_statfs()` pentru o functionalitate minimala. Dupa aceea am completat functia `fill_super` completand restul campurilor din superblock.

### Exercitiul 3
Completand functia `myfs_get_inode` am initializat inode-ul radacina. Prelunad informatiile din namespace-ul root am completat campurile `uid`, `gid` si `mode` ale inode-ului. Fiind un director, am adaugat operatiile specifice si am incrementat numarul de link-uri.

### Exercitiul 4
Corectitudinea rezolvarii se poate observa din outputul urmator:

```
root@qemux86:~/skels/filesystems/myfs# mkdir -p /mnt/myfs
root@qemux86:~/skels/filesystems/myfs# mount -t myfs none /mnt/myfs
root inode has 2 link(s)
root@qemux86:~/skels/filesystems/myfs# cat /proc/mounts | grep myfs
none /mnt/myfs myfs rw,relatime 0 0
root@qemux86:~/skels/filesystems/myfs# ls -di /mnt/myfs/
4282 /mnt/myfs/
root@qemux86:~/skels/filesystems/myfs# stat -f /mnt/myfs
File: "/mnt/myfs"
ID: 0 Namelen: 255 Type: UNKNOWN
Block size: 4096
Blocks: Total: 0 Free: 0 Available: 0
Inodes: Total: 0 Free: 0
root@qemux86:~/skels/filesystems/myfs# ls -la /mnt/myfs
drwxr-xr-x 2 root root 0 Apr 30 12:52 .
drwxr-xr-x 3 root root 1024 Apr 28 10:36 ..
root@qemux86:~/skels/filesystems/myfs# touch /mnt/myfs/a.txt
touch: /mnt/myfs/a.txt: Permission denied
root@qemux86:~/skels/filesystems/myfs# umount /mnt/myfs
```

## minfs

### Exercitiul 1
In functia de mount `myfs_mount` am folosit `mount_bdev` intrucat filesystem-ul este nu mai este virtual ci are nevoie de suport fizic. Campul `fs_flags` al structurii de tipul `file_system_type` are valoarea `FS_REQUIRES_DEV` pentru a indica un filesystem ce utilizeaza un disk.

Verificam ca filesystem-ul a fost creat cu succes:
```
root@qemux86:~/skels/filesystems/minfs/kernel# cat /proc/filesystems | grep minfs
nodev minfs
```
## Exercitiul 2
Cu ajutorul functiei `sb_bread` citim block-ul de la index 0, campului `b_data` i se face cast la structura de tip superblock `struct minfs_super_block` (structura custom) si se verifica valoarea magic number-ului. Se copiaza valorile obtinute in superblock-ul generic si in structura de tipul `struct minfs_sb_info`.

## Exercitiul 3
Am completat functiile `minfs_alloc_inode` populand campul `vfs_inode` al structurii alocate folosind functia `inode_init_once`. Conform functiei utilizate,initializare se face o singura data, campurile inode-ului fiind **idempotent** (nu se modifica in urma operatiilor). Apoi am completat functia de dezalocare asociata.

## Exercitiul 4
Cu ajutorul functiei `sb_bread` citim block-ul de la index 1, apoi extragem inode-ul de index-ul `ino`. Am completat campurile `uid`, `gid`, `mode` si `size` ale variabilei `inode` (VFS inode). In cazul in care inode-ul este director, atunci se completeaza si campurile `i_op` si `i_fop` si incrementam numarul de link-uri.

Acum inlocuim apelul functiei `myfs_get_inode` cu aceasta functie `minfs_iget`.

## Exercitiul 5
Testam corectitudinea implementarii:

Setup:
```
root@qemux86:~/skels/filesystems/minfs/user# ./mkfs.minfs /dev/vdd
root@qemux86:~/skels/filesystems/minfs/user# cd
root@qemux86:~# cd skels/filesystems/minfs/kernel/
root@qemux86:~/skels/filesystems/minfs/kernel# insmod minfs.ko
minfs: loading out-of-tree module taints kernel.
root@qemux86:~/skels/filesystems/minfs/kernel# mkdir -p /mnt/minfs/
```
```
root@qemux86:~/skels/filesystems/minfs/user# ./test-minfs.sh
+ insmod ../kernel/minfs.ko
+ mkdir -p /mnt/minfs
+ ./mkfs.minfs /dev/vdb
+ mount -t minfs /dev/vdb /mnt/minfs
released superblock resources
mount: mounting /dev/vdb on /mnt/minfs failed: Not a directory
root@qemux86:~/skels/filesystems/minfs/user#
```
44 changes: 44 additions & 0 deletions tools/labs/skels/filesystems/Lab09.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Laborator 9

## myfs

### Exercitiul 1
Am identificat versiunea de kernel de pe masina pentru a gasi versiunea corecta a `ramfs` pe care am folosit-o ca model.

```
root@qemux86:~# cat /proc/version
Linux version 5.10.14+
```

Am completat structura `struct inode_operations` cu operatii specifice inode-ului de tip director: `mknod`, `create` si `mkdir`; aceste functii au fost apoi implementate dupa modelul din `ramfs`. Pentru celelalte functii am folosit varianta generica din VFS.

## Exercitiul 2
Completand structura struct `file_operations` am adaugat operatiile specifice lucrului cu structura `file` asociata inode-ului folosind tot implementarile generice din VFS. Am adaugat in structura `inode_operations` operatiile pentru manipulare inode-ului si structura `address_space_operations`. Dupa initializare am asignat structurile completate anterior campurilor potrivite din structura de inode.

Am testat corectitudinea implementarii astfel:
```
root@qemux86:~/skels/filesystems/myfs# insmod myfs.ko
myfs: loading out-of-tree module taints kernel.
root@qemux86:~/skels/filesystems/myfs# mkdir -p /mnt/myfs
root@qemux86:~/skels/filesystems/myfs# mount -t myfs none /mnt/myfs
root inode has 2 link(s)
root@qemux86:~/skels/filesystems/myfs# touch /mnt/myfs/peanuts.txt
mknod begin
mknod end
root@qemux86:~/skels/filesystems/myfs# mkdir -p /mnt/myfs/mountain/forest
mknod begin
mknod end
mknod begin
mknod end
root@qemux86:~/skels/filesystems/myfs# touch /mnt/myfs/mountain/forest/tree.txt
mknod begin
mknod end
root@qemux86:~/skels/filesystems/myfs# rm /mnt/myfs/mountain/forest/tree.txt
root@qemux86:~/skels/filesystems/myfs# rmdir /mnt/myfs/mountain/forest
root@qemux86:~/skels/filesystems/myfs# echo "chocolate" > /mnt/myfs/peanuts.txt
root@qemux86:~/skels/filesystems/myfs# cat /mnt/myfs/peanuts.txt
chocolate
root@qemux86:~/skels/filesystems/myfs# cat /mnt/myfs/peanuts.txt
```

## minfs
3 changes: 3 additions & 0 deletions tools/labs/skels/filesystems/minfs/kernel/Kbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
EXTRA_CFLAGS = -Wall -g -Wno-unused

obj-m = minfs.o
Loading