~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to net/9p/client.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include <linux/poll.h>
30
30
#include <linux/idr.h>
31
31
#include <linux/mutex.h>
 
32
#include <linux/slab.h>
32
33
#include <linux/sched.h>
33
34
#include <linux/uaccess.h>
34
35
#include <net/9p/9p.h>
46
47
        Opt_msize,
47
48
        Opt_trans,
48
49
        Opt_legacy,
 
50
        Opt_version,
49
51
        Opt_err,
50
52
};
51
53
 
53
55
        {Opt_msize, "msize=%u"},
54
56
        {Opt_legacy, "noextend"},
55
57
        {Opt_trans, "trans=%s"},
 
58
        {Opt_version, "version=%s"},
56
59
        {Opt_err, NULL},
57
60
};
58
61
 
 
62
inline int p9_is_proto_dotl(struct p9_client *clnt)
 
63
{
 
64
        return clnt->proto_version == p9_proto_2000L;
 
65
}
 
66
EXPORT_SYMBOL(p9_is_proto_dotl);
 
67
 
 
68
inline int p9_is_proto_dotu(struct p9_client *clnt)
 
69
{
 
70
        return clnt->proto_version == p9_proto_2000u;
 
71
}
 
72
EXPORT_SYMBOL(p9_is_proto_dotu);
 
73
 
 
74
/* Interpret mount option for protocol version */
 
75
static int get_protocol_version(const substring_t *name)
 
76
{
 
77
        int version = -EINVAL;
 
78
 
 
79
        if (!strncmp("9p2000", name->from, name->to-name->from)) {
 
80
                version = p9_proto_legacy;
 
81
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
 
82
        } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) {
 
83
                version = p9_proto_2000u;
 
84
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
 
85
        } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) {
 
86
                version = p9_proto_2000L;
 
87
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
 
88
        } else {
 
89
                P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ",
 
90
                                                        name->from);
 
91
        }
 
92
        return version;
 
93
}
 
94
 
59
95
static struct p9_req_t *
60
96
p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
61
97
 
69
105
 
70
106
static int parse_opts(char *opts, struct p9_client *clnt)
71
107
{
72
 
        char *options;
 
108
        char *options, *tmp_options;
73
109
        char *p;
74
110
        substring_t args[MAX_OPT_ARGS];
75
111
        int option;
76
112
        int ret = 0;
77
113
 
78
 
        clnt->dotu = 1;
 
114
        clnt->proto_version = p9_proto_2000u;
79
115
        clnt->msize = 8192;
80
116
 
81
117
        if (!opts)
82
118
                return 0;
83
119
 
84
 
        options = kstrdup(opts, GFP_KERNEL);
85
 
        if (!options) {
 
120
        tmp_options = kstrdup(opts, GFP_KERNEL);
 
121
        if (!tmp_options) {
86
122
                P9_DPRINTK(P9_DEBUG_ERROR,
87
123
                                "failed to allocate copy of option string\n");
88
124
                return -ENOMEM;
89
125
        }
 
126
        options = tmp_options;
90
127
 
91
128
        while ((p = strsep(&options, ",")) != NULL) {
92
129
                int token;
108
145
                        break;
109
146
                case Opt_trans:
110
147
                        clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
 
148
                        if(clnt->trans_mod == NULL) {
 
149
                                P9_DPRINTK(P9_DEBUG_ERROR,
 
150
                                   "Could not find request transport: %s\n",
 
151
                                   (char *) &args[0]);
 
152
                                ret = -EINVAL;
 
153
                                goto free_and_return;
 
154
                        }
111
155
                        break;
112
156
                case Opt_legacy:
113
 
                        clnt->dotu = 0;
 
157
                        clnt->proto_version = p9_proto_legacy;
 
158
                        break;
 
159
                case Opt_version:
 
160
                        ret = get_protocol_version(&args[0]);
 
161
                        if (ret == -EINVAL)
 
162
                                goto free_and_return;
 
163
                        clnt->proto_version = ret;
114
164
                        break;
115
165
                default:
116
166
                        continue;
117
167
                }
118
168
        }
119
169
 
120
 
        kfree(options);
 
170
free_and_return:
 
171
        kfree(tmp_options);
121
172
        return ret;
122
173
}
123
174
 
280
331
                }
281
332
        }
282
333
 
283
 
        if (c->tagpool)
 
334
        if (c->tagpool) {
 
335
                p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */
284
336
                p9_idpool_destroy(c->tagpool);
 
337
        }
285
338
 
286
339
        /* free requests associated with tags */
287
340
        for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
397
450
                return err;
398
451
        }
399
452
 
400
 
        if (type == P9_RERROR) {
 
453
        if (type == P9_RERROR || type == P9_RLERROR) {
401
454
                int ecode;
402
 
                char *ename;
403
 
 
404
 
                err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode);
405
 
                if (err) {
406
 
                        P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
407
 
                                                                        err);
408
 
                        return err;
409
 
                }
410
 
 
411
 
                if (c->dotu)
 
455
 
 
456
                if (!p9_is_proto_dotl(c)) {
 
457
                        char *ename;
 
458
 
 
459
                        err = p9pdu_readf(req->rc, c->proto_version, "s?d",
 
460
                                                                &ename, &ecode);
 
461
                        if (err)
 
462
                                goto out_err;
 
463
 
 
464
                        if (p9_is_proto_dotu(c))
 
465
                                err = -ecode;
 
466
 
 
467
                        if (!err || !IS_ERR_VALUE(err)) {
 
468
                                err = p9_errstr2errno(ename, strlen(ename));
 
469
 
 
470
                                P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
 
471
 
 
472
                                kfree(ename);
 
473
                        }
 
474
                } else {
 
475
                        err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
412
476
                        err = -ecode;
413
477
 
414
 
                if (!err || !IS_ERR_VALUE(err))
415
 
                        err = p9_errstr2errno(ename, strlen(ename));
416
 
 
417
 
                P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
418
 
 
419
 
                kfree(ename);
 
478
                        P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
 
479
                }
 
