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);
 
 static struct kobject *v9fs_kobj;
 
                                                                        char *);
 void v9fs_session_close(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
 
 
 
        kill_anon_super(s);
 
+       v9fs_session_cancel(v9ses);
        v9fs_session_close(v9ses);
        kfree(v9ses);
        s->s_fs_info = NULL;
        struct v9fs_session_info *v9ses;
 
        v9ses = sb->s_fs_info;
-       v9fs_session_cancel(v9ses);
+       v9fs_session_begin_cancel(v9ses);
 }
 
 static const struct super_operations v9fs_super_ops = {
 
 
 enum p9_trans_status {
        Connected,
+       BeginDisconnect,
        Disconnected,
        Hung,
 };
 struct p9_client *p9_client_create(const char *dev_name, char *options);
 void p9_client_destroy(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,
                                        char *uname, u32 n_uname, char *aname);
 struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
 
 
        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);
 
        if (signal_pending(current)) {
 
        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);
+       }
 
        if (clnt->fidpool)
                p9_idpool_destroy(clnt->fidpool);
 }
 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,
        char *uname, u32 n_uname, char *aname)
 {