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>
This commit is contained in:
committed by
Eric Van Hensbergen
parent
d994f4058d
commit
6d96d3ab7a
13
fs/9p/v9fs.c
13
fs/9p/v9fs.c
@@ -342,6 +342,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
|
|||||||
p9_client_disconnect(v9ses->clnt);
|
p9_client_disconnect(v9ses->clnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v9fs_session_begin_cancel - Begin terminate of a session
|
||||||
|
* @v9ses: session to terminate
|
||||||
|
*
|
||||||
|
* After this call we don't allow any request other than clunk.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
|
||||||
|
{
|
||||||
|
P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
|
||||||
|
p9_client_begin_disconnect(v9ses->clnt);
|
||||||
|
}
|
||||||
|
|
||||||
extern int v9fs_error_init(void);
|
extern int v9fs_error_init(void);
|
||||||
|
|
||||||
static struct kobject *v9fs_kobj;
|
static struct kobject *v9fs_kobj;
|
||||||
|
@@ -108,6 +108,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
|
|||||||
char *);
|
char *);
|
||||||
void v9fs_session_close(struct v9fs_session_info *v9ses);
|
void v9fs_session_close(struct v9fs_session_info *v9ses);
|
||||||
void v9fs_session_cancel(struct v9fs_session_info *v9ses);
|
void v9fs_session_cancel(struct v9fs_session_info *v9ses);
|
||||||
|
void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
|
||||||
|
|
||||||
#define V9FS_MAGIC 0x01021997
|
#define V9FS_MAGIC 0x01021997
|
||||||
|
|
||||||
|
@@ -193,6 +193,7 @@ static void v9fs_kill_super(struct super_block *s)
|
|||||||
|
|
||||||
kill_anon_super(s);
|
kill_anon_super(s);
|
||||||
|
|
||||||
|
v9fs_session_cancel(v9ses);
|
||||||
v9fs_session_close(v9ses);
|
v9fs_session_close(v9ses);
|
||||||
kfree(v9ses);
|
kfree(v9ses);
|
||||||
s->s_fs_info = NULL;
|
s->s_fs_info = NULL;
|
||||||
@@ -205,7 +206,7 @@ v9fs_umount_begin(struct super_block *sb)
|
|||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
|
|
||||||
v9ses = sb->s_fs_info;
|
v9ses = sb->s_fs_info;
|
||||||
v9fs_session_cancel(v9ses);
|
v9fs_session_begin_cancel(v9ses);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct super_operations v9fs_super_ops = {
|
static const struct super_operations v9fs_super_ops = {
|
||||||
|
@@ -54,6 +54,7 @@ enum p9_proto_versions{
|
|||||||
|
|
||||||
enum p9_trans_status {
|
enum p9_trans_status {
|
||||||
Connected,
|
Connected,
|
||||||
|
BeginDisconnect,
|
||||||
Disconnected,
|
Disconnected,
|
||||||
Hung,
|
Hung,
|
||||||
};
|
};
|
||||||
@@ -198,6 +199,7 @@ int p9_client_version(struct p9_client *);
|
|||||||
struct p9_client *p9_client_create(const char *dev_name, char *options);
|
struct p9_client *p9_client_create(const char *dev_name, char *options);
|
||||||
void p9_client_destroy(struct p9_client *clnt);
|
void p9_client_destroy(struct p9_client *clnt);
|
||||||
void p9_client_disconnect(struct p9_client *clnt);
|
void p9_client_disconnect(struct p9_client *clnt);
|
||||||
|
void p9_client_begin_disconnect(struct p9_client *clnt);
|
||||||
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
|
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
|
||||||
char *uname, u32 n_uname, char *aname);
|
char *uname, u32 n_uname, char *aname);
|
||||||
struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
|
struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
|
||||||
|
@@ -533,7 +533,12 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
|
|||||||
|
|
||||||
P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
|
P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
|
||||||
|
|
||||||
if (c->status != Connected)
|
/* we allow for any status other than disconnected */
|
||||||
|
if (c->status == Disconnected)
|
||||||
|
return ERR_PTR(-EIO);
|
||||||
|
|
||||||
|
/* if status is begin_disconnected we allow only clunk request */
|
||||||
|
if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(-EIO);
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
@@ -799,8 +804,10 @@ void p9_client_destroy(struct p9_client *clnt)
|
|||||||
|
|
||||||
v9fs_put_trans(clnt->trans_mod);
|
v9fs_put_trans(clnt->trans_mod);
|
||||||
|
|
||||||
list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
|
list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
|
||||||
|
printk(KERN_INFO "Found fid %d not clunked\n", fid->fid);
|
||||||
p9_fid_destroy(fid);
|
p9_fid_destroy(fid);
|
||||||
|
}
|
||||||
|
|
||||||
if (clnt->fidpool)
|
if (clnt->fidpool)
|
||||||
p9_idpool_destroy(clnt->fidpool);
|
p9_idpool_destroy(clnt->fidpool);
|
||||||
@@ -818,6 +825,13 @@ void p9_client_disconnect(struct p9_client *clnt)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(p9_client_disconnect);
|
EXPORT_SYMBOL(p9_client_disconnect);
|
||||||
|
|
||||||
|
void p9_client_begin_disconnect(struct p9_client *clnt)
|
||||||
|
{
|
||||||
|
P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
|
||||||
|
clnt->status = BeginDisconnect;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(p9_client_begin_disconnect);
|
||||||
|
|
||||||
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
|
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
|
||||||
char *uname, u32 n_uname, char *aname)
|
char *uname, u32 n_uname, char *aname)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user