^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Mostly platform independent upcall operations to Venus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * -- upcalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * -- upcall routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Linux 2.0 version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Michael Callahan <callahan@maths.ox.ac.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Redone for Linux 2.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 1997 Carnegie Mellon University
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Carnegie Mellon University encourages users of this code to contribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/vfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/coda.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "coda_psdev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "coda_linux.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "coda_cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "coda_int.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int coda_upcall(struct venus_comm *vc, int inSize, int *outSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) union inputArgs *buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void *alloc_upcall(int opcode, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) inp = kvzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!inp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) inp->ih.opcode = opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) inp->ih.pid = task_pid_nr_ns(current, &init_pid_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) inp->ih.pgid = task_pgrp_nr_ns(current, &init_pid_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) inp->ih.uid = from_kuid(&init_user_ns, current_fsuid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return (void*)inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define UPARG(op)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) do {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) inp = (union inputArgs *)alloc_upcall(op, insize); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (IS_ERR(inp)) { return PTR_ERR(inp); }\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) outp = (union outputArgs *)(inp); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) outsize = insize; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define INSIZE(tag) sizeof(struct coda_ ## tag ## _in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define OUTSIZE(tag) sizeof(struct coda_ ## tag ## _out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SIZE(tag) max_t(unsigned int, INSIZE(tag), OUTSIZE(tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* the upcalls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int venus_rootfid(struct super_block *sb, struct CodaFid *fidp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) insize = SIZE(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) UPARG(CODA_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *fidp = outp->coda_root.VFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int venus_getattr(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct coda_vattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) insize = SIZE(getattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) UPARG(CODA_GETATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) inp->coda_getattr.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *attr = outp->coda_getattr.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int venus_setattr(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct coda_vattr *vattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) insize = SIZE(setattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) UPARG(CODA_SETATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) inp->coda_setattr.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) inp->coda_setattr.attr = *vattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int venus_lookup(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const char *name, int length, int * type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct CodaFid *resfid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) offset = INSIZE(lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) insize = max_t(unsigned int, offset + length +1, OUTSIZE(lookup));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) UPARG(CODA_LOOKUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) inp->coda_lookup.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) inp->coda_lookup.name = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) inp->coda_lookup.flags = CLU_CASE_SENSITIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* send Venus a null terminated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) memcpy((char *)(inp) + offset, name, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *((char *)inp + offset + length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *resfid = outp->coda_lookup.VFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *type = outp->coda_lookup.vtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) kuid_t uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) insize = SIZE(release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) UPARG(CODA_CLOSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) inp->ih.uid = from_kuid(&init_user_ns, uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) inp->coda_close.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) inp->coda_close.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int venus_open(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int flags, struct file **fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) insize = SIZE(open_by_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) UPARG(CODA_OPEN_BY_FD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) inp->coda_open_by_fd.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) inp->coda_open_by_fd.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *fh = outp->coda_open_by_fd.fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) const char *name, int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct CodaFid *newfid, struct coda_vattr *attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) offset = INSIZE(mkdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) insize = max_t(unsigned int, offset + length + 1, OUTSIZE(mkdir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) UPARG(CODA_MKDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) inp->coda_mkdir.VFid = *dirfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) inp->coda_mkdir.attr = *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) inp->coda_mkdir.name = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Venus must get null terminated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) memcpy((char *)(inp) + offset, name, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *((char *)inp + offset + length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *attrs = outp->coda_mkdir.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) *newfid = outp->coda_mkdir.VFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int venus_rename(struct super_block *sb, struct CodaFid *old_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct CodaFid *new_fid, size_t old_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) size_t new_length, const char *old_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) const char *new_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int offset, s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) offset = INSIZE(rename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) insize = max_t(unsigned int, offset + new_length + old_length + 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) OUTSIZE(rename));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) UPARG(CODA_RENAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) inp->coda_rename.sourceFid = *old_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) inp->coda_rename.destFid = *new_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) inp->coda_rename.srcname = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* Venus must receive an null terminated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) s = ( old_length & ~0x3) +4; /* round up to word boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) memcpy((char *)(inp) + offset, old_name, old_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *((char *)inp + offset + old_length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* another null terminated string for Venus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) offset += s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) inp->coda_rename.destname = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) s = ( new_length & ~0x3) +4; /* round up to word boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) memcpy((char *)(inp) + offset, new_name, new_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *((char *)inp + offset + new_length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int venus_create(struct super_block *sb, struct CodaFid *dirfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) const char *name, int length, int excl, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct CodaFid *newfid, struct coda_vattr *attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) offset = INSIZE(create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) insize = max_t(unsigned int, offset + length + 1, OUTSIZE(create));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) UPARG(CODA_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) inp->coda_create.VFid = *dirfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) inp->coda_create.attr.va_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) inp->coda_create.excl = excl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) inp->coda_create.mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) inp->coda_create.name = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* Venus must get null terminated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) memcpy((char *)(inp) + offset, name, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *((char *)inp + offset + length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *attrs = outp->coda_create.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *newfid = outp->coda_create.VFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) const char *name, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) offset = INSIZE(rmdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) insize = max_t(unsigned int, offset + length + 1, OUTSIZE(rmdir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) UPARG(CODA_RMDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) inp->coda_rmdir.VFid = *dirfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) inp->coda_rmdir.name = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) memcpy((char *)(inp) + offset, name, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *((char *)inp + offset + length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int venus_remove(struct super_block *sb, struct CodaFid *dirfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) const char *name, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int error=0, insize, outsize, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) offset = INSIZE(remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) insize = max_t(unsigned int, offset + length + 1, OUTSIZE(remove));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) UPARG(CODA_REMOVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) inp->coda_remove.VFid = *dirfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) inp->coda_remove.name = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) memcpy((char *)(inp) + offset, name, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *((char *)inp + offset + length) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int venus_readlink(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) char *buffer, int *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int retlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) char *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) insize = max_t(unsigned int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) INSIZE(readlink), OUTSIZE(readlink)+ *length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) UPARG(CODA_READLINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) inp->coda_readlink.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) retlen = outp->coda_readlink.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (retlen >= *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) retlen = *length - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *length = retlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) result = (char *)outp + (long)outp->coda_readlink.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) memcpy(buffer, result, retlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *(buffer + retlen) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int venus_link(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct CodaFid *dirfid, const char *name, int len )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) offset = INSIZE(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) insize = max_t(unsigned int, offset + len + 1, OUTSIZE(link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) UPARG(CODA_LINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) inp->coda_link.sourceFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) inp->coda_link.destFid = *dirfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) inp->coda_link.tname = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* make sure strings are null terminated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) memcpy((char *)(inp) + offset, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *((char *)inp + offset + len) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int venus_symlink(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) const char *name, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) const char *symname, int symlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int offset, s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) offset = INSIZE(symlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) insize = max_t(unsigned int, offset + len + symlen + 8, OUTSIZE(symlink));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) UPARG(CODA_SYMLINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* inp->coda_symlink.attr = *tva; XXXXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) inp->coda_symlink.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Round up to word boundary and null terminate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) inp->coda_symlink.srcname = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) s = ( symlen & ~0x3 ) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) memcpy((char *)(inp) + offset, symname, symlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) *((char *)inp + offset + symlen) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Round up to word boundary and null terminate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) offset += s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) inp->coda_symlink.tname = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) s = (len & ~0x3) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) memcpy((char *)(inp) + offset, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) *((char *)inp + offset + len) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int venus_fsync(struct super_block *sb, struct CodaFid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) insize=SIZE(fsync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) UPARG(CODA_FSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) inp->coda_fsync.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int venus_access(struct super_block *sb, struct CodaFid *fid, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) insize = SIZE(access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) UPARG(CODA_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) inp->coda_access.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) inp->coda_access.flags = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) unsigned int cmd, struct PioctlData *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int iocsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) insize = VC_MAXMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) UPARG(CODA_IOCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* build packet for Venus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (data->vi.in_size > VC_MAXDATASIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (data->vi.out_size > VC_MAXDATASIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) inp->coda_ioctl.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* the cmd field was mutated by increasing its size field to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * reflect the path and follow args. We need to subtract that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * out before sending the command to Venus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) inp->coda_ioctl.cmd = (cmd & ~(PIOCPARM_MASK << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) iocsize = ((cmd >> 16) & PIOCPARM_MASK) - sizeof(char *) - sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) inp->coda_ioctl.cmd |= (iocsize & PIOCPARM_MASK) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* in->coda_ioctl.rwflag = flag; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) inp->coda_ioctl.len = data->vi.in_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) inp->coda_ioctl.data = (char *)(INSIZE(ioctl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* get the data out of user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (copy_from_user((char *)inp + (long)inp->coda_ioctl.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) data->vi.in, data->vi.in_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) error = coda_upcall(coda_vcp(sb), SIZE(ioctl) + data->vi.in_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) pr_warn("%s: Venus returns: %d for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) __func__, error, coda_f2s(fid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (outsize < (long)outp->coda_ioctl.data + outp->coda_ioctl.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* Copy out the OUT buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (outp->coda_ioctl.len > data->vi.out_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* Copy out the OUT buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (copy_to_user(data->vi.out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) (char *)outp + (long)outp->coda_ioctl.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) outp->coda_ioctl.len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int venus_statfs(struct dentry *dentry, struct kstatfs *sfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) insize = SIZE(statfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) UPARG(CODA_STATFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) error = coda_upcall(coda_vcp(dentry->d_sb), insize, &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) sfs->f_blocks = outp->coda_statfs.stat.f_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) sfs->f_bfree = outp->coda_statfs.stat.f_bfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) sfs->f_bavail = outp->coda_statfs.stat.f_bavail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) sfs->f_files = outp->coda_statfs.stat.f_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) sfs->f_ffree = outp->coda_statfs.stat.f_ffree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int venus_access_intent(struct super_block *sb, struct CodaFid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) bool *access_intent_supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) size_t count, loff_t ppos, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) union inputArgs *inp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) union outputArgs *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int insize, outsize, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) bool finalizer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) type == CODA_ACCESS_TYPE_READ_FINISH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) type == CODA_ACCESS_TYPE_WRITE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!*access_intent_supported && !finalizer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) insize = SIZE(access_intent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) UPARG(CODA_ACCESS_INTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) inp->coda_access_intent.VFid = *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) inp->coda_access_intent.count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) inp->coda_access_intent.pos = ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) inp->coda_access_intent.type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) error = coda_upcall(coda_vcp(sb), insize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) finalizer ? NULL : &outsize, inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * we have to free the request buffer for synchronous upcalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * or when asynchronous upcalls fail, but not when asynchronous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * upcalls succeed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!finalizer || error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) kvfree(inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Chunked access is not supported or an old Coda client */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (error == -EOPNOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) *access_intent_supported = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * coda_upcall and coda_downcall routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static void coda_block_signals(sigset_t *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_lock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *old = current->blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) sigfillset(¤t->blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) sigdelset(¤t->blocked, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) sigdelset(¤t->blocked, SIGSTOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) sigdelset(¤t->blocked, SIGINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) recalc_sigpending();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) spin_unlock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static void coda_unblock_signals(sigset_t *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) spin_lock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) current->blocked = *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) recalc_sigpending();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) spin_unlock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* Don't allow signals to interrupt the following upcalls before venus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * has seen them,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * - CODA_CLOSE or CODA_RELEASE upcall (to avoid reference count problems)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * - CODA_STORE (to avoid data loss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * - CODA_ACCESS_INTENT (to avoid reference count problems)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) #define CODA_INTERRUPTIBLE(r) (!coda_hard && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) (((r)->uc_opcode != CODA_CLOSE && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) (r)->uc_opcode != CODA_STORE && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) (r)->uc_opcode != CODA_ACCESS_INTENT && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) (r)->uc_opcode != CODA_RELEASE) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) (r)->uc_flags & CODA_REQ_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static inline void coda_waitfor_upcall(struct venus_comm *vcp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct upc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) unsigned long timeout = jiffies + coda_timeout * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) sigset_t old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) coda_block_signals(&old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) blocked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) add_wait_queue(&req->uc_sleep, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (CODA_INTERRUPTIBLE(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) set_current_state(TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* got a reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (req->uc_flags & (CODA_REQ_WRITE | CODA_REQ_ABORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (blocked && time_after(jiffies, timeout) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) CODA_INTERRUPTIBLE(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) coda_unblock_signals(&old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) blocked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) list_del(&req->uc_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) mutex_unlock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) schedule_timeout(HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mutex_lock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) coda_unblock_signals(&old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) remove_wait_queue(&req->uc_sleep, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * coda_upcall will return an error in the case of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * failed communication with Venus _or_ will peek at Venus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * reply and return Venus' error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * As venus has 2 types of errors, normal errors (positive) and internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * errors (negative), normal errors are negated, while internal errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * are all mapped to -EINTR, while showing a nice warning message. (jh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static int coda_upcall(struct venus_comm *vcp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int inSize, int *outSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) union inputArgs *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) union outputArgs *out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) union inputArgs *sig_inputArgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct upc_req *req = NULL, *sig_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) mutex_lock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (!vcp->vc_inuse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) pr_notice("Venus dead, not sending upcall\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) error = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Format the request message. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) buffer->ih.unique = ++vcp->vc_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) req->uc_data = (void *)buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) req->uc_flags = outSize ? 0 : CODA_REQ_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) req->uc_inSize = inSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) req->uc_outSize = (outSize && *outSize) ? *outSize : inSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) req->uc_opcode = buffer->ih.opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) req->uc_unique = buffer->ih.unique;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) init_waitqueue_head(&req->uc_sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* Append msg to pending queue and poke Venus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) list_add_tail(&req->uc_chain, &vcp->vc_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) wake_up_interruptible(&vcp->vc_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (req->uc_flags & CODA_REQ_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) mutex_unlock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* We can be interrupted while we wait for Venus to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * our request. If the interrupt occurs before Venus has read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * the request, we dequeue and return. If it occurs after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * read but before the reply, we dequeue, send a signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * message, and return. If it occurs after the reply we ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * it. In no case do we want to restart the syscall. If it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * was interrupted by a venus shutdown (psdev_close), return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * ENODEV. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* Go to sleep. Wake up on signals only after the timeout. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) coda_waitfor_upcall(vcp, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Op went through, interrupt or not... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (req->uc_flags & CODA_REQ_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) out = (union outputArgs *)req->uc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* here we map positive Venus errors to kernel errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) error = -out->oh.result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) *outSize = req->uc_outSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) error = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if ((req->uc_flags & CODA_REQ_ABORT) || !signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pr_warn("Unexpected interruption.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /* Interrupted before venus read it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!(req->uc_flags & CODA_REQ_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Venus saw the upcall, make sure we can send interrupt signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (!vcp->vc_inuse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) pr_info("Venus dead, not sending signal.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) sig_req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (!sig_req) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) sig_inputArgs = kvzalloc(sizeof(struct coda_in_hdr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!sig_inputArgs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) kfree(sig_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) error = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) sig_inputArgs->ih.opcode = CODA_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) sig_inputArgs->ih.unique = req->uc_unique;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) sig_req->uc_flags = CODA_REQ_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) sig_req->uc_opcode = sig_inputArgs->ih.opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sig_req->uc_unique = sig_inputArgs->ih.unique;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) sig_req->uc_data = (void *)sig_inputArgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) sig_req->uc_inSize = sizeof(struct coda_in_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) sig_req->uc_outSize = sizeof(struct coda_in_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* insert at head of queue! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) list_add(&(sig_req->uc_chain), &vcp->vc_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) wake_up_interruptible(&vcp->vc_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) mutex_unlock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) The statements below are part of the Coda opportunistic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) programming -- taken from the Mach/BSD kernel code for Coda.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) You don't get correct semantics by stating what needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) done without guaranteeing the invariants needed for it to happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) When will be have time to find out what exactly is going on? (pjb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * There are 7 cases where cache invalidations occur. The semantics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * of each is listed here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * CODA_FLUSH -- flush all entries from the name cache and the cnode cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * CODA_PURGEUSER -- flush all entries from the name cache for a specific user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * This call is a result of token expiration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * The next arise as the result of callbacks on a file or directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * CODA_ZAPFILE -- flush the cached attributes for a file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * CODA_ZAPDIR -- flush the attributes for the dir and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * force a new lookup for all the children
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) of this dir.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * The next is a result of Venus detecting an inconsistent file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * CODA_PURGEFID -- flush the attribute for the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * purge it and its children from the dcache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * The last allows Venus to replace local fids with global ones
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * during reintegration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) size_t nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct inode *inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct CodaFid *fid = NULL, *newfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * Make sure we have received enough data from the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * manager to populate the necessary fields in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) case CODA_PURGEUSER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (nbytes < sizeof(struct coda_purgeuser_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case CODA_ZAPDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (nbytes < sizeof(struct coda_zapdir_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case CODA_ZAPFILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (nbytes < sizeof(struct coda_zapfile_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case CODA_PURGEFID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (nbytes < sizeof(struct coda_purgefid_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) case CODA_REPLACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (nbytes < sizeof(struct coda_replace_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* Handle invalidation requests. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) mutex_lock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) sb = vcp->vc_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!sb || !sb->s_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) goto unlock_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) case CODA_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) coda_cache_clear_all(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) shrink_dcache_sb(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (d_really_is_positive(sb->s_root))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) coda_flag_inode(d_inode(sb->s_root), C_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case CODA_PURGEUSER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) coda_cache_clear_all(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case CODA_ZAPDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) fid = &out->coda_zapdir.CodaFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case CODA_ZAPFILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) fid = &out->coda_zapfile.CodaFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case CODA_PURGEFID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) fid = &out->coda_purgefid.CodaFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) case CODA_REPLACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) fid = &out->coda_replace.OldFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) inode = coda_fid_to_inode(fid, sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) unlock_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) mutex_unlock(&vcp->vc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) case CODA_ZAPDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) coda_flag_inode_children(inode, C_PURGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) coda_flag_inode(inode, C_VATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case CODA_ZAPFILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) coda_flag_inode(inode, C_VATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) case CODA_PURGEFID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) coda_flag_inode_children(inode, C_PURGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* catch the dentries later if some are still busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) coda_flag_inode(inode, C_PURGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) d_prune_aliases(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case CODA_REPLACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) newfid = &out->coda_replace.NewFid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) coda_replace_fid(inode, fid, newfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }