UbixOS  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)
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) {
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 
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 
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;
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