summaryrefslogtreecommitdiff
path: root/src/memory/cached_inode.rs
blob: b81bd2ea3b0b394eb1d3e9f71264ef47c5d929c8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use crate::disk::block::{Block, InodeBlock};
use crate::disk::inode::{Inode, InodeMode, INODE_SIZE};
use crate::AyaFS;
use and_then_some::BoolExt;

impl AyaFS {
    pub(crate) fn create_inode(
        &mut self,
        permissions: u16,
        mode: InodeMode,
        uid: u32,
        gid: u32,
        flags: u32,
    ) -> Option<usize> {
        self.inode_bitmap.allocate().map(|inode_index| {
            self.get_inode_mut(inode_index).map(|inode| {
                *inode = Inode::make_inode(
                    permissions,
                    mode,
                    uid,
                    gid,
                    Self::time_now(),
                    flags,
                    0,
                    0,
                    0,
                );
            });
            inode_index
        })
    }

    pub(crate) fn update_inode(&mut self, inode_index: usize, inode: Inode) -> bool {
        if self.inode_bitmap.query(inode_index) {
            let (block_index, offset) = self.locate_inode(inode_index);
            if let Some(cached_block) = self.cached_inodes.get_block_mut::<InodeBlock>(block_index)
            {
                cached_block.block.inodes[offset / INODE_SIZE] = inode;
            }
            true
        } else {
            false
        }
    }

    pub(crate) fn get_inode(&mut self, inode_index: usize) -> Option<&Inode> {
        self.inode_bitmap.query(inode_index).and_then(|| {
            let (block_index, offset) = self.locate_inode(inode_index);
            self.cached_inodes
                .get_block::<InodeBlock>(block_index)
                .map(|cached_block| &cached_block.block.inodes[offset / INODE_SIZE])
        })
    }

    pub(crate) fn get_inode_mut(&mut self, inode_index: usize) -> Option<&mut Inode> {
        self.inode_bitmap.query(inode_index).and_then(|| {
            let (block_index, offset) = self.locate_inode(inode_index);
            self.cached_inodes
                .get_block_mut::<InodeBlock>(block_index)
                .map(|cached_block| {
                    cached_block.dirty = true; // 保守一些, 只要返回了 &mut Inode 这个页一定标记为脏
                    &mut cached_block.block.inodes[offset / INODE_SIZE]
                })
        })
    }

    pub(crate) fn peek_inode(&self, inode_index: usize) -> Option<&Inode> {
        self.inode_bitmap.query(inode_index).and_then(|| {
            let (block_index, offset) = self.locate_inode(inode_index);
            self.cached_inodes
                .peek_block::<InodeBlock>(block_index)
                .map(|cached_block| &cached_block.block.inodes[offset / INODE_SIZE])
        })
    }

    pub(crate) fn peek_inode_mut(&mut self, inode_index: usize) -> Option<&mut Inode> {
        self.inode_bitmap.query(inode_index).and_then(|| {
            let (block_index, offset) = self.locate_inode(inode_index);
            self.cached_inodes
                .peek_block_mut::<InodeBlock>(block_index)
                .map(|cached_block| {
                    cached_block.dirty = true; // 保守一些, 只要返回了 &mut Inode 这个页一定标记为脏
                    &mut cached_block.block.inodes[offset / INODE_SIZE]
                })
        })
    }
}