diff options
Diffstat (limited to 'fs/coda/inode.c')
-rw-r--r-- | fs/coda/inode.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 6526e6f21ecf..5ea57c8c7f97 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -15,7 +15,8 @@ | |||
15 | #include <linux/stat.h> | 15 | #include <linux/stat.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/unistd.h> | 17 | #include <linux/unistd.h> |
18 | #include <linux/smp_lock.h> | 18 | #include <linux/mutex.h> |
19 | #include <linux/spinlock.h> | ||
19 | #include <linux/file.h> | 20 | #include <linux/file.h> |
20 | #include <linux/vfs.h> | 21 | #include <linux/vfs.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -51,6 +52,7 @@ static struct inode *coda_alloc_inode(struct super_block *sb) | |||
51 | ei->c_flags = 0; | 52 | ei->c_flags = 0; |
52 | ei->c_uid = 0; | 53 | ei->c_uid = 0; |
53 | ei->c_cached_perm = 0; | 54 | ei->c_cached_perm = 0; |
55 | spin_lock_init(&ei->c_lock); | ||
54 | return &ei->vfs_inode; | 56 | return &ei->vfs_inode; |
55 | } | 57 | } |
56 | 58 | ||
@@ -143,7 +145,7 @@ static int get_device_index(struct coda_mount_data *data) | |||
143 | static int coda_fill_super(struct super_block *sb, void *data, int silent) | 145 | static int coda_fill_super(struct super_block *sb, void *data, int silent) |
144 | { | 146 | { |
145 | struct inode *root = NULL; | 147 | struct inode *root = NULL; |
146 | struct venus_comm *vc = NULL; | 148 | struct venus_comm *vc; |
147 | struct CodaFid fid; | 149 | struct CodaFid fid; |
148 | int error; | 150 | int error; |
149 | int idx; | 151 | int idx; |
@@ -157,21 +159,26 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
157 | printk(KERN_INFO "coda_read_super: device index: %i\n", idx); | 159 | printk(KERN_INFO "coda_read_super: device index: %i\n", idx); |
158 | 160 | ||
159 | vc = &coda_comms[idx]; | 161 | vc = &coda_comms[idx]; |
162 | mutex_lock(&vc->vc_mutex); | ||
163 | |||
160 | if (!vc->vc_inuse) { | 164 | if (!vc->vc_inuse) { |
161 | printk("coda_read_super: No pseudo device\n"); | 165 | printk("coda_read_super: No pseudo device\n"); |
162 | return -EINVAL; | 166 | error = -EINVAL; |
167 | goto unlock_out; | ||
163 | } | 168 | } |
164 | 169 | ||
165 | if ( vc->vc_sb ) { | 170 | if (vc->vc_sb) { |
166 | printk("coda_read_super: Device already mounted\n"); | 171 | printk("coda_read_super: Device already mounted\n"); |
167 | return -EBUSY; | 172 | error = -EBUSY; |
173 | goto unlock_out; | ||
168 | } | 174 | } |
169 | 175 | ||
170 | error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); | 176 | error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); |
171 | if (error) | 177 | if (error) |
172 | goto bdi_err; | 178 | goto unlock_out; |
173 | 179 | ||
174 | vc->vc_sb = sb; | 180 | vc->vc_sb = sb; |
181 | mutex_unlock(&vc->vc_mutex); | ||
175 | 182 | ||
176 | sb->s_fs_info = vc; | 183 | sb->s_fs_info = vc; |
177 | sb->s_flags |= MS_NOATIME; | 184 | sb->s_flags |= MS_NOATIME; |
@@ -200,26 +207,33 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
200 | printk("coda_read_super: rootinode is %ld dev %s\n", | 207 | printk("coda_read_super: rootinode is %ld dev %s\n", |
201 | root->i_ino, root->i_sb->s_id); | 208 | root->i_ino, root->i_sb->s_id); |
202 | sb->s_root = d_alloc_root(root); | 209 | sb->s_root = d_alloc_root(root); |
203 | if (!sb->s_root) | 210 | if (!sb->s_root) { |
211 | error = -EINVAL; | ||
204 | goto error; | 212 | goto error; |
205 | return 0; | 213 | } |
214 | return 0; | ||
206 | 215 | ||
207 | error: | 216 | error: |
208 | bdi_destroy(&vc->bdi); | ||
209 | bdi_err: | ||
210 | if (root) | 217 | if (root) |
211 | iput(root); | 218 | iput(root); |
212 | if (vc) | ||
213 | vc->vc_sb = NULL; | ||
214 | 219 | ||
215 | return -EINVAL; | 220 | mutex_lock(&vc->vc_mutex); |
221 | bdi_destroy(&vc->bdi); | ||
222 | vc->vc_sb = NULL; | ||
223 | sb->s_fs_info = NULL; | ||
224 | unlock_out: | ||
225 | mutex_unlock(&vc->vc_mutex); | ||
226 | return error; | ||
216 | } | 227 | } |
217 | 228 | ||
218 | static void coda_put_super(struct super_block *sb) | 229 | static void coda_put_super(struct super_block *sb) |
219 | { | 230 | { |
220 | bdi_destroy(&coda_vcp(sb)->bdi); | 231 | struct venus_comm *vcp = coda_vcp(sb); |
221 | coda_vcp(sb)->vc_sb = NULL; | 232 | mutex_lock(&vcp->vc_mutex); |
233 | bdi_destroy(&vcp->bdi); | ||
234 | vcp->vc_sb = NULL; | ||
222 | sb->s_fs_info = NULL; | 235 | sb->s_fs_info = NULL; |
236 | mutex_unlock(&vcp->vc_mutex); | ||
223 | 237 | ||
224 | printk("Coda: Bye bye.\n"); | 238 | printk("Coda: Bye bye.\n"); |
225 | } | 239 | } |
@@ -245,8 +259,6 @@ int coda_setattr(struct dentry *de, struct iattr *iattr) | |||
245 | struct coda_vattr vattr; | 259 | struct coda_vattr vattr; |
246 | int error; | 260 | int error; |
247 | 261 | ||
248 | lock_kernel(); | ||
249 | |||
250 | memset(&vattr, 0, sizeof(vattr)); | 262 | memset(&vattr, 0, sizeof(vattr)); |
251 | 263 | ||
252 | inode->i_ctime = CURRENT_TIME_SEC; | 264 | inode->i_ctime = CURRENT_TIME_SEC; |
@@ -256,13 +268,10 @@ int coda_setattr(struct dentry *de, struct iattr *iattr) | |||
256 | /* Venus is responsible for truncating the container-file!!! */ | 268 | /* Venus is responsible for truncating the container-file!!! */ |
257 | error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr); | 269 | error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr); |
258 | 270 | ||
259 | if ( !error ) { | 271 | if (!error) { |
260 | coda_vattr_to_iattr(inode, &vattr); | 272 | coda_vattr_to_iattr(inode, &vattr); |
261 | coda_cache_clear_inode(inode); | 273 | coda_cache_clear_inode(inode); |
262 | } | 274 | } |
263 | |||
264 | unlock_kernel(); | ||
265 | |||
266 | return error; | 275 | return error; |
267 | } | 276 | } |
268 | 277 | ||
@@ -276,12 +285,8 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
276 | { | 285 | { |
277 | int error; | 286 | int error; |
278 | 287 | ||
279 | lock_kernel(); | ||
280 | |||
281 | error = venus_statfs(dentry, buf); | 288 | error = venus_statfs(dentry, buf); |
282 | 289 | ||
283 | unlock_kernel(); | ||
284 | |||
285 | if (error) { | 290 | if (error) { |
286 | /* fake something like AFS does */ | 291 | /* fake something like AFS does */ |
287 | buf->f_blocks = 9000000; | 292 | buf->f_blocks = 9000000; |
@@ -301,16 +306,16 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
301 | 306 | ||
302 | /* init_coda: used by filesystems.c to register coda */ | 307 | /* init_coda: used by filesystems.c to register coda */ |
303 | 308 | ||
304 | static int coda_get_sb(struct file_system_type *fs_type, | 309 | static struct dentry *coda_mount(struct file_system_type *fs_type, |
305 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 310 | int flags, const char *dev_name, void *data) |
306 | { | 311 | { |
307 | return get_sb_nodev(fs_type, flags, data, coda_fill_super, mnt); | 312 | return mount_nodev(fs_type, flags, data, coda_fill_super); |
308 | } | 313 | } |
309 | 314 | ||
310 | struct file_system_type coda_fs_type = { | 315 | struct file_system_type coda_fs_type = { |
311 | .owner = THIS_MODULE, | 316 | .owner = THIS_MODULE, |
312 | .name = "coda", | 317 | .name = "coda", |
313 | .get_sb = coda_get_sb, | 318 | .mount = coda_mount, |
314 | .kill_sb = kill_anon_super, | 319 | .kill_sb = kill_anon_super, |
315 | .fs_flags = FS_BINARY_MOUNTDATA, | 320 | .fs_flags = FS_BINARY_MOUNTDATA, |
316 | }; | 321 | }; |