aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/fid.c12
-rw-r--r--fs/9p/v9fs.c21
-rw-r--r--fs/9p/v9fs.h1
-rw-r--r--fs/9p/vfs_dir.c2
-rw-r--r--fs/9p/vfs_inode.c9
-rw-r--r--fs/9p/vfs_super.c3
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
353void 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
344extern int v9fs_error_init(void); 359extern int v9fs_error_init(void);
345 360
346static struct kobject *v9fs_kobj; 361static 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 *);
109void v9fs_session_close(struct v9fs_session_info *v9ses); 109void v9fs_session_close(struct v9fs_session_info *v9ses);
110void v9fs_session_cancel(struct v9fs_session_info *v9ses); 110void v9fs_session_cancel(struct v9fs_session_info *v9ses);
111void 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
433static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 433static 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
451static int 455static 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
212static const struct super_operations v9fs_super_ops = { 213static const struct super_operations v9fs_super_ops = {