480
 
420
481
        } else
421
482
                err = 0;
422
483
 
423
484
        return err;
 
485
 
 
486
out_err:
 
487
        P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
 
488
 
 
489
        return err;
424
490
}
425
491
 
426
492
/**
483
549
 
484
550
        P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
485
551
 
486
 
        if (c->status != Connected)
 
552
        /* we allow for any status other than disconnected */
 
553
        if (c->status == Disconnected)
 
554
                return ERR_PTR(-EIO);
 
555
 
 
556
        /* if status is begin_disconnected we allow only clunk request */
 
557
        if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
487
558
                return ERR_PTR(-EIO);
488
559
 
489
560
        if (signal_pending(current)) {
506
577
        /* marshall the data */
507
578
        p9pdu_prepare(req->tc, tag, type);
508
579
        va_start(ap, fmt);
509
 
        err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap);
 
580
        err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
510
581
        va_end(ap);
 
582
        if (err)
 
583
                goto reterr;
511
584
        p9pdu_finalize(req->tc);
512
585
 
513
586
        err = c->trans_mod->request(c, req);
514
587
        if (err < 0) {
515
 
                c->status = Disconnected;
 
588
                if (err != -ERESTARTSYS)
 
589
                        c->status = Disconnected;
516
590
                goto reterr;
517
591
        }
518
592
 
611
685
        kfree(fid);
612
686
}
613
687
 
614
 
int p9_client_version(struct p9_client *c)
 
688
static int p9_client_version(struct p9_client *c)
615
689
{
616
690
        int err = 0;
617
691
        struct p9_req_t *req;
618
692
        char *version;
619
693
        int msize;
620
694
 
621
 
        P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n",
622
 
                                                        c->msize, c->dotu);
623
 
        req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize,
624
 
                                c->dotu ? "9P2000.u" : "9P2000");
 
695
        P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n",
 
696
                                                c->msize, c->proto_version);
 
697
 
 
698
        switch (c->proto_version) {
 
699
        case p9_proto_2000L:
 
700
                req = p9_client_rpc(c, P9_TVERSION, "ds",
 
701
                                        c->msize, "9P2000.L");
 
702
                break;
 
703
        case p9_proto_2000u:
 
704
                req = p9_client_rpc(c, P9_TVERSION, "ds",
 
705
                                        c->msize, "9P2000.u");
 
706
                break;
 
707
        case p9_proto_legacy:
 
708
                req = p9_client_rpc(c, P9_TVERSION, "ds",
 
709
                                        c->msize, "9P2000");
 
710
                break;
 
711
        default:
 
712
                return -EINVAL;
 
713
                break;
 
714
        }
 
715
 
625
716
        if (IS_ERR(req))
626
717
                return PTR_ERR(req);
627
718
 
628
 
        err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version);
 
719
        err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
629
720
        if (err) {
630
721
                P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
631
722
                p9pdu_dump(1, req->rc);
633
724
        }
634
725
 
635
726
        P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
636
 
        if (!memcmp(version, "9P2000.u", 8))
637
 
                c->dotu = 1;
638
 
        else if (!memcmp(version, "9P2000", 6))
639
 
                c->dotu = 0;
 
727
        if (!strncmp(version, "9P2000.L", 8))
 
728
                c->proto_version = p9_proto_2000L;
 
729
        else if (!strncmp(version, "9P2000.u", 8))
 
730
                c->proto_version = p9_proto_2000u;
 
731
        else if (!strncmp(version, "9P2000", 6))
 
732
                c->proto_version = p9_proto_legacy;
640
733
        else {
641
734
                err = -EREMOTEIO;
642
735
                goto error;
651
744
 
652
745
        return err;
653
746
}
654
 
EXPORT_SYMBOL(p9_client_version);
655
747
 
656
748
struct p9_client *p9_client_create(const char *dev_name, char *options)
657
749
{
667
759
        clnt->trans = NULL;
668
760
        spin_lock_init(&clnt->lock);
669
761
        INIT_LIST_HEAD(&clnt->fidlist);
670
 
        clnt->fidpool = p9_idpool_create();
671
 
        if (IS_ERR(clnt->fidpool)) {
672
 
                err = PTR_ERR(clnt->fidpool);
673
 
                clnt->fidpool = NULL;
674
 
                goto error;
675
 
        }
676
762
 
677
763
        p9_tag_init(clnt);
678
764
 
679
765
        err = parse_opts(options, clnt);
680
766
        if (err < 0)
681
 
                goto error;
 
767
                goto free_client;
682
768
 
683
769
        if (!clnt->trans_mod)
684
770
                clnt->trans_mod = v9fs_get_default_trans();
687
773
                err = -EPROTONOSUPPORT;
688
774
                P9_DPRINTK(P9_DEBUG_ERROR,
689
775
                                "No transport defined or default transport\n");
690
 
                goto error;
691
 
        }
692
 
 
693
 
        P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n",
694
 
                clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
 
776
                goto free_client;
 
777
        }
 
