home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume21 / amd / part06 / nfs_stubs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-10  |  9.3 KB  |  517 lines

  1. /*
  2.  * $Id: nfs_stubs.c,v 5.1.1.2 90/01/11 17:14:34 jsp Exp Locker: jsp $
  3.  *
  4.  * Copyright (c) 1990 Jan-Simon Pendry
  5.  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  6.  * Copyright (c) 1990 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * This code is derived from software contributed to Berkeley by
  10.  * Jan-Simon Pendry at Imperial College, London.
  11.  *
  12.  * Redistribution and use in source and binary forms are permitted
  13.  * provided that the above copyright notice and this paragraph are
  14.  * duplicated in all such forms and that any documentation,
  15.  * advertising materials, and other materials related to such
  16.  * distribution and use acknowledge that the software was developed
  17.  * by Imperial College of Science, Technology and Medicine, London, UK.
  18.  * The names of the College and University may not be used to endorse
  19.  * or promote products derived from this software without specific
  20.  * prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  *
  25.  *    %W% (Berkeley) %G%
  26.  */
  27.  
  28. #include "am.h"
  29.  
  30. /*
  31.  * Convert from UN*X to NFS error code
  32.  */
  33. #ifdef NFS_ERROR_MAPPING
  34. NFS_ERROR_MAPPING
  35. #define nfs_error(e) \
  36.         ((nfsstat)((e) > NFS_LOMAP && (e) < NFS_HIMAP ? \
  37.         nfs_errormap[(e) - NFS_LOMAP] : (e)))
  38. #else
  39. #define nfs_error(e) ((nfsstat)(e))
  40. #endif
  41.  
  42. static char *do_readlink(mp, error_return)
  43. am_node *mp;
  44. int *error_return;
  45. {
  46.     /*
  47.      * If there is a readlink method, then use
  48.      * that, otherwise if a link exists use
  49.      * that, otherwise use the mount point.
  50.      */
  51.     if (mp->am_mnt->mf_ops->readlink) {
  52.         int retry = 0;
  53.         char *ln = (*mp->am_mnt->mf_ops->readlink)(mp, &retry);
  54.         if (ln == 0)
  55.             *error_return = retry;
  56.         /*reschedule_timeout_mp();*/
  57.         return ln;
  58.     } else if (mp->am_link) {
  59.         return mp->am_link;
  60.     } else {
  61.         return mp->am_mnt->mf_mount;
  62.     }
  63. }
  64.  
  65. /*ARGSUSED*/
  66. voidp 
  67. nfsproc_null_2(argp, rqstp)
  68. voidp argp;
  69. struct svc_req *rqstp;
  70. {
  71.     static char res;
  72.  
  73.     return (voidp) &res;
  74. }
  75.  
  76.  
  77. /*ARGSUSED*/
  78. struct attrstat *
  79. nfsproc_getattr_2(argp, rqstp)
  80. struct nfs_fh *argp;
  81. struct svc_req *rqstp;
  82. {
  83.     static struct attrstat res;
  84.     am_node *mp;
  85.     int retry;
  86.  
  87. #ifdef DEBUG
  88.     Debug(D_TRACE)
  89.         plog(XLOG_DEBUG, "gettattr:");
  90. #endif
  91.  
  92.     mp = fh_to_mp2(argp, &retry);
  93.     if (mp == 0) {
  94. getattr_retry:
  95.         if (retry < 0)
  96.             return 0;
  97.         res.status = nfs_error(retry);
  98.     } else {
  99.         if (mp->am_mnt->mf_fattr.type == NFLNK) {
  100.             /*
  101.              * Make sure we can read the link
  102.              */
  103.             char *ln = do_readlink(mp, &retry);
  104.             if (ln == 0)
  105.                 goto getattr_retry;
  106.             mp->am_mnt->mf_fattr.size = strlen(ln);
  107.         }
  108. #ifdef DEBUG
  109.         Debug(D_TRACE)
  110.             plog(XLOG_DEBUG, "\tstat(%s), size = %d", mp->am_path, mp->am_mnt->mf_fattr.size);
  111. #endif
  112.         mp->am_stats.s_getattr++;
  113.         return &mp->am_mnt->mf_attr;
  114.     }
  115.  
  116.     return &res;
  117. }
  118.  
  119.  
  120. /*ARGSUSED*/
  121. struct attrstat *
  122. nfsproc_setattr_2(argp, rqstp)
  123. struct sattrargs *argp;
  124. struct svc_req *rqstp;
  125. {
  126.     static struct attrstat res;
  127.  
  128.     if (!fh_to_mp(&argp->file))
  129.         res.status = nfs_error(ESTALE);
  130.     else
  131.         res.status = nfs_error(EROFS);
  132.  
  133.     return &res;
  134. }
  135.  
  136.  
  137. /*ARGSUSED*/
  138. voidp 
  139. nfsproc_root_2(argp, rqstp)
  140. voidp argp;
  141. struct svc_req *rqstp;
  142. {
  143.     static char res;
  144.  
  145.     return (voidp)&res;
  146. }
  147.  
  148.  
  149. /*ARGSUSED*/
  150. struct diropres *
  151. nfsproc_lookup_2(argp, rqstp)
  152. struct diropargs *argp;
  153. struct svc_req *rqstp;
  154. {
  155.     static struct diropres res;
  156.     am_node *mp;
  157.     int retry;
  158.  
  159. #ifdef DEBUG
  160.     Debug(D_TRACE)
  161.         plog(XLOG_DEBUG, "lookup:");
  162. #endif
  163.  
  164.     mp = fh_to_mp2(&argp->dir, &retry);
  165.     if (mp == 0) {
  166.         if (retry < 0)
  167.             return 0;
  168.         res.status = nfs_error(retry);
  169.     } else {
  170.         int error;
  171.         am_node *ap;
  172. #ifdef DEBUG
  173.         Debug(D_TRACE)
  174.             plog(XLOG_DEBUG, "\tlookuppn(%s, %s)", mp->am_path, argp->name);
  175. #endif
  176.         ap = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &error, VLOOK_CREATE);
  177.         if (ap == 0) {
  178.             if (error < 0) {
  179. #ifdef DEBUG
  180.                 dlog("Not sending RPC reply");
  181. #endif
  182.                 amd_stats.d_drops++;
  183.                 return 0;
  184.             }
  185.             res.status = nfs_error(error);
  186.         } else {
  187. #ifdef DEBUG
  188.             if (ap->am_mnt->mf_fattr.size < 0)
  189.                 dlog("\tERROR: size = %d!", ap->am_mnt->mf_fattr.size);
  190. #endif
  191.             mp_to_fh(ap, &res.diropres_u.diropres.file);
  192.             res.diropres_u.diropres.attributes = ap->am_mnt->mf_fattr;
  193.             res.status = nfs_error(0);
  194.         }
  195.         mp->am_stats.s_lookup++;
  196.         /*reschedule_timeout_mp();*/
  197.     }
  198.  
  199.     return &res;
  200. }
  201.  
  202.  
  203. /*ARGSUSED*/
  204. struct readlinkres *
  205. nfsproc_readlink_2(argp, rqstp)
  206. struct nfs_fh *argp;
  207. struct svc_req *rqstp;
  208. {
  209.     static struct readlinkres res;
  210.     am_node *mp;
  211.     int retry;
  212.  
  213. #ifdef DEBUG
  214.     Debug(D_TRACE)
  215.         plog(XLOG_DEBUG, "readlink:");
  216. #endif
  217.  
  218.     mp = fh_to_mp2(argp, &retry);
  219.     if (mp == 0) {
  220.         if (retry < 0)
  221.             return 0;
  222.         res.status = nfs_error(retry);
  223.     } else {
  224.         char *ln = do_readlink(mp, &retry);
  225.         if (ln == 0) {
  226.             if (retry < 0)
  227.                 return 0;
  228.             res.status = nfs_error(retry);
  229.         } else {
  230.             res.status = NFS_OK;
  231.         }
  232. #ifdef DEBUG
  233.         Debug(D_TRACE)
  234.             if (ln)
  235.                 plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln);
  236. #endif
  237.         res.readlinkres_u.data = ln;
  238.         mp->am_stats.s_readlink++;
  239.     }
  240.  
  241.     return &res;
  242. }
  243.  
  244.  
  245. /*ARGSUSED*/
  246. struct readres *
  247. nfsproc_read_2(argp, rqstp)
  248. struct readargs *argp;
  249. struct svc_req *rqstp;
  250. {
  251.     static struct readres res;
  252.  
  253.     bzero((char *)&res, sizeof(res));
  254.  
  255.     res.status = nfs_error(EACCES);
  256.  
  257.     return &res;
  258. }
  259.  
  260.  
  261. /*ARGSUSED*/
  262. voidp 
  263. nfsproc_writecache_2(argp, rqstp)
  264. voidp argp;
  265. struct svc_req *rqstp;
  266. {
  267.     static char res;
  268.  
  269.     return (voidp) &res;
  270. }
  271.  
  272.  
  273. /*ARGSUSED*/
  274. struct attrstat *
  275. nfsproc_write_2(argp, rqstp)
  276. writeargs *argp;
  277. struct svc_req *rqstp;
  278. {
  279.     static struct attrstat res;
  280.  
  281.     if (!fh_to_mp(&argp->file))
  282.         res.status = nfs_error(ESTALE);
  283.     else
  284.         res.status = nfs_error(EROFS);
  285.  
  286.     return &res;
  287. }
  288.  
  289.  
  290. /*ARGSUSED*/
  291. struct diropres *
  292. nfsproc_create_2(argp, rqstp)
  293. createargs *argp;
  294. struct svc_req *rqstp;
  295. {
  296.     static struct diropres res;
  297.  
  298.     if (!fh_to_mp(&argp->where.dir))
  299.         res.status = nfs_error(ESTALE);
  300.     else
  301.         res.status = nfs_error(EROFS);
  302.  
  303.     return &res;
  304. }
  305.  
  306.  
  307. /*ARGSUSED*/
  308. static nfsstat *
  309. unlink_or_rmdir(argp, rqstp, unlinkp)
  310. struct diropargs *argp;
  311. struct svc_req *rqstp;
  312. {
  313.     static nfsstat res;
  314.     int retry;
  315.     mntfs *mf;
  316.     am_node *mp = fh_to_mp3(&argp->dir, &retry, VLOOK_DELETE);
  317.     if (mp == 0) {
  318.         if (retry < 0)
  319.             return 0;
  320.         res = nfs_error(retry);
  321.         goto out;
  322.     }
  323.     mf = mp->am_mnt;
  324.     if (mf->mf_fattr.type != NFDIR) {
  325.         res = nfs_error(ENOTDIR);
  326.         goto out;
  327.     }
  328. #ifdef DEBUG
  329.     Debug(D_TRACE)
  330.         plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->name);
  331. #endif
  332.     mp = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &retry, VLOOK_DELETE);
  333.     if (mp == 0) {
  334.         /*
  335.          * Ignore retries...
  336.          */
  337.         if (retry < 0)
  338.             retry = 0;
  339.         /*
  340.          * Usual NFS workaround...
  341.          */
  342.         else if (retry == ENOENT)
  343.             retry = 0;
  344.         res = nfs_error(retry);
  345.     } else {
  346.         forcibly_timeout_mp(mp);
  347.         res = NFS_OK;
  348.     }
  349.  
  350. out:
  351.     return &res;
  352. }
  353.  
  354.  
  355. /*ARGSUSED*/
  356. nfsstat *
  357. nfsproc_remove_2(argp, rqstp)
  358. struct diropargs *argp;
  359. struct svc_req *rqstp;
  360. {
  361.     return unlink_or_rmdir(argp, rqstp, 1);
  362. }
  363.  
  364. /*ARGSUSED*/
  365. nfsstat *
  366. nfsproc_rename_2(argp, rqstp)
  367. renameargs *argp;
  368. struct svc_req *rqstp;
  369. {
  370.     static nfsstat res;
  371.     if (!fh_to_mp(&argp->from.dir) || !fh_to_mp(&argp->to.dir))
  372.         res = nfs_error(ESTALE);
  373.     else
  374.         res = nfs_error(EROFS);
  375.     return &res;
  376. }
  377.  
  378.  
  379. /*ARGSUSED*/
  380. nfsstat *
  381. nfsproc_link_2(argp, rqstp)
  382. linkargs *argp;
  383. struct svc_req *rqstp;
  384. {
  385.     static nfsstat res;
  386.     if (!fh_to_mp(&argp->from) || !fh_to_mp(&argp->to.dir))
  387.         res = nfs_error(ESTALE);
  388.     else
  389.         res = nfs_error(EROFS);
  390.  
  391.     return &res;
  392. }
  393.  
  394.  
  395. /*ARGSUSED*/
  396. nfsstat *
  397. nfsproc_symlink_2(argp, rqstp)
  398. symlinkargs *argp;
  399. struct svc_req *rqstp;
  400. {
  401.     static nfsstat res;
  402.     if (!fh_to_mp(&argp->from.dir))
  403.         res = nfs_error(ESTALE);
  404.     else
  405.         res = nfs_error(EROFS);
  406.  
  407.     return &res;
  408. }
  409.  
  410.  
  411. /*ARGSUSED*/
  412. struct diropres *
  413. nfsproc_mkdir_2(argp, rqstp)
  414. createargs *argp;
  415. struct svc_req *rqstp;
  416. {
  417.     static struct diropres res;
  418.     if (!fh_to_mp(&argp->where.dir))
  419.         res.status = nfs_error(ESTALE);
  420.     else
  421.         res.status = nfs_error(EROFS);
  422.  
  423.     return &res;
  424. }
  425.  
  426.  
  427. /*ARGSUSED*/
  428. nfsstat *
  429. nfsproc_rmdir_2(argp, rqstp)
  430. struct diropargs *argp;
  431. struct svc_req *rqstp;
  432. {
  433.     return unlink_or_rmdir(argp, rqstp, 0);
  434. }
  435.  
  436.  
  437. /*ARGSUSED*/
  438. struct readdirres *
  439. nfsproc_readdir_2(argp, rqstp)
  440. readdirargs *argp;
  441. struct svc_req *rqstp;
  442. {
  443.     static readdirres res;
  444.     static entry e_res[2];
  445.     am_node *mp;
  446.     int retry;
  447.  
  448. #ifdef DEBUG
  449.     Debug(D_TRACE)
  450.         plog(XLOG_DEBUG, "readdir:");
  451. #endif
  452.  
  453.     mp = fh_to_mp2(&argp->dir, &retry);
  454.     if (mp == 0) {
  455.         if (retry < 0)
  456.             return 0;
  457.         res.status = nfs_error(retry);
  458.     } else {
  459. #ifdef DEBUG
  460.         Debug(D_TRACE)
  461.             plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
  462. #endif
  463.         res.status = nfs_error((*mp->am_mnt->mf_ops->readdir)(mp, argp->cookie,
  464.                     &res.readdirres_u.reply, e_res));
  465.         mp->am_stats.s_readdir++;
  466.     }
  467.  
  468.     /* XXX - need to take argp->count into account */
  469.  
  470.     return &res;
  471. }
  472.  
  473. /*ARGSUSED*/
  474. struct statfsres *
  475. nfsproc_statfs_2(argp, rqstp)
  476. struct nfs_fh *argp;
  477. struct svc_req *rqstp;
  478. {
  479.     static statfsres res;
  480.     am_node *mp;
  481.     int retry;
  482.  
  483. #ifdef DEBUG
  484.     Debug(D_TRACE)
  485.         plog(XLOG_DEBUG, "statfs:");
  486. #endif
  487.  
  488.     mp = fh_to_mp2(argp, &retry);
  489.     if (mp == 0) {
  490.         if (retry < 0)
  491.             return 0;
  492.         res.status = nfs_error(retry);
  493.     } else {
  494.         statfsokres *fp;
  495. #ifdef DEBUG
  496.         Debug(D_TRACE)
  497.             plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path);
  498. #endif
  499.         /*
  500.          * just return faked up file system information
  501.          */
  502.  
  503.         fp = &res.statfsres_u.reply;
  504.  
  505.         fp->tsize = 1024;
  506.         fp->bsize = 4192;
  507.         fp->blocks = 0;
  508.         fp->bfree = 0;
  509.         fp->bavail = 0;
  510.  
  511.         res.status = NFS_OK;
  512.         mp->am_stats.s_statfs++;
  513.     }
  514.  
  515.     return &res;
  516. }
  517.