patch-2.4.20 linux-2.4.20/fs/intermezzo/upcall.c
Next file: linux-2.4.20/fs/intermezzo/vfs.c
Previous file: linux-2.4.20/fs/intermezzo/sysctl.c
Back to the patch index
Back to the overall index
- Lines: 694
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/fs/intermezzo/upcall.c
- Orig date:
Sun Nov 11 10:20:21 2001
diff -urN linux-2.4.19/fs/intermezzo/upcall.c linux-2.4.20/fs/intermezzo/upcall.c
@@ -1,22 +1,28 @@
-/*
- * Mostly platform independent upcall operations to Venus:
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001, 2002 Cluster File Systems, Inc. <braam@clusterfs.com>
+ * Copyright (C) 2001 Tacit Networks, Inc. <phil@off.net>
+ *
+ * This file is part of InterMezzo, http://www.inter-mezzo.org.
+ *
+ * InterMezzo is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * InterMezzo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with InterMezzo; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Mostly platform independent upcall operations to a cache manager:
* -- upcalls
* -- upcall routines
*
- * Linux 2.0 version
- * Copyright (C) 1996 Peter J. Braam <braam@cs.cmu.edu>,
- * Michael Callahan <callahan@maths.ox.ac.uk>
- *
- * Redone for Linux 2.1
- * Copyright (C) 1997 Carnegie Mellon University
- *
- * Carnegie Mellon University encourages users of this code to contribute
- * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
- *
- * Much cleaned up for InterMezzo
- * Copyright (C) 1998 Peter J. Braam <braam@cs.cmu.edu>,
- * Copyright (C) 1999 Carnegie Mellon University
- *
*/
#include <asm/system.h>
@@ -39,210 +45,513 @@
#include <linux/vmalloc.h>
#include <asm/segment.h>
+#include <linux/intermezzo_lib.h>
#include <linux/intermezzo_fs.h>
-#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
+#include <linux/intermezzo_idl.h>
+
/*
- At present: four upcalls
- - opendir: fetch a directory (synchronous & asynchronous)
- - open: fetch file (synchronous)
- - journal: send a journal page (asynchronous)
- - permit: get a permit (synchronous)
+ At present:
+ -- Asynchronous calls:
+ - kml: give a "more" kml indication to userland
+ - kml_truncate: initiate KML truncation
+ - release_permit: kernel is done with permit
+ -- Synchronous
+ - open: fetch file
+ - permit: get a permit
- Errors returned here are positive.
+ Errors returned by user level code are positive
*/
+static struct izo_upcall_hdr *upc_pack(__u32 opcode, int pathlen, char *path,
+ char *fsetname, int reclen, char *rec,
+ int *size)
+{
+ struct izo_upcall_hdr *hdr;
+ char *ptr;
+ ENTRY;
-#define INSIZE(tag) sizeof(struct lento_ ## tag ## _in)
-#define OUTSIZE(tag) sizeof(struct lento_ ## tag ## _out)
-#define SIZE(tag) ( (INSIZE(tag)>OUTSIZE(tag)) ? INSIZE(tag) : OUTSIZE(tag) )
-
-#define UPARG(op)\
-do {\
- PRESTO_ALLOC(inp, union up_args *, insize);\
- if ( !inp ) { return -ENOMEM; }\
- outp = (union down_args *) (inp);\
- inp->uh.opcode = (op);\
- inp->uh.pid = current->pid;\
- inp->uh.uid = current->fsuid;\
- outsize = insize;\
-} while (0)
-
-#define BUFF_ALLOC(buffer) \
- PRESTO_ALLOC(buffer, char *, PAGE_SIZE); \
- if ( !buffer ) { \
- printk("PRESTO: out of memory!\n"); \
- return -ENOMEM; \
+ *size = sizeof(struct izo_upcall_hdr);
+ if ( fsetname ) {
+ *size += round_strlen(fsetname);
+ }
+ if ( path ) {
+ *size += round_strlen(path);
}
+ if ( rec ) {
+ *size += size_round(reclen);
+ }
+ PRESTO_ALLOC(hdr, *size);
+ if (!hdr) {
+ CERROR("intermezzo upcall: out of memory (opc %d)\n", opcode);
+ EXIT;
+ return NULL;
+ }
+ memset(hdr, 0, *size);
+
+ ptr = (char *)hdr + sizeof(*hdr);
+
+ /* XXX do we need fsuid ? */
+ hdr->u_len = *size;
+ hdr->u_version = IZO_UPC_VERSION;
+ hdr->u_opc = opcode;
+ hdr->u_pid = current->pid;
+ hdr->u_uid = current->fsuid;
+
+ if (path) {
+ /*XXX Robert: please review what len to pass in for
+ NUL terminated strings */
+ hdr->u_pathlen = strlen(path);
+ LOGL0(path, hdr->u_pathlen, ptr);
+ }
+ if (fsetname) {
+ hdr->u_fsetlen = strlen(fsetname);
+ LOGL0(fsetname, strlen(fsetname), ptr);
+ }
+ if (rec) {
+ hdr->u_reclen = reclen;
+ LOGL(rec, reclen, ptr);
+ }
+
+ EXIT;
+ return hdr;
+}
/* the upcalls */
-int lento_kml(int minor, unsigned int offset, unsigned int first_recno,
- unsigned int length, unsigned int last_recno, int namelen,
- char *fsetname)
-{
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
+int izo_upc_kml(int minor, __u64 offset, __u32 first_recno, __u64 length, __u32 last_recno, char *fsetname)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+
ENTRY;
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return 0;
+ }
+
+ hdr = upc_pack(IZO_UPC_KML, 0, NULL, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ hdr->u_offset = offset;
+ hdr->u_first_recno = first_recno;
+ hdr->u_length = length;
+ hdr->u_last_recno = last_recno;
+
+ CDEBUG(D_UPCALL, "KML: fileset %s, offset %Lu, length %Lu, "
+ "first %u, last %d; minor %d\n",
+ fsetname, hdr->u_offset, hdr->u_length, hdr->u_first_recno,
+ hdr->u_last_recno, minor);
+
+ error = izo_upc_upcall(minor, &size, hdr, ASYNCHRONOUS);
+
+ EXIT;
+ return -error;
+}
+
+int izo_upc_kml_truncate(int minor, __u64 length, __u32 last_recno, char *fsetname)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
if (!presto_lento_up(minor)) {
EXIT;
return 0;
}
- insize = SIZE(kml) + namelen + 1;
- UPARG(LENTO_KML);
- inp->lento_kml.namelen = namelen;
- memcpy(inp->lento_kml.fsetname, fsetname, namelen);
- inp->lento_kml.fsetname[namelen] = '\0';
- inp->lento_kml.offset = offset;
- inp->lento_kml.first_recno = first_recno;
- inp->lento_kml.length = length;
- inp->lento_kml.last_recno = last_recno;
-
- CDEBUG(D_UPCALL, "KML: fileset %s, offset %d, length %d, "
- "first %d, last %d; minor %d\n",
- inp->lento_kml.fsetname,
- inp->lento_kml.offset,
- inp->lento_kml.length,
- inp->lento_kml.first_recno,
- inp->lento_kml.last_recno, minor);
+ hdr = upc_pack(IZO_UPC_KML_TRUNC, 0, NULL, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ hdr->u_length = length;
+ hdr->u_last_recno = last_recno;
+
+ CDEBUG(D_UPCALL, "KML TRUNCATE: fileset %s, length %Lu, "
+ "last recno %d, minor %d\n",
+ fsetname, hdr->u_length, hdr->u_last_recno, minor);
- error = lento_upcall(minor, insize, &outsize, inp,
- ASYNCHRONOUS, NULL);
+ error = izo_upc_upcall(minor, &size, hdr, ASYNCHRONOUS);
EXIT;
return error;
}
-int lento_release_permit( int minor, int mycookie )
+int izo_upc_open(int minor, __u32 pathlen, char *path, char *fsetname, struct lento_vfs_context *info)
{
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
ENTRY;
if (!presto_lento_up(minor)) {
EXIT;
- return 0;
+ return -EIO;
}
- insize= SIZE(response_cookie);
- UPARG(LENTO_COOKIE);
- inp->lento_response_cookie.cookie= mycookie;
+ hdr = upc_pack(IZO_UPC_OPEN, pathlen, path, fsetname,
+ sizeof(*info), (char*)info, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
- CDEBUG(D_UPCALL, "cookie %d\n", mycookie);
+ CDEBUG(D_UPCALL, "path %s\n", path);
- error = lento_upcall(minor, insize, &outsize, inp,
- ASYNCHRONOUS, NULL);
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
EXIT;
- return error;
+ return -error;
}
-int lento_opendir(int minor, int pathlen, char *path, int async)
+int izo_upc_get_fileid(int minor, __u32 reclen, char *rec,
+ __u32 pathlen, char *path, char *fsetname)
{
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
ENTRY;
- insize = SIZE(opendir) + pathlen + 1;
- UPARG(LENTO_OPENDIR);
- inp->lento_opendir.async = async;
- inp->lento_opendir.pathlen = pathlen;
- memcpy(inp->lento_opendir.path, path, pathlen);
- inp->lento_opendir.path[pathlen] = '\0';
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
+
+ hdr = upc_pack(IZO_UPC_GET_FILEID, pathlen, path, fsetname, reclen, rec, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
- CDEBUG(D_UPCALL, "path %s\n", inp->lento_opendir.path);
+ CDEBUG(D_UPCALL, "path %s\n", path);
- if (async) {
- error = lento_upcall(minor, insize, &outsize, inp,
- ASYNCHRONOUS, NULL);
- return 0;
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
+
+ EXIT;
+ return -error;
+}
+
+int izo_upc_backfetch(int minor, char *path, char *fsetname, struct lento_vfs_context *info)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
+
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
}
- error = lento_upcall(minor, insize, &outsize, inp,
- SYNCHRONOUS, NULL);
- if (error && error != EISFSETROOT) {
- printk("lento_opendir: error %d\n", error);
+ hdr = upc_pack(IZO_UPC_BACKFETCH, strlen(path), path, fsetname,
+ sizeof(*info), (char *)info, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
}
+ /* This is currently synchronous, kml_reint_record blocks */
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
+
EXIT;
- return error;
+ return -error;
}
-int lento_open(int minor, int pathlen, char *path)
+int izo_upc_permit(int minor, struct dentry *dentry, __u32 pathlen, char *path,
+ char *fsetname)
{
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
-
- ENTRY;
- insize = SIZE(open) + pathlen + 1;
- UPARG(LENTO_OPEN);
- inp->lento_open.pathlen = pathlen;
- memcpy(inp->lento_open.path, path, pathlen);
- inp->lento_open.path[pathlen] = '\0';
-
- CDEBUG(D_UPCALL, "path %s\n", inp->lento_open.path);
-
- error = lento_upcall(minor, insize, &outsize, inp,
- SYNCHRONOUS, NULL);
- if (error) {
- printk("lento_open: error %d\n", error);
- }
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+
+ ENTRY;
+
+ hdr = upc_pack(IZO_UPC_PERMIT, pathlen, path, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ CDEBUG(D_UPCALL, "Permit minor %d path %s\n", minor, path);
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+
+ if (error == -EROFS) {
+ int err;
+ CERROR("InterMezzo: ERROR - requested permit for read-only "
+ "fileset.\n Setting \"%s\" read-only!\n", path);
+ err = izo_mark_cache(dentry, 0xFFFFFFFF, CACHE_CLIENT_RO, NULL);
+ if (err)
+ CERROR("InterMezzo ERROR: mark_cache %d\n", err);
+ } else if (error) {
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
+ }
EXIT;
return error;
}
+/* This is a ping-pong upcall handled on the server when a client (uuid)
+ * requests the permit for itself. */
+int izo_upc_revoke_permit(int minor, char *fsetname, __u8 uuid[16])
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+
+ ENTRY;
+
+ hdr = upc_pack(IZO_UPC_REVOKE_PERMIT, 0, NULL, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
-int lento_permit(int minor, int pathlen, int fsetnamelen, char *path, char *fsetname)
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+
+ if (error)
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
+
+ EXIT;
+ return -error;
+}
+
+int izo_upc_go_fetch_kml(int minor, char *fsetname, __u8 uuid[16],
+ __u64 kmlsize)
{
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
ENTRY;
- insize = SIZE(permit) + pathlen + 1 + fsetnamelen + 1;
- UPARG(LENTO_PERMIT);
- inp->lento_permit.pathlen = pathlen;
- inp->lento_permit.fsetnamelen = fsetnamelen;
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
+
+ hdr = upc_pack(IZO_UPC_GO_FETCH_KML, 0, NULL, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ hdr->u_offset = kmlsize;
+ memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
+
+ error = izo_upc_upcall(minor, &size, hdr, ASYNCHRONOUS);
+ if (error)
+ CERROR("%s: error %d\n", __FUNCTION__, error);
- memcpy(inp->lento_permit.path, path, pathlen);
- inp->lento_permit.path[pathlen] = '\0';
+ EXIT;
+ return -error;
+}
- memcpy(&(inp->lento_permit.path[pathlen+1]), fsetname, fsetnamelen);
- inp->lento_permit.path[fsetnamelen + 1 + pathlen] = '\0';
+int izo_upc_connect(int minor, __u64 ip_address, __u64 port, __u8 uuid[16],
+ int client_flag)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
- CDEBUG(D_UPCALL, "Permit minor %d path %s\n", minor,
- inp->lento_permit.path);
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
- error = lento_upcall(minor, insize, &outsize, inp,
- SYNCHRONOUS, NULL);
+ hdr = upc_pack(IZO_UPC_CONNECT, 0, NULL, NULL, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ hdr->u_offset = ip_address;
+ hdr->u_length = port;
+ memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
+ hdr->u_first_recno = client_flag;
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
if (error) {
- if( error == -EROFS ) {
- int err;
- printk("lento_permit: ERROR - requested permit for "
- "read-only fileset.\n"
- " Setting \"%s\" read-only!\n",
- path);
- err= presto_mark_cache(path, 0xFFFFFFFF,
- CACHE_CLIENT_RO, NULL);
- if( err ) {
- printk("ERROR : mark_cache %d\n", err);
- }
- }
- else {
- printk("lento_permit: error %d\n", error);
- }
+ CERROR("%s: error %d\n", __FUNCTION__, error);
}
EXIT;
+ return -error;
+}
+
+int izo_upc_set_kmlsize(int minor, char *fsetname, __u8 uuid[16], __u64 kmlsize)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
+
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
+
+ hdr = upc_pack(IZO_UPC_SET_KMLSIZE, 0, NULL, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ memcpy(hdr->u_uuid, uuid, sizeof(hdr->u_uuid));
+ hdr->u_length = kmlsize;
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("%s: error %d\n", __FUNCTION__, error);
+
+ EXIT;
+ return -error;
+}
+
+int izo_upc_repstatus(int minor, char * fsetname, struct izo_rcvd_rec *lr_server)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
+
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
+
+ hdr = upc_pack(IZO_UPC_REPSTATUS, 0, NULL, fsetname,
+ sizeof(*lr_server), (char*)lr_server,
+ &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("%s: error %d\n", __FUNCTION__, error);
+
+ EXIT;
+ return -error;
+}
+
+
+#if 0
+int izo_upc_client_make_branch(int minor, char *fsetname, char *tagname,
+ char *branchname)
+{
+ int size, error;
+ struct izo_upcall_hdr *hdr;
+ int pathlen;
+ char *path;
+ ENTRY;
+
+ hdr = upc_pack(IZO_UPC_CLIENT_MAKE_BRANCH, strlen(tagname), tagname,
+ fsetname, strlen(branchname) + 1, branchname, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ error = -PTR_ERR(hdr);
+ goto error;
+ }
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: error %d\n", error);
+ error:
+ PRESTO_FREE(path, pathlen);
+ EXIT;
return error;
}
+#endif
+
+int izo_upc_server_make_branch(int minor, char *fsetname)
+{
+ int size, error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
+ hdr = upc_pack(IZO_UPC_SERVER_MAKE_BRANCH, 0, NULL, fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ error = -PTR_ERR(hdr);
+ goto error;
+ }
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: error %d\n", error);
+
+ error:
+ EXIT;
+ return -error;
+}
+
+int izo_upc_branch_undo(int minor, char *fsetname, char *branchname)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
+
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
+
+ hdr = upc_pack(IZO_UPC_BRANCH_UNDO, strlen(branchname), branchname,
+ fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
+
+ EXIT;
+ return -error;
+}
+
+int izo_upc_branch_redo(int minor, char *fsetname, char *branchname)
+{
+ int size;
+ int error;
+ struct izo_upcall_hdr *hdr;
+ ENTRY;
+
+ if (!presto_lento_up(minor)) {
+ EXIT;
+ return -EIO;
+ }
+
+ hdr = upc_pack(IZO_UPC_BRANCH_REDO, strlen(branchname) + 1, branchname,
+ fsetname, 0, NULL, &size);
+ if (!hdr || IS_ERR(hdr)) {
+ EXIT;
+ return -PTR_ERR(hdr);
+ }
+
+ error = izo_upc_upcall(minor, &size, hdr, SYNCHRONOUS);
+ if (error)
+ CERROR("InterMezzo: %s: error %d\n", __FUNCTION__, error);
+
+ EXIT;
+ return -error;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)