778
 
 
779
        clnt->fidpool = p9_idpool_create();
 
780
        if (IS_ERR(clnt->fidpool)) {
 
781
                err = PTR_ERR(clnt->fidpool);
 
782
                clnt->fidpool = NULL;
 
783
                goto put_trans;
 
784
        }
 
785
 
 
786
        P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
 
787
                clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
695
788
 
696
789
        err = clnt->trans_mod->create(clnt, dev_name, options);
697
790
        if (err)
698
 
                goto error;
 
791
                goto destroy_fidpool;
699
792
 
700
793
        if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
701
794
                clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
702
795
 
703
796
        err = p9_client_version(clnt);
704
797
        if (err)
705
 
                goto error;
 
798
                goto close_trans;
706
799
 
707
800
        return clnt;
708
801
 
709
 
error:
710
 
        p9_client_destroy(clnt);
 
802
close_trans:
 
803
        clnt->trans_mod->close(clnt);
 
804
destroy_fidpool:
 
805
        p9_idpool_destroy(clnt->fidpool);
 
806
put_trans:
 
807
        v9fs_put_trans(clnt->trans_mod);
 
808
free_client:
 
809
        kfree(clnt);
711
810
        return ERR_PTR(err);
712
811
}
713
812
EXPORT_SYMBOL(p9_client_create);
723
822
 
724
823
        v9fs_put_trans(clnt->trans_mod);
725
824
 
726
 
        list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
 
825
        list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
 
826
                printk(KERN_INFO "Found fid %d not clunked\n", fid->fid);
727
827
                p9_fid_destroy(fid);
 
828
        }
728
829
 
729
830
        if (clnt->fidpool)
730
831
                p9_idpool_destroy(clnt->fidpool);
742
843
}
743
844
EXPORT_SYMBOL(p9_client_disconnect);
744
845
 
 
846
void p9_client_begin_disconnect(struct p9_client *clnt)
 
847
{
 
848
        P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
 
849
        clnt->status = BeginDisconnect;
 
850
}
 
851
EXPORT_SYMBOL(p9_client_begin_disconnect);
 
852
 
745
853
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
746
854
        char *uname, u32 n_uname, char *aname)
747
855
{
768
876
                goto error;
769
877
        }
770
878
 
771
 
        err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
 
879
        err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
772
880
        if (err) {
773
881
                p9pdu_dump(1, req->rc);
774
882
                p9_free_req(clnt, req);
792
900
}
793
901
EXPORT_SYMBOL(p9_client_attach);
794
902
 
795
 
struct p9_fid *
796
 
p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
797
 
{
798
 
        int err;
799
 
        struct p9_req_t *req;
800
 
        struct p9_qid qid;
801
 
        struct p9_fid *afid;
802
 
 
803
 
        P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
804
 
        err = 0;
805
 
 
806
 
        afid = p9_fid_create(clnt);
807
 
        if (IS_ERR(afid)) {
808
 
                err = PTR_ERR(afid);
809
 
                afid = NULL;
810
 
                goto error;
811
 
        }
812
 
 
813
 
        req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
814
 
                        afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
815
 
        if (IS_ERR(req)) {
816
 
                err = PTR_ERR(req);
817
 
                goto error;
818
 
        }
819
 
 
820
 
        err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
821
 
        if (err) {
822
 
                p9pdu_dump(1, req->rc);
823
 
                p9_free_req(clnt, req);
824
 
                goto error;
825
 
        }
826
 
 
827
 
        P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
828
 
                                        qid.type,
829
 
                                        (unsigned long long)qid.path,
830
 
                                        qid.version);
831
 
 
832
 
        memmove(&afid->qid, &qid, sizeof(struct p9_qid));
833
 
        p9_free_req(clnt, req);
834
 
        return afid;
835
 
 
836
 
error:
837
 
        if (afid)
838
 
                p9_fid_destroy(afid);
839
 
        return ERR_PTR(err);
840
 
}
841
 
EXPORT_SYMBOL(p9_client_auth);
842
 
 
843
903
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
844
904
        int clone)
845
905
{
851
911
        int16_t nwqids, count;
852
912
 
853
913
        err = 0;
 
914
        wqids = NULL;
854
915
        clnt = oldfid->clnt;
855
916
        if (clone) {
856
917
                fid = p9_fid_create(clnt);
875
936
                goto error;
876
937
        }
877
938
 
878
 
        err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids);
 
939
        err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
879
940
        if (err) {
880
941
                p9pdu_dump(1, req->rc);
881
942
                p9_free_req(clnt, req);
901
962
        else
902
963
                fid->qid = oldfid->qid;
903
964
 
 
965
        kfree(wqids);
904
966
        return fid;
905
967
 
906
968
clunk_fid:
 
969
        kfree(wqids);
907
970
        p9_client_clunk(fid);
908
971
        fid = NULL;
909
972
 
923
986
        struct p9_qid qid;
924
987
        int iounit;
925
988
 
926
 
        P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode);
 
989
        clnt = fid->clnt;
 
990
        P9_DPRINTK(P9_DEBUG_9P, ">>> %s fid %d mode %d\n",
 
991
                p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode);
927
992
        err = 0;
928
 
        clnt = fid->clnt;
929
993
 
930
994
        if (fid->mode != -1)
931
995
                return -EINVAL;
932
996
 
933
 
        req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
 
997
        if (p9_is_proto_dotl(clnt))
 
998
                req = p9_client_rpc(clnt, P9_TLOPEN, "dd", fid->fid, mode);
 
999
        else
 
1000
                req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
