hc
2024-02-19 151fecfb72a0d602dfe79790602ef64b4e241574
kernel/fs/coda/upcall.c
....@@ -33,7 +33,7 @@
3333 #include <linux/vfs.h>
3434
3535 #include <linux/coda.h>
36
-#include <linux/coda_psdev.h>
36
+#include "coda_psdev.h"
3737 #include "coda_linux.h"
3838 #include "coda_cache.h"
3939
....@@ -46,7 +46,7 @@
4646 {
4747 union inputArgs *inp;
4848
49
- CODA_ALLOC(inp, union inputArgs *, size);
49
+ inp = kvzalloc(size, GFP_KERNEL);
5050 if (!inp)
5151 return ERR_PTR(-ENOMEM);
5252
....@@ -85,7 +85,7 @@
8585 if (!error)
8686 *fidp = outp->coda_root.VFid;
8787
88
- CODA_FREE(inp, insize);
88
+ kvfree(inp);
8989 return error;
9090 }
9191
....@@ -104,7 +104,7 @@
104104 if (!error)
105105 *attr = outp->coda_getattr.attr;
106106
107
- CODA_FREE(inp, insize);
107
+ kvfree(inp);
108108 return error;
109109 }
110110
....@@ -123,7 +123,7 @@
123123
124124 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
125125
126
- CODA_FREE(inp, insize);
126
+ kvfree(inp);
127127 return error;
128128 }
129129
....@@ -153,7 +153,7 @@
153153 *type = outp->coda_lookup.vtype;
154154 }
155155
156
- CODA_FREE(inp, insize);
156
+ kvfree(inp);
157157 return error;
158158 }
159159
....@@ -173,7 +173,7 @@
173173
174174 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
175175
176
- CODA_FREE(inp, insize);
176
+ kvfree(inp);
177177 return error;
178178 }
179179
....@@ -194,7 +194,7 @@
194194 if (!error)
195195 *fh = outp->coda_open_by_fd.fh;
196196
197
- CODA_FREE(inp, insize);
197
+ kvfree(inp);
198198 return error;
199199 }
200200
....@@ -224,7 +224,7 @@
224224 *newfid = outp->coda_mkdir.VFid;
225225 }
226226
227
- CODA_FREE(inp, insize);
227
+ kvfree(inp);
228228 return error;
229229 }
230230
....@@ -262,7 +262,7 @@
262262
263263 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
264264
265
- CODA_FREE(inp, insize);
265
+ kvfree(inp);
266266 return error;
267267 }
268268
....@@ -295,7 +295,7 @@
295295 *newfid = outp->coda_create.VFid;
296296 }
297297
298
- CODA_FREE(inp, insize);
298
+ kvfree(inp);
299299 return error;
300300 }
301301
....@@ -318,7 +318,7 @@
318318
319319 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
320320
321
- CODA_FREE(inp, insize);
321
+ kvfree(inp);
322322 return error;
323323 }
324324
....@@ -340,7 +340,7 @@
340340
341341 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
342342
343
- CODA_FREE(inp, insize);
343
+ kvfree(inp);
344344 return error;
345345 }
346346
....@@ -370,7 +370,7 @@
370370 *(buffer + retlen) = '\0';
371371 }
372372
373
- CODA_FREE(inp, insize);
373
+ kvfree(inp);
374374 return error;
375375 }
376376
....@@ -398,7 +398,7 @@
398398
399399 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
400400
401
- CODA_FREE(inp, insize);
401
+ kvfree(inp);
402402 return error;
403403 }
404404
....@@ -433,7 +433,7 @@
433433
434434 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
435435
436
- CODA_FREE(inp, insize);
436
+ kvfree(inp);
437437 return error;
438438 }
439439
....@@ -449,7 +449,7 @@
449449 inp->coda_fsync.VFid = *fid;
450450 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
451451
452
- CODA_FREE(inp, insize);
452
+ kvfree(inp);
453453 return error;
454454 }
455455
....@@ -467,7 +467,7 @@
467467
468468 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
469469
470
- CODA_FREE(inp, insize);
470
+ kvfree(inp);
471471 return error;
472472 }
473473
....@@ -543,7 +543,7 @@
543543 }
544544
545545 exit:
546
- CODA_FREE(inp, insize);
546
+ kvfree(inp);
547547 return error;
548548 }
549549
....@@ -553,7 +553,7 @@
553553 union outputArgs *outp;
554554 int insize, outsize, error;
555555
556
- insize = max_t(unsigned int, INSIZE(statfs), OUTSIZE(statfs));
556
+ insize = SIZE(statfs);
557557 UPARG(CODA_STATFS);
558558
559559 error = coda_upcall(coda_vcp(dentry->d_sb), insize, &outsize, inp);
....@@ -565,8 +565,49 @@
565565 sfs->f_ffree = outp->coda_statfs.stat.f_ffree;
566566 }
567567
568
- CODA_FREE(inp, insize);
568
+ kvfree(inp);
569569 return error;
570
+}
571
+
572
+int venus_access_intent(struct super_block *sb, struct CodaFid *fid,
573
+ bool *access_intent_supported,
574
+ size_t count, loff_t ppos, int type)
575
+{
576
+ union inputArgs *inp;
577
+ union outputArgs *outp;
578
+ int insize, outsize, error;
579
+ bool finalizer =
580
+ type == CODA_ACCESS_TYPE_READ_FINISH ||
581
+ type == CODA_ACCESS_TYPE_WRITE_FINISH;
582
+
583
+ if (!*access_intent_supported && !finalizer)
584
+ return 0;
585
+
586
+ insize = SIZE(access_intent);
587
+ UPARG(CODA_ACCESS_INTENT);
588
+
589
+ inp->coda_access_intent.VFid = *fid;
590
+ inp->coda_access_intent.count = count;
591
+ inp->coda_access_intent.pos = ppos;
592
+ inp->coda_access_intent.type = type;
593
+
594
+ error = coda_upcall(coda_vcp(sb), insize,
595
+ finalizer ? NULL : &outsize, inp);
596
+
597
+ /*
598
+ * we have to free the request buffer for synchronous upcalls
599
+ * or when asynchronous upcalls fail, but not when asynchronous
600
+ * upcalls succeed
601
+ */
602
+ if (!finalizer || error)
603
+ kvfree(inp);
604
+
605
+ /* Chunked access is not supported or an old Coda client */
606
+ if (error == -EOPNOTSUPP) {
607
+ *access_intent_supported = false;
608
+ error = 0;
609
+ }
610
+ return error;
570611 }
571612
572613 /*
....@@ -598,10 +639,12 @@
598639 * has seen them,
599640 * - CODA_CLOSE or CODA_RELEASE upcall (to avoid reference count problems)
600641 * - CODA_STORE (to avoid data loss)
642
+ * - CODA_ACCESS_INTENT (to avoid reference count problems)
601643 */
602644 #define CODA_INTERRUPTIBLE(r) (!coda_hard && \
603645 (((r)->uc_opcode != CODA_CLOSE && \
604646 (r)->uc_opcode != CODA_STORE && \
647
+ (r)->uc_opcode != CODA_ACCESS_INTENT && \
605648 (r)->uc_opcode != CODA_RELEASE) || \
606649 (r)->uc_flags & CODA_REQ_READ))
607650
....@@ -687,21 +730,25 @@
687730 goto exit;
688731 }
689732
690
- req->uc_data = (void *)buffer;
691
- req->uc_flags = 0;
692
- req->uc_inSize = inSize;
693
- req->uc_outSize = *outSize ? *outSize : inSize;
694
- req->uc_opcode = ((union inputArgs *)buffer)->ih.opcode;
695
- req->uc_unique = ++vcp->vc_seq;
696
- init_waitqueue_head(&req->uc_sleep);
733
+ buffer->ih.unique = ++vcp->vc_seq;
697734
698
- /* Fill in the common input args. */
699
- ((union inputArgs *)buffer)->ih.unique = req->uc_unique;
735
+ req->uc_data = (void *)buffer;
736
+ req->uc_flags = outSize ? 0 : CODA_REQ_ASYNC;
737
+ req->uc_inSize = inSize;
738
+ req->uc_outSize = (outSize && *outSize) ? *outSize : inSize;
739
+ req->uc_opcode = buffer->ih.opcode;
740
+ req->uc_unique = buffer->ih.unique;
741
+ init_waitqueue_head(&req->uc_sleep);
700742
701743 /* Append msg to pending queue and poke Venus. */
702744 list_add_tail(&req->uc_chain, &vcp->vc_pending);
703
-
704745 wake_up_interruptible(&vcp->vc_waitq);
746
+
747
+ if (req->uc_flags & CODA_REQ_ASYNC) {
748
+ mutex_unlock(&vcp->vc_mutex);
749
+ return 0;
750
+ }
751
+
705752 /* We can be interrupted while we wait for Venus to process
706753 * our request. If the interrupt occurs before Venus has read
707754 * the request, we dequeue and return. If it occurs after the
....@@ -743,20 +790,20 @@
743790 sig_req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
744791 if (!sig_req) goto exit;
745792
746
- CODA_ALLOC((sig_req->uc_data), char *, sizeof(struct coda_in_hdr));
747
- if (!sig_req->uc_data) {
793
+ sig_inputArgs = kvzalloc(sizeof(*sig_inputArgs), GFP_KERNEL);
794
+ if (!sig_inputArgs) {
748795 kfree(sig_req);
749796 goto exit;
750797 }
751798
752799 error = -EINTR;
753
- sig_inputArgs = (union inputArgs *)sig_req->uc_data;
754800 sig_inputArgs->ih.opcode = CODA_SIGNAL;
755801 sig_inputArgs->ih.unique = req->uc_unique;
756802
757803 sig_req->uc_flags = CODA_REQ_ASYNC;
758804 sig_req->uc_opcode = sig_inputArgs->ih.opcode;
759805 sig_req->uc_unique = sig_inputArgs->ih.unique;
806
+ sig_req->uc_data = (void *)sig_inputArgs;
760807 sig_req->uc_inSize = sizeof(struct coda_in_hdr);
761808 sig_req->uc_outSize = sizeof(struct coda_in_hdr);
762809
....@@ -804,11 +851,43 @@
804851 *
805852 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
806853
807
-int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
854
+int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out,
855
+ size_t nbytes)
808856 {
809857 struct inode *inode = NULL;
810858 struct CodaFid *fid = NULL, *newfid;
811859 struct super_block *sb;
860
+
861
+ /*
862
+ * Make sure we have received enough data from the cache
863
+ * manager to populate the necessary fields in the buffer
864
+ */
865
+ switch (opcode) {
866
+ case CODA_PURGEUSER:
867
+ if (nbytes < sizeof(struct coda_purgeuser_out))
868
+ return -EINVAL;
869
+ break;
870
+
871
+ case CODA_ZAPDIR:
872
+ if (nbytes < sizeof(struct coda_zapdir_out))
873
+ return -EINVAL;
874
+ break;
875
+
876
+ case CODA_ZAPFILE:
877
+ if (nbytes < sizeof(struct coda_zapfile_out))
878
+ return -EINVAL;
879
+ break;
880
+
881
+ case CODA_PURGEFID:
882
+ if (nbytes < sizeof(struct coda_purgefid_out))
883
+ return -EINVAL;
884
+ break;
885
+
886
+ case CODA_REPLACE:
887
+ if (nbytes < sizeof(struct coda_replace_out))
888
+ return -EINVAL;
889
+ break;
890
+ }
812891
813892 /* Handle invalidation requests. */
814893 mutex_lock(&vcp->vc_mutex);
....@@ -879,4 +958,3 @@
879958 iput(inode);
880959 return 0;
881960 }
882
-