diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/fid.c | 12 | ||||
-rw-r--r-- | fs/9p/v9fs.c | 21 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 1 | ||||
-rw-r--r-- | fs/9p/vfs_dir.c | 2 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 9 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 3 |
6 files changed, 41 insertions, 7 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 82ee460e534d..7317b39b2815 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -111,7 +111,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
111 | { | 111 | { |
112 | int i, n, l, clone, any, access; | 112 | int i, n, l, clone, any, access; |
113 | u32 uid; | 113 | u32 uid; |
114 | struct p9_fid *fid; | 114 | struct p9_fid *fid, *old_fid = NULL; |
115 | struct dentry *d, *ds; | 115 | struct dentry *d, *ds; |
116 | struct v9fs_session_info *v9ses; | 116 | struct v9fs_session_info *v9ses; |
117 | char **wnames, *uname; | 117 | char **wnames, *uname; |
@@ -184,10 +184,18 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
184 | l = min(n - i, P9_MAXWELEM); | 184 | l = min(n - i, P9_MAXWELEM); |
185 | fid = p9_client_walk(fid, l, &wnames[i], clone); | 185 | fid = p9_client_walk(fid, l, &wnames[i], clone); |
186 | if (IS_ERR(fid)) { | 186 | if (IS_ERR(fid)) { |
187 | if (old_fid) { | ||
188 | /* | ||
189 | * If we fail, clunk fid which are mapping | ||
190 | * to path component and not the last component | ||
191 | * of the path. | ||
192 | */ | ||
193 | p9_client_clunk(old_fid); | ||
194 | } | ||
187 | kfree(wnames); | 195 | kfree(wnames); |
188 | return fid; | 196 | return fid; |
189 | } | 197 | } |
190 | 198 | old_fid = fid; | |
191 | i += l; | 199 | i += l; |
192 | clone = 0; | 200 | clone = 0; |
193 | } | 201 | } |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index cb57d3326182..5c5bc8480070 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -242,7 +242,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
242 | list_add(&v9ses->slist, &v9fs_sessionlist); | 242 | list_add(&v9ses->slist, &v9fs_sessionlist); |
243 | spin_unlock(&v9fs_sessionlist_lock); | 243 | spin_unlock(&v9fs_sessionlist_lock); |
244 | 244 | ||
245 | v9ses->flags = V9FS_PROTO_2000U | V9FS_ACCESS_USER; | 245 | v9ses->flags = V9FS_ACCESS_USER; |
246 | strcpy(v9ses->uname, V9FS_DEFUSER); | 246 | strcpy(v9ses->uname, V9FS_DEFUSER); |
247 | strcpy(v9ses->aname, V9FS_DEFANAME); | 247 | strcpy(v9ses->aname, V9FS_DEFANAME); |
248 | v9ses->uid = ~0; | 248 | v9ses->uid = ~0; |
@@ -263,8 +263,10 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
263 | goto error; | 263 | goto error; |
264 | } | 264 | } |
265 | 265 | ||
266 | if (!p9_is_proto_dotu(v9ses->clnt)) | 266 | if (p9_is_proto_dotl(v9ses->clnt)) |
267 | v9ses->flags &= ~V9FS_PROTO_2000U; | 267 | v9ses->flags |= V9FS_PROTO_2000L; |
268 | else if (p9_is_proto_dotu(v9ses->clnt)) | ||
269 | v9ses->flags |= V9FS_PROTO_2000U; | ||
268 | 270 | ||
269 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; | 271 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; |
270 | 272 | ||
@@ -341,6 +343,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | |||
341 | p9_client_disconnect(v9ses->clnt); | 343 | p9_client_disconnect(v9ses->clnt); |
342 | } | 344 | } |
343 | 345 | ||
346 | /** | ||
347 | * v9fs_session_begin_cancel - Begin terminate of a session | ||
348 | * @v9ses: session to terminate | ||
349 | * | ||
350 | * After this call we don't allow any request other than clunk. | ||
351 | */ | ||
352 | |||
353 | void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses) | ||
354 | { | ||
355 | P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses); | ||
356 | p9_client_begin_disconnect(v9ses->clnt); | ||
357 | } | ||
358 | |||
344 | extern int v9fs_error_init(void); | 359 | extern int v9fs_error_init(void); |
345 | 360 | ||
346 | static struct kobject *v9fs_kobj; | 361 | static struct kobject *v9fs_kobj; |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 6b801d1ddf4b..a0a8d3dd1361 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -108,6 +108,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | |||
108 | char *); | 108 | char *); |
109 | void v9fs_session_close(struct v9fs_session_info *v9ses); | 109 | void v9fs_session_close(struct v9fs_session_info *v9ses); |
110 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); | 110 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); |
111 | void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses); | ||
111 | 112 | ||
112 | #define V9FS_MAGIC 0x01021997 | 113 | #define V9FS_MAGIC 0x01021997 |
113 | 114 | ||
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 909711f57c0d..0adfd64dfcee 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -131,6 +131,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
131 | rdir = (struct p9_rdir *) fid->rdir; | 131 | rdir = (struct p9_rdir *) fid->rdir; |
132 | 132 | ||
133 | err = mutex_lock_interruptible(&rdir->mutex); | 133 | err = mutex_lock_interruptible(&rdir->mutex); |
134 | if (err) | ||
135 | return err; | ||
134 | while (err == 0) { | 136 | while (err == 0) { |
135 | if (rdir->tail == rdir->head) { | 137 | if (rdir->tail == rdir->head) { |
136 | err = v9fs_file_readn(filp, rdir->buf, NULL, | 138 | err = v9fs_file_readn(filp, rdir->buf, NULL, |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 63c2b5af268a..f2434fc9d2c4 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -432,6 +432,7 @@ error: | |||
432 | 432 | ||
433 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 433 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) |
434 | { | 434 | { |
435 | int retval; | ||
435 | struct inode *file_inode; | 436 | struct inode *file_inode; |
436 | struct v9fs_session_info *v9ses; | 437 | struct v9fs_session_info *v9ses; |
437 | struct p9_fid *v9fid; | 438 | struct p9_fid *v9fid; |
@@ -445,7 +446,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | |||
445 | if (IS_ERR(v9fid)) | 446 | if (IS_ERR(v9fid)) |
446 | return PTR_ERR(v9fid); | 447 | return PTR_ERR(v9fid); |
447 | 448 | ||
448 | return p9_client_remove(v9fid); | 449 | retval = p9_client_remove(v9fid); |
450 | if (!retval) | ||
451 | drop_nlink(file_inode); | ||
452 | return retval; | ||
449 | } | 453 | } |
450 | 454 | ||
451 | static int | 455 | static int |
@@ -657,6 +661,9 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
657 | P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", | 661 | P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", |
658 | dir, dentry->d_name.name, dentry, nameidata); | 662 | dir, dentry->d_name.name, dentry, nameidata); |
659 | 663 | ||
664 | if (dentry->d_name.len > NAME_MAX) | ||
665 | return ERR_PTR(-ENAMETOOLONG); | ||
666 | |||
660 | sb = dir->i_sb; | 667 | sb = dir->i_sb; |
661 | v9ses = v9fs_inode2v9ses(dir); | 668 | v9ses = v9fs_inode2v9ses(dir); |
662 | dfid = v9fs_fid_lookup(dentry->d_parent); | 669 | dfid = v9fs_fid_lookup(dentry->d_parent); |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index a271549d9e21..491108bd6e0d 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -194,6 +194,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
194 | 194 | ||
195 | kill_anon_super(s); | 195 | kill_anon_super(s); |
196 | 196 | ||
197 | v9fs_session_cancel(v9ses); | ||
197 | v9fs_session_close(v9ses); | 198 | v9fs_session_close(v9ses); |
198 | kfree(v9ses); | 199 | kfree(v9ses); |
199 | s->s_fs_info = NULL; | 200 | s->s_fs_info = NULL; |
@@ -206,7 +207,7 @@ v9fs_umount_begin(struct super_block *sb) | |||
206 | struct v9fs_session_info *v9ses; | 207 | struct v9fs_session_info *v9ses; |
207 | 208 | ||
208 | v9ses = sb->s_fs_info; | 209 | v9ses = sb->s_fs_info; |
209 | v9fs_session_cancel(v9ses); | 210 | v9fs_session_begin_cancel(v9ses); |
210 | } | 211 | } |
211 | 212 | ||
212 | static const struct super_operations v9fs_super_ops = { | 213 | static const struct super_operations v9fs_super_ops = { |