diff options
author | Linus Torvalds | 2012-03-28 09:58:38 -0700 |
---|---|---|
committer | Linus Torvalds | 2012-03-28 09:58:38 -0700 |
commit | e9c0f1529c9022afbab16a442382aa9a84a79c41 (patch) | |
tree | 173e99d46283f5d814bf4407728ad0d2ea702100 | |
parent | b18dafc86bb879d2f38a1743985d7ceb283c2f4d (diff) | |
parent | 5bdad93387c64f0095df7ae9a252ff44234a8b3f (diff) |
Merge tag 'for-linus-3.4-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull 9p changes for the 3.4 merge window from Eric Van Hensbergen.
* tag 'for-linus-3.4-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
9p: statfs should not override server f_type
net/9p: handle flushed Tclunk/Tremove
net/9p: don't allow Tflush to be interrupted
-rw-r--r-- | fs/9p/vfs_super.c | 2 | ||||
-rw-r--r-- | net/9p/client.c | 26 |
2 files changed, 24 insertions, 4 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 10b7d3c9dba8..8c92a9ba8330 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -259,7 +259,7 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf) if (v9fs_proto_dotl(v9ses)) { res = p9_client_statfs(fid, &rs); if (res == 0) { - buf->f_type = V9FS_MAGIC; + buf->f_type = rs.type; buf->f_bsize = rs.bsize; buf->f_blocks = rs.blocks; buf->f_bfree = rs.bfree; diff --git a/net/9p/client.c b/net/9p/client.c index 776618cd2be5..b23a17c431c8 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -740,10 +740,18 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) c->status = Disconnected; goto reterr; } +again: /* Wait for the response */ err = wait_event_interruptible(*req->wq, req->status >= REQ_STATUS_RCVD); + if ((err == -ERESTARTSYS) && (c->status == Connected) + && (type == P9_TFLUSH)) { + sigpending = 1; + clear_thread_flag(TIF_SIGPENDING); + goto again; + } + if (req->status == REQ_STATUS_ERROR) { p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); err = req->t_err; @@ -1420,6 +1428,7 @@ int p9_client_clunk(struct p9_fid *fid) int err; struct p9_client *clnt; struct p9_req_t *req; + int retries = 0; if (!fid) { pr_warn("%s (%d): Trying to clunk with NULL fid\n", @@ -1428,7 +1437,9 @@ int p9_client_clunk(struct p9_fid *fid) return 0; } - p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid); +again: + p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid, + retries); err = 0; clnt = fid->clnt; @@ -1444,8 +1455,14 @@ int p9_client_clunk(struct p9_fid *fid) error: /* * Fid is not valid even after a failed clunk + * If interrupted, retry once then give up and + * leak fid until umount. */ - p9_fid_destroy(fid); + if (err == -ERESTARTSYS) { + if (retries++ == 0) + goto again; + } else + p9_fid_destroy(fid); return err; } EXPORT_SYMBOL(p9_client_clunk); @@ -1470,7 +1487,10 @@ int p9_client_remove(struct p9_fid *fid) p9_free_req(clnt, req); error: - p9_fid_destroy(fid); + if (err == -ERESTARTSYS) + p9_client_clunk(fid); + else + p9_fid_destroy(fid); return err; } EXPORT_SYMBOL(p9_client_remove); |