diff options
author | Jim Garlick <garlick@llnl.gov> | 2012-02-26 14:49:57 -0600 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2012-02-26 14:49:57 -0600 |
commit | 208f3c28aab706fca2bc1bae7091da8a99c5e322 (patch) | |
tree | aa05253f7dece741e2a9a90a0fad2879a54b2039 /net | |
parent | a314f2748e76c866222a18e639c640d584d277fb (diff) | |
download | op-kernel-dev-208f3c28aab706fca2bc1bae7091da8a99c5e322.zip op-kernel-dev-208f3c28aab706fca2bc1bae7091da8a99c5e322.tar.gz |
net/9p: handle flushed Tclunk/Tremove
When a Tclunk or Tremove request is flushed, the fid is not freed on the
server.
p9_client_clunk() should retry once on interrupt, then if interrupted
again, leak the fid for the duration of the connection.
p9_client_remove() should call p9_client_clunk() on interrupt
instead of unconditionally destroying the fid.
Signed-off-by: Jim Garlick <garlick@llnl.gov>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 6efbb33..b23a17c 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1428,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", @@ -1436,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; @@ -1452,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); @@ -1478,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); |