934
1001
        if (IS_ERR(req)) {
935
1002
                err = PTR_ERR(req);
936
1003
                goto error;
937
1004
        }
938
1005
 
939
 
        err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
 
1006
        err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
940
1007
        if (err) {
941
1008
                p9pdu_dump(1, req->rc);
942
1009
                goto free_and_error;
943
1010
        }
944
1011
 
945
 
        P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n",
946
 
                                qid.type,
947
 
                                (unsigned long long)qid.path,
948
 
                                qid.version, iounit);
 
1012
        P9_DPRINTK(P9_DEBUG_9P, "<<< %s qid %x.%llx.%x iounit %x\n",
 
1013
                p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN",  qid.type,
 
1014
                (unsigned long long)qid.path, qid.version, iounit);
949
1015
 
950
1016
        fid->mode = mode;
951
1017
        fid->iounit = iounit;
957
1023
}
958
1024
EXPORT_SYMBOL(p9_client_open);
959
1025
 
 
1026
int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
 
1027
                gid_t gid, struct p9_qid *qid)
 
1028
{
 
1029
        int err = 0;
 
1030
        struct p9_client *clnt;
 
1031
        struct p9_req_t *req;
 
1032
        int iounit;
 
1033
 
 
1034
        P9_DPRINTK(P9_DEBUG_9P,
 
1035
                        ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
 
1036
                        ofid->fid, name, flags, mode, gid);
 
1037
        clnt = ofid->clnt;
 
1038
 
 
1039
        if (ofid->mode != -1)
 
1040
                return -EINVAL;
 
1041
 
 
1042
        req = p9_client_rpc(clnt, P9_TLCREATE, "dsddd", ofid->fid, name, flags,
 
1043
                        mode, gid);
 
1044
        if (IS_ERR(req)) {
 
1045
                err = PTR_ERR(req);
 
1046
                goto error;
 
1047
        }
 
1048
 
 
1049
        err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
 
1050
        if (err) {
 
1051
                p9pdu_dump(1, req->rc);
 
1052
                goto free_and_error;
 
1053
        }
 
1054
 
 
1055
        P9_DPRINTK(P9_DEBUG_9P, "<<< RLCREATE qid %x.%llx.%x iounit %x\n",
 
1056
                        qid->type,
 
1057
                        (unsigned long long)qid->path,
 
1058
                        qid->version, iounit);
 
1059
 
 
1060
        ofid->mode = mode;
 
1061
        ofid->iounit = iounit;
 
1062
 
 
1063
free_and_error:
 
1064
        p9_free_req(clnt, req);
 
1065
error:
 
1066
        return err;
 
1067
}
 
1068
EXPORT_SYMBOL(p9_client_create_dotl);
 
1069
 
960
1070
int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
961
1071
                     char *extension)
962
1072
{
981
1091
                goto error;
982
1092
        }
983
1093
 
984
 
        err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
 
1094
        err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
985
1095
        if (err) {
986
1096
                p9pdu_dump(1, req->rc);
987
1097
                goto free_and_error;
1002
1112
}
1003
1113
EXPORT_SYMBOL(p9_client_fcreate);
1004
1114
 
 
1115
int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
 
1116
                struct p9_qid *qid)
 
1117
{
 
1118
        int err = 0;
 
1119
        struct p9_client *clnt;
 
1120
        struct p9_req_t *req;
 
1121
 
 
1122
        P9_DPRINTK(P9_DEBUG_9P, ">>> TSYMLINK dfid %d name %s  symtgt %s\n",
 
1123
                        dfid->fid, name, symtgt);
 
1124
        clnt = dfid->clnt;
 
1125
 
 
1126
        req = p9_client_rpc(clnt, P9_TSYMLINK, "dssd", dfid->fid, name, symtgt,
 
1127
                        gid);
 
1128
        if (IS_ERR(req)) {
 
1129
                err = PTR_ERR(req);
 
1130
                goto error;
 
1131
        }
 
1132
 
 
1133
        err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
 
1134
        if (err) {
 
1135
                p9pdu_dump(1, req->rc);
 
1136
                goto free_and_error;
 
1137
        }
 
1138
 
 
1139
        P9_DPRINTK(P9_DEBUG_9P, "<<< RSYMLINK qid %x.%llx.%x\n",
 
1140
                        qid->type, (unsigned long long)qid->path, qid->version);
 
1141
 
 
1142
free_and_error:
 
1143
        p9_free_req(clnt, req);
 
1144
error:
 
1145
        return err;
 
1146
}
 
1147
EXPORT_SYMBOL(p9_client_symlink);
 
1148
 
 
1149
int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, char *newname)
 
1150
{
 
1151
        struct p9_client *clnt;
 
1152
        struct p9_req_t *req;
 
1153
 
 
1154
        P9_DPRINTK(P9_DEBUG_9P, ">>> TLINK dfid %d oldfid %d newname %s\n",
 
1155
                        dfid->fid, oldfid->fid, newname);
 
1156
        clnt = dfid->clnt;
 
1157
        req = p9_client_rpc(clnt, P9_TLINK, "dds", dfid->fid, oldfid->fid,
 
1158
                        newname);
 
1159
        if (IS_ERR(req))
 
1160
                return PTR_ERR(req);
 
1161
 
 
1162
        P9_DPRINTK(P9_DEBUG_9P, "<<< RLINK\n");
 
1163
        p9_free_req(clnt, req);
 
1164
        return 0;
 
1165
}
 
1166
EXPORT_SYMBOL(p9_client_link);
 
