aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bfs')
-rw-r--r--fs/bfs/bfs.h1
-rw-r--r--fs/bfs/dir.c46
-rw-r--r--fs/bfs/file.c4
-rw-r--r--fs/bfs/inode.c24
4 files changed, 44 insertions, 31 deletions
diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h
index d1a6cd10afce..7109e451abf7 100644
--- a/fs/bfs/bfs.h
+++ b/fs/bfs/bfs.h
@@ -18,6 +18,7 @@ struct bfs_sb_info {
18 unsigned long si_lasti; 18 unsigned long si_lasti;
19 unsigned long *si_imap; 19 unsigned long *si_imap;
20 struct buffer_head *si_sbh; /* buffer header w/superblock */ 20 struct buffer_head *si_sbh; /* buffer header w/superblock */
21 struct mutex bfs_lock;
21}; 22};
22 23
23/* 24/*
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 034950cb3cbe..87ee5ccee348 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -32,16 +32,17 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
32 struct inode *dir = f->f_path.dentry->d_inode; 32 struct inode *dir = f->f_path.dentry->d_inode;
33 struct buffer_head *bh; 33 struct buffer_head *bh;
34 struct bfs_dirent *de; 34 struct bfs_dirent *de;
35 struct bfs_sb_info *info = BFS_SB(dir->i_sb);
35 unsigned int offset; 36 unsigned int offset;
36 int block; 37 int block;
37 38
38 lock_kernel(); 39 mutex_lock(&info->bfs_lock);
39 40
40 if (f->f_pos & (BFS_DIRENT_SIZE - 1)) { 41 if (f->f_pos & (BFS_DIRENT_SIZE - 1)) {
41 printf("Bad f_pos=%08lx for %s:%08lx\n", 42 printf("Bad f_pos=%08lx for %s:%08lx\n",
42 (unsigned long)f->f_pos, 43 (unsigned long)f->f_pos,
43 dir->i_sb->s_id, dir->i_ino); 44 dir->i_sb->s_id, dir->i_ino);
44 unlock_kernel(); 45 mutex_unlock(&info->bfs_lock);
45 return -EBADF; 46 return -EBADF;
46 } 47 }
47 48
@@ -61,7 +62,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
61 le16_to_cpu(de->ino), 62 le16_to_cpu(de->ino),
62 DT_UNKNOWN) < 0) { 63 DT_UNKNOWN) < 0) {
63 brelse(bh); 64 brelse(bh);
64 unlock_kernel(); 65 mutex_unlock(&info->bfs_lock);
65 return 0; 66 return 0;
66 } 67 }
67 } 68 }
@@ -71,7 +72,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
71 brelse(bh); 72 brelse(bh);
72 } 73 }
73 74
74 unlock_kernel(); 75 mutex_unlock(&info->bfs_lock);
75 return 0; 76 return 0;
76} 77}
77 78
@@ -95,10 +96,10 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,
95 inode = new_inode(s); 96 inode = new_inode(s);
96 if (!inode) 97 if (!inode)
97 return -ENOSPC; 98 return -ENOSPC;
98 lock_kernel(); 99 mutex_lock(&info->bfs_lock);
99 ino = find_first_zero_bit(info->si_imap, info->si_lasti); 100 ino = find_first_zero_bit(info->si_imap, info->si_lasti);
100 if (ino > info->si_lasti) { 101 if (ino > info->si_lasti) {
101 unlock_kernel(); 102 mutex_unlock(&info->bfs_lock);
102 iput(inode); 103 iput(inode);
103 return -ENOSPC; 104 return -ENOSPC;
104 } 105 }
@@ -125,10 +126,10 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,
125 if (err) { 126 if (err) {
126 inode_dec_link_count(inode); 127 inode_dec_link_count(inode);
127 iput(inode); 128 iput(inode);
128 unlock_kernel(); 129 mutex_unlock(&info->bfs_lock);
129 return err; 130 return err;
130 } 131 }
131 unlock_kernel(); 132 mutex_unlock(&info->bfs_lock);
132 d_instantiate(dentry, inode); 133 d_instantiate(dentry, inode);
133 return 0; 134 return 0;
134} 135}
@@ -139,22 +140,23 @@ static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry,
139 struct inode *inode = NULL; 140 struct inode *inode = NULL;
140 struct buffer_head *bh; 141 struct buffer_head *bh;
141 struct bfs_dirent *de; 142 struct bfs_dirent *de;
143 struct bfs_sb_info *info = BFS_SB(dir->i_sb);
142 144
143 if (dentry->d_name.len > BFS_NAMELEN) 145 if (dentry->d_name.len > BFS_NAMELEN)
144 return ERR_PTR(-ENAMETOOLONG); 146 return ERR_PTR(-ENAMETOOLONG);
145 147
146 lock_kernel(); 148 mutex_lock(&info->bfs_lock);
147 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); 149 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
148 if (bh) { 150 if (bh) {
149 unsigned long ino = (unsigned long)le16_to_cpu(de->ino); 151 unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
150 brelse(bh); 152 brelse(bh);
151 inode = bfs_iget(dir->i_sb, ino); 153 inode = bfs_iget(dir->i_sb, ino);
152 if (IS_ERR(inode)) { 154 if (IS_ERR(inode)) {
153 unlock_kernel(); 155 mutex_unlock(&info->bfs_lock);
154 return ERR_CAST(inode); 156 return ERR_CAST(inode);
155 } 157 }
156 } 158 }
157 unlock_kernel(); 159 mutex_unlock(&info->bfs_lock);
158 d_add(dentry, inode); 160 d_add(dentry, inode);
159 return NULL; 161 return NULL;
160} 162}
@@ -163,13 +165,14 @@ static int bfs_link(struct dentry *old, struct inode *dir,
163 struct dentry *new) 165 struct dentry *new)
164{ 166{
165 struct inode *inode = old->d_inode; 167 struct inode *inode = old->d_inode;
168 struct bfs_sb_info *info = BFS_SB(inode->i_sb);
166 int err; 169 int err;
167 170
168 lock_kernel(); 171 mutex_lock(&info->bfs_lock);
169 err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, 172 err = bfs_add_entry(dir, new->d_name.name, new->d_name.len,
170 inode->i_ino); 173 inode->i_ino);
171 if (err) { 174 if (err) {
172 unlock_kernel(); 175 mutex_unlock(&info->bfs_lock);
173 return err; 176 return err;
174 } 177 }
175 inc_nlink(inode); 178 inc_nlink(inode);
@@ -177,19 +180,19 @@ static int bfs_link(struct dentry *old, struct inode *dir,
177 mark_inode_dirty(inode); 180 mark_inode_dirty(inode);
178 atomic_inc(&inode->i_count); 181 atomic_inc(&inode->i_count);
179 d_instantiate(new, inode); 182 d_instantiate(new, inode);
180 unlock_kernel(); 183 mutex_unlock(&info->bfs_lock);
181 return 0; 184 return 0;
182} 185}
183 186
184static int bfs_unlink(struct inode *dir, struct dentry *dentry) 187static int bfs_unlink(struct inode *dir, struct dentry *dentry)
185{ 188{
186 int error = -ENOENT; 189 int error = -ENOENT;
187 struct inode *inode; 190 struct inode *inode = dentry->d_inode;
188 struct buffer_head *bh; 191 struct buffer_head *bh;
189 struct bfs_dirent *de; 192 struct bfs_dirent *de;
193 struct bfs_sb_info *info = BFS_SB(inode->i_sb);
190 194
191 inode = dentry->d_inode; 195 mutex_lock(&info->bfs_lock);
192 lock_kernel();
193 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); 196 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
194 if (!bh || (le16_to_cpu(de->ino) != inode->i_ino)) 197 if (!bh || (le16_to_cpu(de->ino) != inode->i_ino))
195 goto out_brelse; 198 goto out_brelse;
@@ -210,7 +213,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry)
210 213
211out_brelse: 214out_brelse:
212 brelse(bh); 215 brelse(bh);
213 unlock_kernel(); 216 mutex_unlock(&info->bfs_lock);
214 return error; 217 return error;
215} 218}
216 219
@@ -220,6 +223,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
220 struct inode *old_inode, *new_inode; 223 struct inode *old_inode, *new_inode;
221 struct buffer_head *old_bh, *new_bh; 224 struct buffer_head *old_bh, *new_bh;
222 struct bfs_dirent *old_de, *new_de; 225 struct bfs_dirent *old_de, *new_de;
226 struct bfs_sb_info *info;
223 int error = -ENOENT; 227 int error = -ENOENT;
224 228
225 old_bh = new_bh = NULL; 229 old_bh = new_bh = NULL;
@@ -227,7 +231,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
227 if (S_ISDIR(old_inode->i_mode)) 231 if (S_ISDIR(old_inode->i_mode))
228 return -EINVAL; 232 return -EINVAL;
229 233
230 lock_kernel(); 234 info = BFS_SB(old_inode->i_sb);
235
236 mutex_lock(&info->bfs_lock);
231 old_bh = bfs_find_entry(old_dir, 237 old_bh = bfs_find_entry(old_dir,
232 old_dentry->d_name.name, 238 old_dentry->d_name.name,
233 old_dentry->d_name.len, &old_de); 239 old_dentry->d_name.len, &old_de);
@@ -264,7 +270,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
264 error = 0; 270 error = 0;
265 271
266end_rename: 272end_rename:
267 unlock_kernel(); 273 mutex_unlock(&info->bfs_lock);
268 brelse(old_bh); 274 brelse(old_bh);
269 brelse(new_bh); 275 brelse(new_bh);
270 return error; 276 return error;
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index b11e63e8fbcd..6a021265f018 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -99,7 +99,7 @@ static int bfs_get_block(struct inode *inode, sector_t block,
99 return -ENOSPC; 99 return -ENOSPC;
100 100
101 /* The rest has to be protected against itself. */ 101 /* The rest has to be protected against itself. */
102 lock_kernel(); 102 mutex_lock(&info->bfs_lock);
103 103
104 /* 104 /*
105 * If the last data block for this file is the last allocated 105 * If the last data block for this file is the last allocated
@@ -151,7 +151,7 @@ static int bfs_get_block(struct inode *inode, sector_t block,
151 mark_buffer_dirty(sbh); 151 mark_buffer_dirty(sbh);
152 map_bh(bh_result, sb, phys); 152 map_bh(bh_result, sb, phys);
153out: 153out:
154 unlock_kernel(); 154 mutex_unlock(&info->bfs_lock);
155 return err; 155 return err;
156} 156}
157 157
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index c8b3982e11ca..053e690ec9ed 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -104,6 +104,7 @@ static int bfs_write_inode(struct inode *inode, int unused)
104 struct bfs_inode *di; 104 struct bfs_inode *di;
105 struct buffer_head *bh; 105 struct buffer_head *bh;
106 int block, off; 106 int block, off;
107 struct bfs_sb_info *info = BFS_SB(inode->i_sb);
107 108
108 dprintf("ino=%08x\n", ino); 109 dprintf("ino=%08x\n", ino);
109 110
@@ -112,13 +113,13 @@ static int bfs_write_inode(struct inode *inode, int unused)
112 return -EIO; 113 return -EIO;
113 } 114 }
114 115
115 lock_kernel(); 116 mutex_lock(&info->bfs_lock);
116 block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; 117 block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
117 bh = sb_bread(inode->i_sb, block); 118 bh = sb_bread(inode->i_sb, block);
118 if (!bh) { 119 if (!bh) {
119 printf("Unable to read inode %s:%08x\n", 120 printf("Unable to read inode %s:%08x\n",
120 inode->i_sb->s_id, ino); 121 inode->i_sb->s_id, ino);
121 unlock_kernel(); 122 mutex_unlock(&info->bfs_lock);
122 return -EIO; 123 return -EIO;
123 } 124 }
124 125
@@ -145,7 +146,7 @@ static int bfs_write_inode(struct inode *inode, int unused)
145 146
146 mark_buffer_dirty(bh); 147 mark_buffer_dirty(bh);
147 brelse(bh); 148 brelse(bh);
148 unlock_kernel(); 149 mutex_unlock(&info->bfs_lock);
149 return 0; 150 return 0;
150} 151}
151 152
@@ -170,7 +171,7 @@ static void bfs_delete_inode(struct inode *inode)
170 171
171 inode->i_size = 0; 172 inode->i_size = 0;
172 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; 173 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
173 lock_kernel(); 174 mutex_lock(&info->bfs_lock);
174 mark_inode_dirty(inode); 175 mark_inode_dirty(inode);
175 176
176 block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; 177 block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
@@ -178,7 +179,7 @@ static void bfs_delete_inode(struct inode *inode)
178 if (!bh) { 179 if (!bh) {
179 printf("Unable to read inode %s:%08lx\n", 180 printf("Unable to read inode %s:%08lx\n",
180 inode->i_sb->s_id, ino); 181 inode->i_sb->s_id, ino);
181 unlock_kernel(); 182 mutex_unlock(&info->bfs_lock);
182 return; 183 return;
183 } 184 }
184 off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; 185 off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
@@ -204,14 +205,16 @@ static void bfs_delete_inode(struct inode *inode)
204 info->si_lf_eblk = bi->i_sblock - 1; 205 info->si_lf_eblk = bi->i_sblock - 1;
205 mark_buffer_dirty(info->si_sbh); 206 mark_buffer_dirty(info->si_sbh);
206 } 207 }
207 unlock_kernel(); 208 mutex_unlock(&info->bfs_lock);
208 clear_inode(inode); 209 clear_inode(inode);
209} 210}
210 211
211static void bfs_put_super(struct super_block *s) 212static void bfs_put_super(struct super_block *s)
212{ 213{
213 struct bfs_sb_info *info = BFS_SB(s); 214 struct bfs_sb_info *info = BFS_SB(s);
215
214 brelse(info->si_sbh); 216 brelse(info->si_sbh);
217 mutex_destroy(&info->bfs_lock);
215 kfree(info->si_imap); 218 kfree(info->si_imap);
216 kfree(info); 219 kfree(info);
217 s->s_fs_info = NULL; 220 s->s_fs_info = NULL;
@@ -236,11 +239,13 @@ static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
236 239
237static void bfs_write_super(struct super_block *s) 240static void bfs_write_super(struct super_block *s)
238{ 241{
239 lock_kernel(); 242 struct bfs_sb_info *info = BFS_SB(s);
243
244 mutex_lock(&info->bfs_lock);
240 if (!(s->s_flags & MS_RDONLY)) 245 if (!(s->s_flags & MS_RDONLY))
241 mark_buffer_dirty(BFS_SB(s)->si_sbh); 246 mark_buffer_dirty(info->si_sbh);
242 s->s_dirt = 0; 247 s->s_dirt = 0;
243 unlock_kernel(); 248 mutex_unlock(&info->bfs_lock);
244} 249}
245 250
246static struct kmem_cache *bfs_inode_cachep; 251static struct kmem_cache *bfs_inode_cachep;
@@ -409,6 +414,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
409 s->s_dirt = 1; 414 s->s_dirt = 1;
410 } 415 }
411 dump_imap("read_super", s); 416 dump_imap("read_super", s);
417 mutex_init(&info->bfs_lock);
412 return 0; 418 return 0;
413 419
414out: 420out: