home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: nfs_stubs.c,v 5.1.1.2 90/01/11 17:14:34 jsp Exp Locker: jsp $
- *
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Imperial College of Science, Technology and Medicine, London, UK.
- * The names of the College and University may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * %W% (Berkeley) %G%
- */
-
- #include "am.h"
-
- /*
- * Convert from UN*X to NFS error code
- */
- #ifdef NFS_ERROR_MAPPING
- NFS_ERROR_MAPPING
- #define nfs_error(e) \
- ((nfsstat)((e) > NFS_LOMAP && (e) < NFS_HIMAP ? \
- nfs_errormap[(e) - NFS_LOMAP] : (e)))
- #else
- #define nfs_error(e) ((nfsstat)(e))
- #endif
-
- static char *do_readlink(mp, error_return)
- am_node *mp;
- int *error_return;
- {
- /*
- * If there is a readlink method, then use
- * that, otherwise if a link exists use
- * that, otherwise use the mount point.
- */
- if (mp->am_mnt->mf_ops->readlink) {
- int retry = 0;
- char *ln = (*mp->am_mnt->mf_ops->readlink)(mp, &retry);
- if (ln == 0)
- *error_return = retry;
- /*reschedule_timeout_mp();*/
- return ln;
- } else if (mp->am_link) {
- return mp->am_link;
- } else {
- return mp->am_mnt->mf_mount;
- }
- }
-
- /*ARGSUSED*/
- voidp
- nfsproc_null_2(argp, rqstp)
- voidp argp;
- struct svc_req *rqstp;
- {
- static char res;
-
- return (voidp) &res;
- }
-
-
- /*ARGSUSED*/
- struct attrstat *
- nfsproc_getattr_2(argp, rqstp)
- struct nfs_fh *argp;
- struct svc_req *rqstp;
- {
- static struct attrstat res;
- am_node *mp;
- int retry;
-
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "gettattr:");
- #endif
-
- mp = fh_to_mp2(argp, &retry);
- if (mp == 0) {
- getattr_retry:
- if (retry < 0)
- return 0;
- res.status = nfs_error(retry);
- } else {
- if (mp->am_mnt->mf_fattr.type == NFLNK) {
- /*
- * Make sure we can read the link
- */
- char *ln = do_readlink(mp, &retry);
- if (ln == 0)
- goto getattr_retry;
- mp->am_mnt->mf_fattr.size = strlen(ln);
- }
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "\tstat(%s), size = %d", mp->am_path, mp->am_mnt->mf_fattr.size);
- #endif
- mp->am_stats.s_getattr++;
- return &mp->am_mnt->mf_attr;
- }
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- struct attrstat *
- nfsproc_setattr_2(argp, rqstp)
- struct sattrargs *argp;
- struct svc_req *rqstp;
- {
- static struct attrstat res;
-
- if (!fh_to_mp(&argp->file))
- res.status = nfs_error(ESTALE);
- else
- res.status = nfs_error(EROFS);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- voidp
- nfsproc_root_2(argp, rqstp)
- voidp argp;
- struct svc_req *rqstp;
- {
- static char res;
-
- return (voidp)&res;
- }
-
-
- /*ARGSUSED*/
- struct diropres *
- nfsproc_lookup_2(argp, rqstp)
- struct diropargs *argp;
- struct svc_req *rqstp;
- {
- static struct diropres res;
- am_node *mp;
- int retry;
-
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "lookup:");
- #endif
-
- mp = fh_to_mp2(&argp->dir, &retry);
- if (mp == 0) {
- if (retry < 0)
- return 0;
- res.status = nfs_error(retry);
- } else {
- int error;
- am_node *ap;
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "\tlookuppn(%s, %s)", mp->am_path, argp->name);
- #endif
- ap = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &error, VLOOK_CREATE);
- if (ap == 0) {
- if (error < 0) {
- #ifdef DEBUG
- dlog("Not sending RPC reply");
- #endif
- amd_stats.d_drops++;
- return 0;
- }
- res.status = nfs_error(error);
- } else {
- #ifdef DEBUG
- if (ap->am_mnt->mf_fattr.size < 0)
- dlog("\tERROR: size = %d!", ap->am_mnt->mf_fattr.size);
- #endif
- mp_to_fh(ap, &res.diropres_u.diropres.file);
- res.diropres_u.diropres.attributes = ap->am_mnt->mf_fattr;
- res.status = nfs_error(0);
- }
- mp->am_stats.s_lookup++;
- /*reschedule_timeout_mp();*/
- }
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- struct readlinkres *
- nfsproc_readlink_2(argp, rqstp)
- struct nfs_fh *argp;
- struct svc_req *rqstp;
- {
- static struct readlinkres res;
- am_node *mp;
- int retry;
-
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "readlink:");
- #endif
-
- mp = fh_to_mp2(argp, &retry);
- if (mp == 0) {
- if (retry < 0)
- return 0;
- res.status = nfs_error(retry);
- } else {
- char *ln = do_readlink(mp, &retry);
- if (ln == 0) {
- if (retry < 0)
- return 0;
- res.status = nfs_error(retry);
- } else {
- res.status = NFS_OK;
- }
- #ifdef DEBUG
- Debug(D_TRACE)
- if (ln)
- plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln);
- #endif
- res.readlinkres_u.data = ln;
- mp->am_stats.s_readlink++;
- }
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- struct readres *
- nfsproc_read_2(argp, rqstp)
- struct readargs *argp;
- struct svc_req *rqstp;
- {
- static struct readres res;
-
- bzero((char *)&res, sizeof(res));
-
- res.status = nfs_error(EACCES);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- voidp
- nfsproc_writecache_2(argp, rqstp)
- voidp argp;
- struct svc_req *rqstp;
- {
- static char res;
-
- return (voidp) &res;
- }
-
-
- /*ARGSUSED*/
- struct attrstat *
- nfsproc_write_2(argp, rqstp)
- writeargs *argp;
- struct svc_req *rqstp;
- {
- static struct attrstat res;
-
- if (!fh_to_mp(&argp->file))
- res.status = nfs_error(ESTALE);
- else
- res.status = nfs_error(EROFS);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- struct diropres *
- nfsproc_create_2(argp, rqstp)
- createargs *argp;
- struct svc_req *rqstp;
- {
- static struct diropres res;
-
- if (!fh_to_mp(&argp->where.dir))
- res.status = nfs_error(ESTALE);
- else
- res.status = nfs_error(EROFS);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- static nfsstat *
- unlink_or_rmdir(argp, rqstp, unlinkp)
- struct diropargs *argp;
- struct svc_req *rqstp;
- {
- static nfsstat res;
- int retry;
- mntfs *mf;
- am_node *mp = fh_to_mp3(&argp->dir, &retry, VLOOK_DELETE);
- if (mp == 0) {
- if (retry < 0)
- return 0;
- res = nfs_error(retry);
- goto out;
- }
- mf = mp->am_mnt;
- if (mf->mf_fattr.type != NFDIR) {
- res = nfs_error(ENOTDIR);
- goto out;
- }
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->name);
- #endif
- mp = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &retry, VLOOK_DELETE);
- if (mp == 0) {
- /*
- * Ignore retries...
- */
- if (retry < 0)
- retry = 0;
- /*
- * Usual NFS workaround...
- */
- else if (retry == ENOENT)
- retry = 0;
- res = nfs_error(retry);
- } else {
- forcibly_timeout_mp(mp);
- res = NFS_OK;
- }
-
- out:
- return &res;
- }
-
-
- /*ARGSUSED*/
- nfsstat *
- nfsproc_remove_2(argp, rqstp)
- struct diropargs *argp;
- struct svc_req *rqstp;
- {
- return unlink_or_rmdir(argp, rqstp, 1);
- }
-
- /*ARGSUSED*/
- nfsstat *
- nfsproc_rename_2(argp, rqstp)
- renameargs *argp;
- struct svc_req *rqstp;
- {
- static nfsstat res;
- if (!fh_to_mp(&argp->from.dir) || !fh_to_mp(&argp->to.dir))
- res = nfs_error(ESTALE);
- else
- res = nfs_error(EROFS);
- return &res;
- }
-
-
- /*ARGSUSED*/
- nfsstat *
- nfsproc_link_2(argp, rqstp)
- linkargs *argp;
- struct svc_req *rqstp;
- {
- static nfsstat res;
- if (!fh_to_mp(&argp->from) || !fh_to_mp(&argp->to.dir))
- res = nfs_error(ESTALE);
- else
- res = nfs_error(EROFS);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- nfsstat *
- nfsproc_symlink_2(argp, rqstp)
- symlinkargs *argp;
- struct svc_req *rqstp;
- {
- static nfsstat res;
- if (!fh_to_mp(&argp->from.dir))
- res = nfs_error(ESTALE);
- else
- res = nfs_error(EROFS);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- struct diropres *
- nfsproc_mkdir_2(argp, rqstp)
- createargs *argp;
- struct svc_req *rqstp;
- {
- static struct diropres res;
- if (!fh_to_mp(&argp->where.dir))
- res.status = nfs_error(ESTALE);
- else
- res.status = nfs_error(EROFS);
-
- return &res;
- }
-
-
- /*ARGSUSED*/
- nfsstat *
- nfsproc_rmdir_2(argp, rqstp)
- struct diropargs *argp;
- struct svc_req *rqstp;
- {
- return unlink_or_rmdir(argp, rqstp, 0);
- }
-
-
- /*ARGSUSED*/
- struct readdirres *
- nfsproc_readdir_2(argp, rqstp)
- readdirargs *argp;
- struct svc_req *rqstp;
- {
- static readdirres res;
- static entry e_res[2];
- am_node *mp;
- int retry;
-
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "readdir:");
- #endif
-
- mp = fh_to_mp2(&argp->dir, &retry);
- if (mp == 0) {
- if (retry < 0)
- return 0;
- res.status = nfs_error(retry);
- } else {
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
- #endif
- res.status = nfs_error((*mp->am_mnt->mf_ops->readdir)(mp, argp->cookie,
- &res.readdirres_u.reply, e_res));
- mp->am_stats.s_readdir++;
- }
-
- /* XXX - need to take argp->count into account */
-
- return &res;
- }
-
- /*ARGSUSED*/
- struct statfsres *
- nfsproc_statfs_2(argp, rqstp)
- struct nfs_fh *argp;
- struct svc_req *rqstp;
- {
- static statfsres res;
- am_node *mp;
- int retry;
-
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "statfs:");
- #endif
-
- mp = fh_to_mp2(argp, &retry);
- if (mp == 0) {
- if (retry < 0)
- return 0;
- res.status = nfs_error(retry);
- } else {
- statfsokres *fp;
- #ifdef DEBUG
- Debug(D_TRACE)
- plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path);
- #endif
- /*
- * just return faked up file system information
- */
-
- fp = &res.statfsres_u.reply;
-
- fp->tsize = 1024;
- fp->bsize = 4192;
- fp->blocks = 0;
- fp->bfree = 0;
- fp->bavail = 0;
-
- res.status = NFS_OK;
- mp->am_stats.s_statfs++;
- }
-
- return &res;
- }
-