diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2010-03-29 19:13:59 -0400 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2010-04-05 11:37:36 -0400 |
commit | 6d96d3ab7aea5f0e75205a0c97f8d1fdf82c5287 (patch) | |
tree | a4dfa0472e2e670de1da7e7c0905da12d4608ab4 | |
parent | d994f4058d9f9be7e44529b55fc6be6552901ead (diff) |
9p: Make sure we are able to clunk the cached fid on umount
dcache prune happen on umount. So we cannot mark the client
satus disconnect. That will prevent a 9p call to the server
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
-rw-r--r-- | fs/9p/v9fs.c | 13 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 1 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 3 | ||||
-rw-r--r-- | include/net/9p/client.h | 2 | ||||
-rw-r--r-- | net/9p/client.c | 18 |
5 files changed, 34 insertions, 3 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 2f814cf0c731..0b78ae8157b9 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -342,6 +342,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | |||
342 | p9_client_disconnect(v9ses->clnt); | 342 | p9_client_disconnect(v9ses->clnt); |
343 | } | 343 | } |
344 | 344 | ||
345 | /** | ||
346 | * v9fs_session_begin_cancel - Begin terminate of a session | ||
347 | * @v9ses: session to terminate | ||
348 | * | ||
349 | * After this call we don't allow any request other than clunk. | ||
350 | */ | ||
351 | |||
352 | void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses) | ||
353 | { | ||
354 | P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses); | ||
355 | p9_client_begin_disconnect(v9ses->clnt); | ||
356 | } | ||
357 | |||
345 | extern int v9fs_error_init(void); | 358 | extern int v9fs_error_init(void); |
346 | 359 | ||
347 | static struct kobject *v9fs_kobj; | 360 | 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_super.c b/fs/9p/vfs_super.c index 69357c0d9899..d1a3c809a291 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -193,6 +193,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
193 | 193 | ||
194 | kill_anon_super(s); | 194 | kill_anon_super(s); |
195 | 195 | ||
196 | v9fs_session_cancel(v9ses); | ||
196 | v9fs_session_close(v9ses); | 197 | v9fs_session_close(v9ses); |
197 | kfree(v9ses); | 198 | kfree(v9ses); |
198 | s->s_fs_info = NULL; | 199 | s->s_fs_info = NULL; |
@@ -205,7 +206,7 @@ v9fs_umount_begin(struct super_block *sb) | |||
205 | struct v9fs_session_info *v9ses; | 206 | struct v9fs_session_info *v9ses; |
206 | 207 | ||
207 | v9ses = sb->s_fs_info; | 208 | v9ses = sb->s_fs_info; |
208 | v9fs_session_cancel(v9ses); | 209 | v9fs_session_begin_cancel(v9ses); |
209 | } | 210 | } |
210 | 211 | ||
211 | static const struct super_operations v9fs_super_ops = { | 212 | static const struct super_operations v9fs_super_ops = { |
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index f076dfa75ae8..4f3760afc20f 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
@@ -54,6 +54,7 @@ enum p9_proto_versions{ | |||
54 | 54 | ||
55 | enum p9_trans_status { | 55 | enum p9_trans_status { |
56 | Connected, | 56 | Connected, |
57 | BeginDisconnect, | ||
57 | Disconnected, | 58 | Disconnected, |
58 | Hung, | 59 | Hung, |
59 | }; | 60 | }; |
@@ -198,6 +199,7 @@ int p9_client_version(struct p9_client *); | |||
198 | struct p9_client *p9_client_create(const char *dev_name, char *options); | 199 | struct p9_client *p9_client_create(const char *dev_name, char *options); |
199 | void p9_client_destroy(struct p9_client *clnt); | 200 | void p9_client_destroy(struct p9_client *clnt); |
200 | void p9_client_disconnect(struct p9_client *clnt); | 201 | void p9_client_disconnect(struct p9_client *clnt); |
202 | void p9_client_begin_disconnect(struct p9_client *clnt); | ||
201 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | 203 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, |
202 | char *uname, u32 n_uname, char *aname); | 204 | char *uname, u32 n_uname, char *aname); |
203 | struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, | 205 | struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, |
diff --git a/net/9p/client.c b/net/9p/client.c index e3e5bf4469ce..a037a29f3f0e 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -533,7 +533,12 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) | |||
533 | 533 | ||
534 | P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); | 534 | P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); |
535 | 535 | ||
536 | if (c->status != Connected) | 536 | /* we allow for any status other than disconnected */ |
537 | if (c->status == Disconnected) | ||
538 | return ERR_PTR(-EIO); | ||
539 | |||
540 | /* if status is begin_disconnected we allow only clunk request */ | ||
541 | if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) | ||
537 | return ERR_PTR(-EIO); | 542 | return ERR_PTR(-EIO); |
538 | 543 | ||
539 | if (signal_pending(current)) { | 544 | if (signal_pending(current)) { |
@@ -799,8 +804,10 @@ void p9_client_destroy(struct p9_client *clnt) | |||
799 | 804 | ||
800 | v9fs_put_trans(clnt->trans_mod); | 805 | v9fs_put_trans(clnt->trans_mod); |
801 | 806 | ||
802 | list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) | 807 | list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) { |
808 | printk(KERN_INFO "Found fid %d not clunked\n", fid->fid); | ||
803 | p9_fid_destroy(fid); | 809 | p9_fid_destroy(fid); |
810 | } | ||
804 | 811 | ||
805 | if (clnt->fidpool) | 812 | if (clnt->fidpool) |
806 | p9_idpool_destroy(clnt->fidpool); | 813 | p9_idpool_destroy(clnt->fidpool); |
@@ -818,6 +825,13 @@ void p9_client_disconnect(struct p9_client *clnt) | |||
818 | } | 825 | } |
819 | EXPORT_SYMBOL(p9_client_disconnect); | 826 | EXPORT_SYMBOL(p9_client_disconnect); |
820 | 827 | ||
828 | void p9_client_begin_disconnect(struct p9_client *clnt) | ||
829 | { | ||
830 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
831 | clnt->status = BeginDisconnect; | ||
832 | } | ||
833 | EXPORT_SYMBOL(p9_client_begin_disconnect); | ||
834 | |||
821 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | 835 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, |
822 | char *uname, u32 n_uname, char *aname) | 836 | char *uname, u32 n_uname, char *aname) |
823 | { | 837 | { |