16
16
#include <linux/ip.h>
17
17
#include "internal.h"
18
18
#include "afs_cm.h"
19
+ #include "protocol_yfs.h"
19
20
20
21
static int afs_deliver_cb_init_call_back_state (struct afs_call * );
21
22
static int afs_deliver_cb_init_call_back_state3 (struct afs_call * );
@@ -30,6 +31,8 @@ static void SRXAFSCB_Probe(struct work_struct *);
30
31
static void SRXAFSCB_ProbeUuid (struct work_struct * );
31
32
static void SRXAFSCB_TellMeAboutYourself (struct work_struct * );
32
33
34
+ static int afs_deliver_yfs_cb_callback (struct afs_call * );
35
+
33
36
#define CM_NAME (name ) \
34
37
const char afs_SRXCB##name##_name[] __tracepoint_string = \
35
38
"CB." #name
@@ -100,13 +103,24 @@ static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
100
103
.work = SRXAFSCB_TellMeAboutYourself ,
101
104
};
102
105
106
+ /*
107
+ * YFS CB.CallBack operation type
108
+ */
109
+ static CM_NAME (YFS_CallBack );
110
+ static const struct afs_call_type afs_SRXYFSCB_CallBack = {
111
+ .name = afs_SRXCBYFS_CallBack_name ,
112
+ .deliver = afs_deliver_yfs_cb_callback ,
113
+ .destructor = afs_cm_destructor ,
114
+ .work = SRXAFSCB_CallBack ,
115
+ };
116
+
103
117
/*
104
118
* route an incoming cache manager call
105
119
* - return T if supported, F if not
106
120
*/
107
121
bool afs_cm_incoming_call (struct afs_call * call )
108
122
{
109
- _enter ("{CB.OP %u}" , call -> operation_ID );
123
+ _enter ("{%u, CB.OP %u}" , call -> service_id , call -> operation_ID );
110
124
111
125
switch (call -> operation_ID ) {
112
126
case CBCallBack :
@@ -127,6 +141,11 @@ bool afs_cm_incoming_call(struct afs_call *call)
127
141
case CBTellMeAboutYourself :
128
142
call -> type = & afs_SRXCBTellMeAboutYourself ;
129
143
return true;
144
+ case YFSCBCallBack :
145
+ if (call -> service_id != YFS_CM_SERVICE )
146
+ return false;
147
+ call -> type = & afs_SRXYFSCB_CallBack ;
148
+ return true;
130
149
default :
131
150
return false;
132
151
}
@@ -570,3 +589,85 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
570
589
571
590
return afs_queue_call_work (call );
572
591
}
592
+
593
+ /*
594
+ * deliver request data to a YFS CB.CallBack call
595
+ */
596
+ static int afs_deliver_yfs_cb_callback (struct afs_call * call )
597
+ {
598
+ struct afs_callback_break * cb ;
599
+ struct sockaddr_rxrpc srx ;
600
+ struct yfs_xdr_YFSFid * bp ;
601
+ size_t size ;
602
+ int ret , loop ;
603
+
604
+ _enter ("{%u}" , call -> unmarshall );
605
+
606
+ switch (call -> unmarshall ) {
607
+ case 0 :
608
+ afs_extract_to_tmp (call );
609
+ call -> unmarshall ++ ;
610
+
611
+ /* extract the FID array and its count in two steps */
612
+ case 1 :
613
+ _debug ("extract FID count" );
614
+ ret = afs_extract_data (call , true);
615
+ if (ret < 0 )
616
+ return ret ;
617
+
618
+ call -> count = ntohl (call -> tmp );
619
+ _debug ("FID count: %u" , call -> count );
620
+ if (call -> count > YFSCBMAX )
621
+ return afs_protocol_error (call , - EBADMSG ,
622
+ afs_eproto_cb_fid_count );
623
+
624
+ size = array_size (call -> count , sizeof (struct yfs_xdr_YFSFid ));
625
+ call -> buffer = kmalloc (size , GFP_KERNEL );
626
+ if (!call -> buffer )
627
+ return - ENOMEM ;
628
+ afs_extract_to_buf (call , size );
629
+ call -> unmarshall ++ ;
630
+
631
+ case 2 :
632
+ _debug ("extract FID array" );
633
+ ret = afs_extract_data (call , false);
634
+ if (ret < 0 )
635
+ return ret ;
636
+
637
+ _debug ("unmarshall FID array" );
638
+ call -> request = kcalloc (call -> count ,
639
+ sizeof (struct afs_callback_break ),
640
+ GFP_KERNEL );
641
+ if (!call -> request )
642
+ return - ENOMEM ;
643
+
644
+ cb = call -> request ;
645
+ bp = call -> buffer ;
646
+ for (loop = call -> count ; loop > 0 ; loop -- , cb ++ ) {
647
+ cb -> fid .vid = xdr_to_u64 (bp -> volume );
648
+ cb -> fid .vnode = xdr_to_u64 (bp -> vnode .lo );
649
+ cb -> fid .vnode_hi = ntohl (bp -> vnode .hi );
650
+ cb -> fid .unique = ntohl (bp -> vnode .unique );
651
+ bp ++ ;
652
+ }
653
+
654
+ afs_extract_to_tmp (call );
655
+ call -> unmarshall ++ ;
656
+
657
+ case 3 :
658
+ break ;
659
+ }
660
+
661
+ if (!afs_check_call_state (call , AFS_CALL_SV_REPLYING ))
662
+ return afs_io_error (call , afs_io_error_cm_reply );
663
+
664
+ /* We'll need the file server record as that tells us which set of
665
+ * vnodes to operate upon.
666
+ */
667
+ rxrpc_kernel_get_peer (call -> net -> socket , call -> rxcall , & srx );
668
+ call -> cm_server = afs_find_server (call -> net , & srx );
669
+ if (!call -> cm_server )
670
+ trace_afs_cm_no_server (call , & srx );
671
+
672
+ return afs_queue_call_work (call );
673
+ }
0 commit comments