1167
 
 
1168
int p9_client_fsync(struct p9_fid *fid, int datasync)
 
1169
{
 
1170
        int err;
 
1171
        struct p9_client *clnt;
 
1172
        struct p9_req_t *req;
 
1173
 
 
1174
        P9_DPRINTK(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
 
1175
                        fid->fid, datasync);
 
1176
        err = 0;
 
1177
        clnt = fid->clnt;
 
1178
 
 
1179
        req = p9_client_rpc(clnt, P9_TFSYNC, "dd", fid->fid, datasync);
 
1180
        if (IS_ERR(req)) {
 
1181
                err = PTR_ERR(req);
 
1182
                goto error;
 
1183
        }
 
1184
 
 
1185
        P9_DPRINTK(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
 
1186
 
 
1187
        p9_free_req(clnt, req);
 
1188
 
 
1189
error:
 
1190
        return err;
 
1191
}
 
1192
EXPORT_SYMBOL(p9_client_fsync);
 
1193
 
1005
1194
int p9_client_clunk(struct p9_fid *fid)
1006
1195
{
1007
1196
        int err;
1008
1197
        struct p9_client *clnt;
1009
1198
        struct p9_req_t *req;
1010
1199
 
 
1200
        if (!fid) {
 
1201
                P9_EPRINTK(KERN_WARNING, "Trying to clunk with NULL fid\n");
 
1202
                dump_stack();
 
1203
                return 0;
 
1204
        }
 
1205
 
1011
1206
        P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
1012
1207
        err = 0;
1013
1208
        clnt = fid->clnt;
1047
1242
        P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
1048
1243
 
1049
1244
        p9_free_req(clnt, req);
 
1245
error:
1050
1246
        p9_fid_destroy(fid);
1051
 
 
1052
 
error:
1053
1247
        return err;
1054
1248
}
1055
1249
EXPORT_SYMBOL(p9_client_remove);
1082
1276
                goto error;
1083
1277
        }
1084
1278
 
1085
 
        err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr);
 
1279
        err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1086
1280
        if (err) {
1087
1281
                p9pdu_dump(1, req->rc);
1088
1282
                goto free_and_error;
1092
1286
 
1093
1287
        if (data) {
1094
1288
                memmove(data, dataptr, count);
1095
 
        }
1096
 
 
1097
 
        if (udata) {
 
1289
        } else {
1098
1290
                err = copy_to_user(udata, dataptr, count);
1099
1291
                if (err) {
1100
1292
                        err = -EFAULT;
1101
1293
                        goto free_and_error;
1102
1294
                }
1103
1295
        }
1104
 
 
1105
1296
        p9_free_req(clnt, req);
1106
1297
        return count;
1107
1298
 
1143
1334
                goto error;
1144
1335
        }
1145
1336
 
1146
 
        err = p9pdu_readf(req->rc, clnt->dotu, "d", &count);
 
1337
        err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1147
1338
        if (err) {
1148
1339
                p9pdu_dump(1, req->rc);
1149
1340
                goto free_and_error;
1183
1374
                goto error;
1184
1375
        }
1185
1376
 
1186
 
        err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret);
 
1377
        err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
1187
1378
        if (err) {
1188
1379
                p9pdu_dump(1, req->rc);
1189
1380
                p9_free_req(clnt, req);
1210
1401
}
1211
1402
EXPORT_SYMBOL(p9_client_stat);
1212
1403
 
1213
 
static int p9_client_statsize(struct p9_wstat *wst, int optional)
 
1404
struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
 
1405
                                                        u64 request_mask)
 
1406
{
 
1407
        int err;
 
1408
        struct p9_client *clnt;
 
1409
        struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl),
 
1410
                                                                GFP_KERNEL);
 
1411
        struct p9_req_t *req;
 
1412
 
 
1413
        P9_DPRINTK(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n",
 
1414
                                                        fid->fid, request_mask);
 
1415
 
 
1416
        if (!ret)
 
1417
                return ERR_PTR(-ENOMEM);
 
1418
 
 
1419
        err = 0;
 
1420
        clnt = fid->clnt;
 
1421
 
 
1422
        req = p9_client_rpc(clnt, P9_TGETATTR, "dq", fid->fid, request_mask);
 
1423
        if (IS_ERR(req)) {
 
1424
                err = PTR_ERR(req);
 
1425
                goto error;
 
1426
        }
 
1427
 
 
1428
        err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
 
1429
        if (err) {
 
1430
                p9pdu_dump(1, req->rc);
 
1431
                p9_free_req(clnt, req);
 
1432
                goto error;
 
1433
        }
 
1434
 
 
1435
        P9_DPRINTK(P9_DEBUG_9P,
 
1436
                "<<< RGETATTR st_result_mask=%lld\n"
 
1437
                "<<< qid=%x.%llx.%x\n"
 
1438
                "<<< st_mode=%8.8x st_nlink=%llu\n"
 
1439
                "<<< st_uid=%d st_gid=%d\n"
 
1440
                "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n"
 
1441
                "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
 
1442
                "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
 
1443
                "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n"
 
1444
                "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
 
1445
                "<<< st_gen=%lld st_data_version=%lld",
 
1446
                ret->st_result_mask, ret->qid.type, ret->qid.path,
 
1447
                ret->qid.version, ret->st_mode, ret->st_nlink, ret->st_uid,
 
1448
                ret->st_gid, ret->st_rdev, ret->st_size, ret->st_blksize,
 
1449
                ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
 
1450
                ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
 
1451
                ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
 
1452
                ret->st_gen, ret->st_data_version);
 
