UbixOS V2 2.0

inode.c
Go to the documentation of this file.
1 /*-
2 * Copyright (c) 2002-2018 The UbixOS Project.
3 * All rights reserved.
4 *
5 * This was developed by Christopher W. Olsen for the UbixOS Project.
6 *
7 * Redistribution and use in source and binary forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 *
10 * 1) Redistributions of source code must retain the above copyright notice, this list of
11 * conditions, the following disclaimer and the list of authors.
12 * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13 * conditions, the following disclaimer and the list of authors in the documentation and/or
14 * other materials provided with the distribution.
15 * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16 * endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <vfs/vfs.h>
30 #include <ubixos/wait.h>
31 #include <ubixos/sched.h>
32
33 //static struct inode *first_inode = NULL;
34 static struct wait_queue *inode_wait = NULL;
35 //static int nr_inodes = 0;
36 static int nr_free_inodes = 0;
37
38 static void write_inode(struct inode * inode);
39 static void __wait_on_inode(struct inode * inode);
40 static inline void unlock_inode(struct inode * inode);
41
42 static inline void wait_on_inode(struct inode * inode) {
43 if (inode->i_lock)
44 __wait_on_inode(inode);
45 }
46
47 void iput(struct inode * inode) {
48 if (!inode)
49 return;
50
51 wait_on_inode(inode);
52
53 #ifdef _IGNORE
54 if (!inode->i_count) {
55 printk("VFS: iput: trying to free free inode\n");
56 printk("VFS: device %d/%d, inode %lu, mode=0%07o\n", MAJOR(inode->i_rdev), MINOR(inode->i_rdev), inode->i_ino, inode->i_mode);
57 return;
58 }
59 #endif
60
61 if (inode->i_pipe)
62 wake_up_interruptible(&PIPE_WAIT(*inode));
63
64 repeat:
65
66 if (inode->i_count > 1) {
67 inode->i_count--;
68 return;
69 }
70
71 wake_up(&inode_wait);
72
73 if (inode->i_pipe) {
74 unsigned long page = (unsigned long) PIPE_BASE(*inode);
75 PIPE_BASE (*inode) = NULL;
76 vmm_freeVirtualPage(page);
77 }
78
79 if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
80 inode->i_sb->s_op->put_inode(inode);
81 if (!inode->i_nlink)
82 return;
83 }
84
85 if (inode->i_dirt) {
86 write_inode(inode); /* we can sleep - so do again */
87 wait_on_inode(inode);
88 goto repeat;
89 }
90
91 inode->i_count--;
92 nr_free_inodes++;
93 return;
94 }
95
96 static void __wait_on_inode(struct inode * inode) {
97 struct wait_queue wait = { _current, NULL };
98
99 add_wait_queue(&inode->i_wait, &wait);
100
101 repeat:
102
103 _current->state = UNINTERRUPTIBLE;
104
105 if (inode->i_lock) {
106 sched_yield();
107 //schedule();
108 goto repeat;
109 }
110
111 remove_wait_queue(&inode->i_wait, &wait);
112
113 _current->state = RUNNING;
114
115 }
116
117 static void write_inode(struct inode * inode) {
118 if (!inode->i_dirt)
119 return;
120
121 wait_on_inode(inode);
122
123 if (!inode->i_dirt)
124 return;
125
126 if (!inode->i_sb || !inode->i_sb->s_op || !inode->i_sb->s_op->write_inode) {
127 inode->i_dirt = 0;
128 return;
129 }
130
131 inode->i_lock = 1;
132 inode->i_sb->s_op->write_inode(inode);
133
134 unlock_inode(inode);
135 }
136
137
138 static inline void unlock_inode(struct inode * inode) {
139 inode->i_lock = 0;
140 wake_up(&inode->i_wait);
141 }
iput
void iput(struct inode *inode)
Definition: inode.c:47
inode::i_sb
struct super_block * i_sb
Definition: inode.h:55
PIPE_BASE
#define PIPE_BASE(inode)
Definition: pipe_fs.h:45
vfs.h
remove_wait_queue
void remove_wait_queue(struct wait_queue **p, struct wait_queue *wait)
Definition: sched.c:315
RUNNING
Definition: sched.h:47
inode::i_count
unsigned short i_count
Definition: inode.h:64
add_wait_queue
void add_wait_queue(struct wait_queue **p, struct wait_queue *wait)
Definition: sched.c:299
wake_up_interruptible
void wake_up_interruptible(struct wait_queue **q)
Definition: sched.c:335
sched.h
wait.h
UNINTERRUPTIBLE
Definition: sched.h:47
inode::i_lock
unsigned char i_lock
Definition: inode.h:66
inode
Definition: inode.h:39
inode::i_dirt
unsigned char i_dirt
Definition: inode.h:67
wake_up
void wake_up(struct wait_queue **q)
Definition: sched.c:360
_current
kTask_t * _current
Definition: sched.c:50
inode::i_rdev
__dev_t i_rdev
Definition: inode.h:46
taskStruct::state
tState state
Definition: sched.h:72
inode::i_mode
__mode_t i_mode
Definition: inode.h:42
inode::i_ino
unsigned long i_ino
Definition: inode.h:41
inode::i_nlink
__nlink_t i_nlink
Definition: inode.h:43
wait_queue
Definition: wait.h:34
super_operations::put_inode
void(* put_inode)(struct inode *)
Definition: vfs.h:100
super_block::s_op
struct super_operations * s_op
Definition: vfs.h:114
inode::i_pipe
unsigned char i_pipe
Definition: inode.h:68
PIPE_WAIT
#define PIPE_WAIT(inode)
Definition: pipe_fs.h:44
vmm_freeVirtualPage
int vmm_freeVirtualPage(uint32_t addr)
Definition: freevirtualpage.c:31
inode::i_wait
struct wait_queue * i_wait
Definition: inode.h:56
sched_yield
void sched_yield()
Definition: sched.c:244
super_operations::write_inode
void(* write_inode)(struct inode *)
Definition: vfs.h:99
NULL
#define NULL
Definition: fat_string.h:17