Merge 9bb48c82aced ("tty: implement write_iter") into tty-linus
[linux-2.6-microblaze.git] / net / 9p / client.c
index 785a7bb..4f62f29 100644 (file)
@@ -903,6 +903,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
        fid->clnt = clnt;
        fid->rdir = NULL;
        fid->fid = 0;
+       refcount_set(&fid->count, 1);
 
        idr_preload(GFP_KERNEL);
        spin_lock_irq(&clnt->lock);
@@ -910,7 +911,6 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
                            GFP_NOWAIT);
        spin_unlock_irq(&clnt->lock);
        idr_preload_end();
-
        if (!ret)
                return fid;
 
@@ -1189,7 +1189,6 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
 
        p9_debug(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
                 oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
-
        req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
                                                                nwname, wnames);
        if (IS_ERR(req)) {
@@ -1221,7 +1220,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
        if (nwname)
                memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
        else
-               fid->qid = oldfid->qid;
+               memmove(&fid->qid, &oldfid->qid, sizeof(struct p9_qid));
 
        kfree(wqids);
        return fid;
@@ -1274,6 +1273,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
                p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN",  qid.type,
                (unsigned long long)qid.path, qid.version, iounit);
 
+       memmove(&fid->qid, &qid, sizeof(struct p9_qid));
        fid->mode = mode;
        fid->iounit = iounit;
 
@@ -1319,6 +1319,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
                        (unsigned long long)qid->path,
                        qid->version, iounit);
 
+       memmove(&ofid->qid, qid, sizeof(struct p9_qid));
        ofid->mode = mode;
        ofid->iounit = iounit;
 
@@ -1364,6 +1365,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
                                (unsigned long long)qid.path,
                                qid.version, iounit);
 
+       memmove(&fid->qid, &qid, sizeof(struct p9_qid));
        fid->mode = mode;
        fid->iounit = iounit;
 
@@ -1460,12 +1462,14 @@ int p9_client_clunk(struct p9_fid *fid)
        struct p9_req_t *req;
        int retries = 0;
 
-       if (!fid) {
-               pr_warn("%s (%d): Trying to clunk with NULL fid\n",
+       if (!fid || IS_ERR(fid)) {
+               pr_warn("%s (%d): Trying to clunk with invalid fid\n",
                        __func__, task_pid_nr(current));
                dump_stack();
                return 0;
        }
+       if (!refcount_dec_and_test(&fid->count))
+               return 0;
 
 again:
        p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,