1453
 
 
1454
        p9_free_req(clnt, req);
 
1455
        return ret;
 
1456
 
 
1457
error:
 
1458
        kfree(ret);
 
1459
        return ERR_PTR(err);
 
1460
}
 
1461
EXPORT_SYMBOL(p9_client_getattr_dotl);
 
1462
 
 
1463
static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
1214
1464
{
1215
1465
        int ret;
1216
1466
 
 
1467
        /* NOTE: size shouldn't include its own length */
1217
1468
        /* size[2] type[2] dev[4] qid[13] */
1218
1469
        /* mode[4] atime[4] mtime[4] length[8]*/
1219
1470
        /* name[s] uid[s] gid[s] muid[s] */
1220
 
        ret = 2+2+4+13+4+4+4+8+2+2+2+2;
 
1471
        ret = 2+4+13+4+4+4+8+2+2+2+2;
1221
1472
 
1222
1473
        if (wst->name)
1223
1474
                ret += strlen(wst->name);
1228
1479
        if (wst->muid)
1229
1480
                ret += strlen(wst->muid);
1230
1481
 
1231
 
        if (optional) {
 
1482
        if ((proto_version == p9_proto_2000u) ||
 
1483
                (proto_version == p9_proto_2000L)) {
1232
1484
                ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
1233
1485
                if (wst->extension)
1234
1486
                        ret += strlen(wst->extension);
1245
1497
 
1246
1498
        err = 0;
1247
1499
        clnt = fid->clnt;
1248
 
        wst->size = p9_client_statsize(wst, clnt->dotu);
 
1500
        wst->size = p9_client_statsize(wst, clnt->proto_version);
1249
1501
        P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
1250
1502
        P9_DPRINTK(P9_DEBUG_9P,
1251
1503
                "     sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
1258
1510
                wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
1259
1511
                wst->n_uid, wst->n_gid, wst->n_muid);
1260
1512
 
1261
 
        req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size, wst);
 
1513
        req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
1262
1514
        if (IS_ERR(req)) {
1263
1515
                err = PTR_ERR(req);
1264
1516
                goto error;
1271
1523
        return err;
1272
1524
}
1273
1525
EXPORT_SYMBOL(p9_client_wstat);
 
1526
 
 
1527
int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
 
1528
{
 
1529
        int err;
 
1530
        struct p9_req_t *req;
 
1531
        struct p9_client *clnt;
 
1532
 
 
1533
        err = 0;
 
1534
        clnt = fid->clnt;
 
1535
        P9_DPRINTK(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid);
 
1536
        P9_DPRINTK(P9_DEBUG_9P,
 
1537
                "    valid=%x mode=%x uid=%d gid=%d size=%lld\n"
 
1538
                "    atime_sec=%lld atime_nsec=%lld\n"
 
1539
                "    mtime_sec=%lld mtime_nsec=%lld\n",
 
1540
                p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid,
 
1541
                p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
 
1542
                p9attr->mtime_sec, p9attr->mtime_nsec);
 
1543
 
 
1544
        req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr);
 
1545
 
 
1546
        if (IS_ERR(req)) {
 
1547
                err = PTR_ERR(req);
 
1548
                goto error;
 
1549
        }
 
1550
        P9_DPRINTK(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
 
1551
        p9_free_req(clnt, req);
 
1552
error:
 
1553
        return err;
 
1554
}
 
1555
EXPORT_SYMBOL(p9_client_setattr);
 
1556
 
 
1557
int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
 
1558
{
 
1559
        int err;
 
1560
        struct p9_req_t *req;
 
1561
        struct p9_client *clnt;
 
1562
 
 
1563
        err = 0;
 
1564
        clnt = fid->clnt;
 
1565
 
 
1566
        P9_DPRINTK(P9_DEBUG_9P, ">>> TSTATFS fid %d\n", fid->fid);
 
1567
 
 
1568
        req = p9_client_rpc(clnt, P9_TSTATFS, "d", fid->fid);
 
1569
        if (IS_ERR(req)) {
 
1570
                err = PTR_ERR(req);
 
1571
                goto error;
 
1572
        }
 
1573
 
 
1574
        err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
 
1575
                &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
 
1576
                &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
 
1577
        if (err) {
 
1578
                p9pdu_dump(1, req->rc);
 
1579
                p9_free_req(clnt, req);
 
1580
                goto error;
 
1581
        }
 
1582
 
 
1583
        P9_DPRINTK(P9_DEBUG_9P, "<<< RSTATFS fid %d type 0x%lx bsize %ld "
 
1584
                "blocks %llu bfree %llu bavail %llu files %llu ffree %llu "
 
1585
                "fsid %llu namelen %ld\n",
 
1586
                fid->fid, (long unsigned int)sb->type, (long int)sb->bsize,
 
1587
                sb->blocks, sb->bfree, sb->bavail, sb->files,  sb->ffree,
 
1588
                sb->fsid, (long int)sb->namelen);
 
1589
 
 
1590
        p9_free_req(clnt, req);
 
1591
error:
 
1592
        return err;
 
1593
}
 
1594
EXPORT_SYMBOL(p9_client_statfs);
 
1595
 
 
1596
int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name)
 
1597
{
 
1598
        int err;
 
1599
        struct p9_req_t *req;
 
1600
        struct p9_client *clnt;
 
1601
 
 
1602
        err = 0;
 
1603
        clnt = fid->clnt;
 
1604
 
 
1605
        P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAME fid %d newdirfid %d name %s\n",
 
1606
                        fid->fid, newdirfid->fid, name);
 
1607
 
 
1608
        req = p9_client_rpc(clnt, P9_TRENAME, "dds", fid->fid,
 
1609
                        newdirfid->fid, name);
 
1610
        if (IS_ERR(req)) {
 
1611
                err = PTR_ERR(req);
 
1612
                goto error;
 
1613
        }
 
1614
 
 
1615
        P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
 
1616
 
 
1617
        p9_free_req(clnt, req);
 
1618
error:
 
1619
        return err;
 
1620
}
 
