The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/intermezzo/upcall.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
    2  * vim:expandtab:shiftwidth=8:tabstop=8:
    3  *
    4  * Copyright (C) 2001, 2002 Cluster File Systems, Inc. <braam@clusterfs.com>
    5  * Copyright (C) 2001 Tacit Networks, Inc. <phil@off.net>
    6  *
    7  *   This file is part of InterMezzo, http://www.inter-mezzo.org.
    8  *
    9  *   InterMezzo is free software; you can redistribute it and/or
   10  *   modify it under the terms of version 2 of the GNU General Public
   11  *   License as published by the Free Software Foundation.
   12  *
   13  *   InterMezzo is distributed in the hope that it will be useful,
   14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16  *   GNU General Public License for more details.
   17  *
   18  *   You should have received a copy of the GNU General Public License
   19  *   along with InterMezzo; if not, write to the Free Software
   20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   21  *
   22  * Mostly platform independent upcall operations to a cache manager:
   23  *  -- upcalls
   24  *  -- upcall routines
   25  *
   26  */
   27 
   28 #include <asm/system.h>
   29 #include <asm/segment.h>
   30 #include <asm/signal.h>
   31 #include <linux/signal.h>
   32 
   33 #include <linux/types.h>
   34 #include <linux/kernel.h>
   35 #include <linux/mm.h>
   36 #include <linux/vmalloc.h>
   37 #include <linux/slab.h>
   38 #include <linux/sched.h>
   39 #include <linux/fs.h>
   40 #include <linux/stat.h>
   41 #include <linux/errno.h>
   42 #include <linux/locks.h>
   43 #include <linux/string.h>
   44 #include <asm/uaccess.h>
   45 #include <linux/vmalloc.h>
   46 #include <asm/segment.h>
   47 
   48 #include <linux/intermezzo_lib.h>
   49 #include <linux/intermezzo_fs.h>
   50 #include <linux/intermezzo_psdev.h>
   51 
   52 #include <linux/intermezzo_idl.h>
   53 
   54 /*
   55   At present:
   56   -- Asynchronous calls:
   57    - kml:            give a "more" kml indication to userland
   58    - kml_truncate:   initiate KML truncation
   59    - release_permit: kernel is done with permit
   60   -- Synchronous
   61    - open:           fetch file
   62    - permit:         get a permit
   63 
   64   Errors returned by user level code are positive
   65 
   66  */
   67 
   68 static struct izo_upcall_hdr *upc_pack(__u32 opcode, int pathlen, char *path,
   69                                        char *fsetname, int reclen, char *rec,
   70                                        int *size)
   71 {
   72         struct izo_upcall_hdr *hdr;
   73         char *ptr;
   74         ENTRY;
   75 
   76         *size = sizeof(struct izo_upcall_hdr);
   77         if ( fsetname ) {
   78                 *size += round_strlen(fsetname);
   79         }
   80         if ( path ) { 
   81                 *size += round_strlen(path);
   82         }
   83         if ( rec ) { 
   84                 *size += size_round(reclen);
   85         }
   86         PRESTO_ALLOC(hdr, *size);
   87         if (!hdr) { 
   88                 CERROR("intermezzo upcall: out of memory (opc %d)\n", opcode);
   89                 EXIT;
   90                 return NULL;
   91         }
   92         memset(hdr, 0, *size);
   93 
   94         ptr = (char *)hdr + sizeof(*hdr);
   95 
   96         /* XXX do we need fsuid ? */
   97         hdr->u_len = *size;
   98         hdr->u_version = IZO_UPC_VERSION;
   99         hdr->u_opc = opcode;
  100         hdr->u_pid = current->pid;
  101         hdr->u_uid = current->fsuid;
  102 
  103         if (path) { 
  104                 /*XXX Robert: please review what len to pass in for 
  105                   NUL terminated strings */
  106                 hdr->u_pathlen = strlen(path);
  107                 LOGL0(path, hdr->u_pathlen, ptr);
  108         }
  109         if (fsetname) { 
  110                 hdr->u_fsetlen = strlen(fsetname);
  111                 LOGL0(fsetname, strlen(fsetname), ptr);
  112         }
  113         if (rec) { 
  114                 hdr->u_reclen = reclen;
  115                 LOGL(rec, reclen, ptr);
  116         }
  117         
  118         EXIT;
  119         return hdr;
  120 }
  121 
  122 /* the upcalls */
  123 int izo_upc_kml(int minor, __u64 offset, __u32 first_recno, __u64 length, __u32 last_recno, char *fsetname)
  124 {
  125         int size;
  126         int error;
  127         struct izo_upcall_hdr *hdr;
  128 
  129         ENTRY;
  130         if (!presto_lento_up(minor)) {
  131                 EXIT;
  132                 return 0;
  133         }
  134 
  135         hdr = upc_pack(IZO_UPC_KML, 0, NULL, fsetname, 0, NULL, &size);
  136         if (!hdr || IS_ERR(hdr)) {
  137                 EXIT;
  138                 return -PTR_ERR(hdr);
  139         }
  140 
  141         hdr->u_offset = offset;
  142         hdr->u_first_recno = first_recno;
  143         hdr->u_length = length;
  144         hdr->u_last_recno = last_recno;
  145 
  146         CDEBUG(D_UPCALL, "KML: fileset %s, offset %Lu, length %Lu, "
  147                "first %u, last %d; minor %d\n",
  148                fsetname, hdr->u_offset, hdr->u_length, hdr->u_first_recno,
  149                hdr->u_last_recno, minor);
  150 
  151         error = izo_upc_upcall(minor, &size, hdr, ASYNCHRONOUS);
  152 
  153         EXIT;
  154         return -error;
  155 }
  156 
  157 int izo_upc_kml_truncate(int minor, __u64 length, __u32 last_recno, char *fsetname)
  158 {
  159         int size;
  160         int error;
  161         struct izo_upcall_hdr *hdr;
  162 
  163         ENTRY;
  164         if (!presto_lento_up(minor)) {
  165                 EXIT;
  166                 return 0;
  167         }
  168 
  169         hdr = upc_pack(IZO_UPC_KML_TRUNC, 0, NULL, fsetname, 0, NULL, &size);
  170         if (!hdr || IS_ERR(hdr)) {
  171                 EXIT;
  172                 return -PTR_ERR(hdr);
  173         }
  174 
  175         hdr->u_length = length;
  176         hdr->u_last_recno = last_recno;
  177 
  178         CDEBUG(D_UPCALL, "KML TRUNCATE: fileset %s, length %Lu, "
  179                "last recno %d, minor %d\n",
  180                fsetname, hdr->u_length, hdr->u_last_recno, minor);
  181 
  182         error = izo_upc_upcall(minor, &size, hdr, ASYNCHRONOUS);
  183 
  184         EXIT;
  185         return error;
  186 }
  187 
  188 int izo_upc_open(int minor, __u32 pathlen, char *path, char *fsetname, struct lento_vfs_context *info)
  189 {
  190         int size;
  191         int error;
  192         struct izo_upcall_hdr *hdr;
  193         ENTRY;
  194 
  195         if (!presto_lento_up(minor)) {
  196                 EXIT;
  197                 return -EIO;
  198         }
  199 
  200         hdr = upc_pack(IZO_UPC_OPEN, pathlen, path, fsetname, 
  201                        sizeof(*info), (char*)info, &size);
  202         if (!hdr || IS_ERR(hdr)) {
  203                 EXIT;
  204                 return -PTR_ERR(hdr);
  205         }
  206 
  207         CDEBUG(D_UPCALL, "path %s\n", path);
  208 
  209         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  210         if (error)
  211                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  212 
  213         EXIT;
  214         return -error;
  215 }
  216 
  217 int izo_upc_get_fileid(int minor, __u32 reclen, char *rec, 
  218                        __u32 pathlen, char *path, char *fsetname)
  219 {
  220         int size;
  221         int error;
  222         struct izo_upcall_hdr *hdr;
  223         ENTRY;
  224 
  225         if (!presto_lento_up(minor)) {
  226                 EXIT;
  227                 return -EIO;
  228         }
  229 
  230         hdr = upc_pack(IZO_UPC_GET_FILEID, pathlen, path, fsetname, reclen, rec, &size);
  231         if (!hdr || IS_ERR(hdr)) {
  232                 EXIT;
  233                 return -PTR_ERR(hdr);
  234         }
  235 
  236         CDEBUG(D_UPCALL, "path %s\n", path);
  237 
  238         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  239         if (error)
  240                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  241 
  242         EXIT;
  243         return -error;
  244 }
  245 
  246 int izo_upc_backfetch(int minor, char *path, char *fsetname, struct lento_vfs_context *info)
  247 {
  248         int size;
  249         int error;
  250         struct izo_upcall_hdr *hdr;
  251         ENTRY;
  252 
  253         if (!presto_lento_up(minor)) {
  254                 EXIT;
  255                 return -EIO;
  256         }
  257 
  258         hdr = upc_pack(IZO_UPC_BACKFETCH, strlen(path), path, fsetname, 
  259                        sizeof(*info), (char *)info, &size);
  260         if (!hdr || IS_ERR(hdr)) {
  261                 EXIT;
  262                 return -PTR_ERR(hdr);
  263         }
  264 
  265         /* This is currently synchronous, kml_reint_record blocks */
  266         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  267         if (error)
  268                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  269 
  270         EXIT;
  271         return -error;
  272 }
  273 
  274 int izo_upc_permit(int minor, struct dentry *dentry, __u32 pathlen, char *path,
  275                    char *fsetname)
  276 {
  277         int size;
  278         int error;
  279         struct izo_upcall_hdr *hdr;
  280 
  281         ENTRY;
  282 
  283         hdr = upc_pack(IZO_UPC_PERMIT, pathlen, path, fsetname, 0, NULL, &size);
  284         if (!hdr || IS_ERR(hdr)) {
  285                 EXIT;
  286                 return -PTR_ERR(hdr);
  287         }
  288 
  289         CDEBUG(D_UPCALL, "Permit minor %d path %s\n", minor, path);
  290 
  291         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  292 
  293         if (error == -EROFS) {
  294                 int err;
  295                 CERROR("InterMezzo: ERROR - requested permit for read-only "
  296                        "fileset.\n   Setting \"%s\" read-only!\n", path);
  297                 err = izo_mark_cache(dentry, 0xFFFFFFFF, CACHE_CLIENT_RO, NULL);
  298                 if (err)
  299                         CERROR("InterMezzo ERROR: mark_cache %d\n", err);
  300         } else if (error) {
  301                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  302         }
  303 
  304         EXIT;
  305         return error;
  306 }
  307 
  308 /* This is a ping-pong upcall handled on the server when a client (uuid)
  309  * requests the permit for itself. */
  310 int izo_upc_revoke_permit(int minor, char *fsetname, __u8 uuid[16])
  311 {
  312         int size;
  313         int error;
  314         struct izo_upcall_hdr *hdr;
  315 
  316         ENTRY;
  317 
  318         hdr = upc_pack(IZO_UPC_REVOKE_PERMIT, 0, NULL, fsetname, 0, NULL, &size);
  319         if (!hdr || IS_ERR(hdr)) {
  320                 EXIT;
  321                 return -PTR_ERR(hdr);
  322         }
  323 
  324         memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
  325 
  326         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  327 
  328         if (error)
  329                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  330 
  331         EXIT;
  332         return -error;
  333 }
  334 
  335 int izo_upc_go_fetch_kml(int minor, char *fsetname, __u8 uuid[16],
  336                          __u64 kmlsize)
  337 {
  338         int size;
  339         int error;
  340         struct izo_upcall_hdr *hdr;
  341         ENTRY;
  342 
  343         if (!presto_lento_up(minor)) {
  344                 EXIT;
  345                 return -EIO;
  346         }
  347 
  348         hdr = upc_pack(IZO_UPC_GO_FETCH_KML, 0, NULL, fsetname, 0, NULL, &size);
  349         if (!hdr || IS_ERR(hdr)) {
  350                 EXIT;
  351                 return -PTR_ERR(hdr);
  352         }
  353 
  354         hdr->u_offset = kmlsize;
  355         memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
  356 
  357         error = izo_upc_upcall(minor, &size, hdr, ASYNCHRONOUS);
  358         if (error)
  359                 CERROR("%s: error %d\n", __FUNCTION__, error);
  360 
  361         EXIT;
  362         return -error;
  363 }
  364 
  365 int izo_upc_connect(int minor, __u64 ip_address, __u64 port, __u8 uuid[16],
  366                     int client_flag)
  367 {
  368         int size;
  369         int error;
  370         struct izo_upcall_hdr *hdr;
  371         ENTRY;
  372 
  373         if (!presto_lento_up(minor)) {
  374                 EXIT;
  375                 return -EIO;
  376         }
  377 
  378         hdr = upc_pack(IZO_UPC_CONNECT, 0, NULL, NULL, 0, NULL, &size);
  379         if (!hdr || IS_ERR(hdr)) {
  380                 EXIT;
  381                 return -PTR_ERR(hdr);
  382         }
  383 
  384         hdr->u_offset = ip_address;
  385         hdr->u_length = port;
  386         memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
  387         hdr->u_first_recno = client_flag;
  388 
  389         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  390         if (error) {
  391                 CERROR("%s: error %d\n", __FUNCTION__, error);
  392         }
  393 
  394         EXIT;
  395         return -error;
  396 }
  397 
  398 int izo_upc_set_kmlsize(int minor, char *fsetname, __u8 uuid[16], __u64 kmlsize)
  399 {
  400         int size;
  401         int error;
  402         struct izo_upcall_hdr *hdr;
  403         ENTRY;
  404 
  405         if (!presto_lento_up(minor)) {
  406                 EXIT;
  407                 return -EIO;
  408         }
  409 
  410         hdr = upc_pack(IZO_UPC_SET_KMLSIZE, 0, NULL, fsetname, 0, NULL, &size);
  411         if (!hdr || IS_ERR(hdr)) {
  412                 EXIT;
  413                 return -PTR_ERR(hdr);
  414         }
  415 
  416         memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
  417         hdr->u_length = kmlsize;
  418 
  419         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  420         if (error)
  421                 CERROR("%s: error %d\n", __FUNCTION__, error);
  422 
  423         EXIT;
  424         return -error;
  425 }
  426 
  427 int izo_upc_repstatus(int minor,  char * fsetname, struct izo_rcvd_rec *lr_server)
  428 {
  429         int size;
  430         int error;
  431         struct izo_upcall_hdr *hdr;
  432         ENTRY;
  433 
  434         if (!presto_lento_up(minor)) {
  435                 EXIT;
  436                 return -EIO;
  437         }
  438 
  439         hdr = upc_pack(IZO_UPC_REPSTATUS, 0, NULL, fsetname, 
  440                        sizeof(*lr_server), (char*)lr_server, 
  441                        &size);
  442         if (!hdr || IS_ERR(hdr)) {
  443                 EXIT;
  444                 return -PTR_ERR(hdr);
  445         }
  446 
  447         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  448         if (error)
  449                 CERROR("%s: error %d\n", __FUNCTION__, error);
  450 
  451         EXIT;
  452         return -error;
  453 }
  454 
  455 
  456 #if 0
  457 int izo_upc_client_make_branch(int minor, char *fsetname, char *tagname,
  458                                char *branchname)
  459 {
  460         int size, error;
  461         struct izo_upcall_hdr *hdr;
  462         int pathlen;
  463         char *path;
  464         ENTRY;
  465 
  466         hdr = upc_pack(IZO_UPC_CLIENT_MAKE_BRANCH, strlen(tagname), tagname,
  467                        fsetname, strlen(branchname) + 1, branchname, &size);
  468         if (!hdr || IS_ERR(hdr)) {
  469                 error = -PTR_ERR(hdr);
  470                 goto error;
  471         }
  472 
  473         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  474         if (error)
  475                 CERROR("InterMezzo: error %d\n", error);
  476 
  477  error:
  478         PRESTO_FREE(path, pathlen);
  479         EXIT;
  480         return error;
  481 }
  482 #endif
  483 
  484 int izo_upc_server_make_branch(int minor, char *fsetname)
  485 {
  486         int size, error;
  487         struct izo_upcall_hdr *hdr;
  488         ENTRY;
  489 
  490         hdr = upc_pack(IZO_UPC_SERVER_MAKE_BRANCH, 0, NULL, fsetname, 0, NULL, &size);
  491         if (!hdr || IS_ERR(hdr)) {
  492                 error = -PTR_ERR(hdr);
  493                 goto error;
  494         }
  495 
  496         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  497         if (error)
  498                 CERROR("InterMezzo: error %d\n", error);
  499 
  500  error:
  501         EXIT;
  502         return -error;
  503 }
  504 
  505 int izo_upc_branch_undo(int minor, char *fsetname, char *branchname)
  506 {
  507         int size;
  508         int error;
  509         struct izo_upcall_hdr *hdr;
  510         ENTRY;
  511 
  512         if (!presto_lento_up(minor)) {
  513                 EXIT;
  514                 return -EIO;
  515         }
  516 
  517         hdr = upc_pack(IZO_UPC_BRANCH_UNDO, strlen(branchname), branchname,
  518                        fsetname, 0, NULL, &size);
  519         if (!hdr || IS_ERR(hdr)) {
  520                 EXIT;
  521                 return -PTR_ERR(hdr);
  522         }
  523 
  524         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  525         if (error)
  526                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  527 
  528         EXIT;
  529         return -error;
  530 }
  531 
  532 int izo_upc_branch_redo(int minor, char *fsetname, char *branchname)
  533 {
  534         int size;
  535         int error;
  536         struct izo_upcall_hdr *hdr;
  537         ENTRY;
  538 
  539         if (!presto_lento_up(minor)) {
  540                 EXIT;
  541                 return -EIO;
  542         }
  543 
  544         hdr = upc_pack(IZO_UPC_BRANCH_REDO, strlen(branchname) + 1, branchname,
  545                        fsetname, 0, NULL, &size);
  546         if (!hdr || IS_ERR(hdr)) {
  547                 EXIT;
  548                 return -PTR_ERR(hdr);
  549         }
  550 
  551         error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
  552         if (error)
  553                 CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
  554 
  555         EXIT;
  556         return -error;
  557 }

Cache object: 059367980610254eee8b344b5eba4165


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.