1621
EXPORT_SYMBOL(p9_client_rename);
 
1622
 
 
1623
/*
 
1624
 * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
 
1625
 */
 
1626
struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
 
1627
                                const char *attr_name, u64 *attr_size)
 
1628
{
 
1629
        int err;
 
1630
        struct p9_req_t *req;
 
1631
        struct p9_client *clnt;
 
1632
        struct p9_fid *attr_fid;
 
1633
 
 
1634
        err = 0;
 
1635
        clnt = file_fid->clnt;
 
1636
        attr_fid = p9_fid_create(clnt);
 
1637
        if (IS_ERR(attr_fid)) {
 
1638
                err = PTR_ERR(attr_fid);
 
1639
                attr_fid = NULL;
 
1640
                goto error;
 
1641
        }
 
1642
        P9_DPRINTK(P9_DEBUG_9P,
 
1643
                ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
 
1644
                file_fid->fid, attr_fid->fid, attr_name);
 
1645
 
 
1646
        req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
 
1647
                        file_fid->fid, attr_fid->fid, attr_name);
 
1648
        if (IS_ERR(req)) {
 
1649
                err = PTR_ERR(req);
 
1650
                goto error;
 
1651
        }
 
1652
        err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
 
1653
        if (err) {
 
1654
                p9pdu_dump(1, req->rc);
 
1655
                p9_free_req(clnt, req);
 
1656
                goto clunk_fid;
 
1657
        }
 
1658
        p9_free_req(clnt, req);
 
1659
        P9_DPRINTK(P9_DEBUG_9P, "<<<  RXATTRWALK fid %d size %llu\n",
 
1660
                attr_fid->fid, *attr_size);
 
1661
        return attr_fid;
 
1662
clunk_fid:
 
1663
        p9_client_clunk(attr_fid);
 
1664
        attr_fid = NULL;
 
1665
error:
 
1666
        if (attr_fid && (attr_fid != file_fid))
 
1667
                p9_fid_destroy(attr_fid);
 
1668
 
 
1669
        return ERR_PTR(err);
 
1670
}
 
1671
EXPORT_SYMBOL_GPL(p9_client_xattrwalk);
 
1672
 
 
1673
int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
 
1674
                        u64 attr_size, int flags)
 
1675
{
 
1676
        int err;
 
1677
        struct p9_req_t *req;
 
1678
        struct p9_client *clnt;
 
1679
 
 
1680
        P9_DPRINTK(P9_DEBUG_9P,
 
1681
                ">>> TXATTRCREATE fid %d name  %s size %lld flag %d\n",
 
1682
                fid->fid, name, (long long)attr_size, flags);
 
1683
        err = 0;
 
1684
        clnt = fid->clnt;
 
1685
        req = p9_client_rpc(clnt, P9_TXATTRCREATE, "dsqd",
 
1686
                        fid->fid, name, attr_size, flags);
 
1687
        if (IS_ERR(req)) {
 
1688
                err = PTR_ERR(req);
 
1689
                goto error;
 
1690
        }
 
1691
        P9_DPRINTK(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
 
1692
        p9_free_req(clnt, req);
 
1693
error:
 
1694
        return err;
 
1695
}
 
1696
EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
 
1697
 
 
1698
int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
 
1699
{
 
1700
        int err, rsize, total;
 
1701
        struct p9_client *clnt;
 
1702
        struct p9_req_t *req;
 
1703
        char *dataptr;
 
1704
 
 
1705
        P9_DPRINTK(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
 
1706
                                fid->fid, (long long unsigned) offset, count);
 
1707
 
 
1708
        err = 0;
 
1709
        clnt = fid->clnt;
 
1710
        total = 0;
 
1711
 
 
1712
        rsize = fid->iounit;
 
1713
        if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
 
1714
                rsize = clnt->msize - P9_READDIRHDRSZ;
 
1715
 
 
1716
        if (count < rsize)
 
1717
                rsize = count;
 
1718
 
 
1719
        req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid, offset, rsize);
 
1720
        if (IS_ERR(req)) {
 
1721
                err = PTR_ERR(req);
 
1722
                goto error;
 
1723
        }
 
1724
 
 
1725
        err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
 
1726
        if (err) {
 
1727
                p9pdu_dump(1, req->rc);
 
1728
                goto free_and_error;
 
1729
        }
 
1730
 
 
1731
        P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
 
1732
 
 
1733
        if (data)
 
1734
                memmove(data, dataptr, count);
 
1735
 
 
1736
        p9_free_req(clnt, req);
 
1737
        return count;
 
1738
 
 
1739
free_and_error:
 
1740
        p9_free_req(clnt, req);
 
1741
error:
 
1742
        return err;
 
1743
}
 
1744
EXPORT_SYMBOL(p9_client_readdir);
 
1745
 
 
1746
int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
 
1747
                        dev_t rdev, gid_t gid, struct p9_qid *qid)
 
1748
{
 
1749
        int err;
 
1750
        struct p9_client *clnt;
 
1751
        struct p9_req_t *req;
 
1752
 
 
1753
        err = 0;
 
1754
        clnt = fid->clnt;
 
1755
        P9_DPRINTK(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
 
1756
                "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
 
1757
        req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddd", fid->fid, name, mode,
 
1758
                MAJOR(rdev), MINOR(rdev), gid);
 
1759
        if (IS_ERR(req))
 
1760
                return PTR_ERR(req);
 
1761
 
 
1762
        err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
 
1763
        if (err) {
 
1764
                p9pdu_dump(1, req->rc);
 
1765
                goto error;
 
1766
        }
 
1767
        P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
 
1768
                                (unsigned long long)qid->path, qid->version);
 
1769
 
 
1770
error:
 
1771
        p9_free_req(clnt, req);
 
1772
        return err;
 
1773
 
 
1774
}
 
1775
EXPORT_SYMBOL(p9_client_mknod_dotl);
 
1776
 
 
1777
int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
 
1778
                                gid_t gid, struct p9_qid *qid)
 
1779
{
 
1780
        int err;
 
1781
        struct p9_client *clnt;
 
1782
        struct p9_req_t *req;
 
1783
 
 
1784
        err = 0;
 
1785
        clnt = fid->clnt;
 
1786
        P9_DPRINTK(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
 
1787
                 fid->fid, name, mode, gid);
 
1788
        req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode,
 
1789
                gid);
 
1790
        if (IS_ERR(req))
 
1791
                return PTR_ERR(req);
 
1792
 
 
1793
        err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
 
1794
        if (err) {
 
1795
                p9pdu_dump(1, req->rc);
 
1796
                goto error;
 
1797
        }
 
1798
        P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
 
1799
                                (unsigned long long)qid->path, qid->version);
 
1800
 
 
1801
error:
 
1802
        p9_free_req(clnt, req);
 
1803
        return err;
 
1804
 
 
1805
}
 
1806
EXPORT_SYMBOL(p9_client_mkdir_dotl);
 
1807
 
 
1808
int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
 
1809
{
 
1810
        int err;
 
1811
        struct p9_client *clnt;
 
1812
        struct p9_req_t *req;
 
1813
 
 
1814
        err = 0;
 
1815
        clnt = fid->clnt;
 
1816
        P9_DPRINTK(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
 
1817
                        "start %lld length %lld proc_id %d client_id %s\n",
 
1818
                        fid->fid, flock->type, flock->flags, flock->start,
 
1819
                        flock->length, flock->proc_id, flock->client_id);
 
1820
 
 
1821
        req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
 
1822
                                flock->flags, flock->start, flock->length,
 
1823
                                        flock->proc_id, flock->client_id);
 
1824
 
 
1825
        if (IS_ERR(req))
 
1826
                return PTR_ERR(req);
 
1827
 
 
1828
        err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
 
1829
        if (err) {
 
1830
                p9pdu_dump(1, req->rc);
 
1831
                goto error;
 
1832
        }
 
1833
        P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
 
1834
error:
 
1835
        p9_free_req(clnt, req);
 
1836
        return err;
 
1837
 
 
1838
}
 
1839
EXPORT_SYMBOL(p9_client_lock_dotl);
 
1840
 
 
1841
int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
 
1842
{
 
1843
        int err;
 
1844
        struct p9_client *clnt;
 
1845
        struct p9_req_t *req;
 
1846
 
 
1847
        err = 0;
 
1848
        clnt = fid->clnt;
 
1849
        P9_DPRINTK(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
 
1850
                "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
 
1851
                glock->start, glock->length, glock->proc_id, glock->client_id);
 
1852
 
 
1853
        req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid,  glock->type,
 
1854
                glock->start, glock->length, glock->proc_id, glock->client_id);
 
1855
 
 
1856
        if (IS_ERR(req))
 
1857
                return PTR_ERR(req);
 
1858
 
 
1859
        err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type,
 
1860
                        &glock->start, &glock->length, &glock->proc_id,
 
1861
                        &glock->client_id);
 
1862
        if (err) {
 
1863
                p9pdu_dump(1, req->rc);
 
1864
                goto error;
 
1865
        }
 
1866
        P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
 
1867
                "proc_id %d client_id %s\n", glock->type, glock->start,
 
1868
                glock->length, glock->proc_id, glock->client_id);
 
1869
error:
 
1870
        p9_free_req(clnt, req);
 
1871
        return err;
 
1872
}
 
1873
EXPORT_SYMBOL(p9_client_getlock_dotl);
 
1874
 
 
1875
int p9_client_readlink(struct p9_fid *fid, char **target)
 
1876
{
 
1877
        int err;
 
1878
        struct p9_client *clnt;
 
1879
        struct p9_req_t *req;
 
1880
 
 
1881
        err = 0;
 
1882
        clnt = fid->clnt;
 
1883
        P9_DPRINTK(P9_DEBUG_9P, ">>> TREADLINK fid %d\n", fid->fid);
 
1884
 
 
1885
        req = p9_client_rpc(clnt, P9_TREADLINK, "d", fid->fid);
 
1886
        if (IS_ERR(req))
 
1887
                return PTR_ERR(req);
 
1888
 
 
1889
        err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
 
1890
        if (err) {
 
1891
                p9pdu_dump(1, req->rc);
 
1892
                goto error;
 
1893
        }
 
1894
        P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
 
1895
error:
 
1896
        p9_free_req(clnt, req);
 
1897
        return err;
 
1898
}
 
1899
EXPORT_SYMBOL(p9_client_readlink);