* Copyright (c) 1990 Jan-Simon Pendry
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
* Copyright (c) 1990, 1993
* 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, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)nfs_subr.c 8.1 (Berkeley) 6/6/93
* $Id: nfs_subr.c,v 5.2.2.1 1992/02/09 15:08:53 jsp beta $
* Convert from UN*X to NFS error code
((nfsstat)((e) > NFS_LOMAP && (e) < NFS_HIMAP ? \
nfs_errormap[(e) - NFS_LOMAP] : (e)))
#define nfs_error(e) ((nfsstat)(e))
#endif /* NFS_ERROR_MAPPING */
static char *do_readlink
P((am_node
*mp
, int *error_return
, struct attrstat
**attrpp
));
static char *do_readlink(mp
, error_return
, attrpp
)
struct attrstat
**attrpp
;
* 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
) {
mp
= (*mp
->am_mnt
->mf_ops
->readlink
)(mp
, &retry
);
/*reschedule_timeout_mp();*/
ln
= mp
->am_mnt
->mf_mount
;
nfsproc_null_2(argp
, rqstp
)
nfsproc_getattr_2(argp
, rqstp
)
static struct attrstat res
;
plog(XLOG_DEBUG
, "gettattr:");
mp
= fh_to_mp2(argp
, &retry
);
#endif /* PRECISE_SYMLINKS */
res
.status
= nfs_error(retry
);
struct attrstat
*attrp
= &mp
->am_attr
;
if (mp
->am_fattr
.type
== NFLNK
) {
* Make sure we can read the link,
* and then determine the length.
char *ln
= do_readlink(mp
, &retry
, &attrp
);
#endif /* PRECISE_SYMLINKS */
plog(XLOG_DEBUG
, "\tstat(%s), size = %d", mp
->am_path
, attrp
->attrstat_u
.attributes
.size
);
mp
->am_stats
.s_getattr
++;
nfsproc_setattr_2(argp
, rqstp
)
static struct attrstat res
;
if (!fh_to_mp(&argp
->file
))
res
.status
= nfs_error(ESTALE
);
res
.status
= nfs_error(EROFS
);
nfsproc_root_2(argp
, rqstp
)
nfsproc_lookup_2(argp
, rqstp
)
static struct diropres res
;
plog(XLOG_DEBUG
, "lookup:");
mp
= fh_to_mp2(&argp
->dir
, &retry
);
res
.status
= nfs_error(retry
);
plog(XLOG_DEBUG
, "\tlookuppn(%s, %s)", mp
->am_path
, argp
->name
);
ap
= (*mp
->am_mnt
->mf_ops
->lookuppn
)(mp
, argp
->name
, &error
, VLOOK_CREATE
);
dlog("Not sending RPC reply");
res
.status
= nfs_error(error
);
mp_to_fh(ap
, &res
.diropres_u
.diropres
.file
);
res
.diropres_u
.diropres
.attributes
= ap
->am_fattr
;
/*reschedule_timeout_mp();*/
nfsproc_readlink_2(argp
, rqstp
)
static struct readlinkres res
;
plog(XLOG_DEBUG
, "readlink:");
mp
= fh_to_mp2(argp
, &retry
);
res
.status
= nfs_error(retry
);
char *ln
= do_readlink(mp
, &retry
, (struct attrstat
**) 0);
plog(XLOG_DEBUG
, "\treadlink(%s) = %s", mp
->am_path
, ln
);
res
.readlinkres_u
.data
= ln
;
mp
->am_stats
.s_readlink
++;
nfsproc_read_2(argp
, rqstp
)
static struct readres res
;
bzero((char *)&res
, sizeof(res
));
res
.status
= nfs_error(EACCES
);
nfsproc_writecache_2(argp
, rqstp
)
nfsproc_write_2(argp
, rqstp
)
static struct attrstat res
;
if (!fh_to_mp(&argp
->file
))
res
.status
= nfs_error(ESTALE
);
res
.status
= nfs_error(EROFS
);
nfsproc_create_2(argp
, rqstp
)
static struct diropres res
;
if (!fh_to_mp(&argp
->where
.dir
))
res
.status
= nfs_error(ESTALE
);
res
.status
= nfs_error(EROFS
);
unlink_or_rmdir(argp
, rqstp
, unlinkp
)
am_node
*mp
= fh_to_mp3(&argp
->dir
, &retry
, VLOOK_DELETE
);
if (mp
->am_fattr
.type
!= NFDIR
) {
res
= nfs_error(ENOTDIR
);
plog(XLOG_DEBUG
, "\tremove(%s, %s)", mp
->am_path
, argp
->name
);
mp
= (*mp
->am_mnt
->mf_ops
->lookuppn
)(mp
, argp
->name
, &retry
, VLOOK_DELETE
);
* Usual NFS workaround...
else if (retry
== ENOENT
)
nfsproc_remove_2(argp
, rqstp
)
return unlink_or_rmdir(argp
, rqstp
, TRUE
);
nfsproc_rename_2(argp
, rqstp
)
if (!fh_to_mp(&argp
->from
.dir
) || !fh_to_mp(&argp
->to
.dir
))
* If the kernel is doing clever things with referenced files
else if (strncmp(argp
->to
.name
, ".nfs", 4) == 0)
nfsproc_link_2(argp
, rqstp
)
if (!fh_to_mp(&argp
->from
) || !fh_to_mp(&argp
->to
.dir
))
nfsproc_symlink_2(argp
, rqstp
)
if (!fh_to_mp(&argp
->from
.dir
))
nfsproc_mkdir_2(argp
, rqstp
)
static struct diropres res
;
if (!fh_to_mp(&argp
->where
.dir
))
res
.status
= nfs_error(ESTALE
);
res
.status
= nfs_error(EROFS
);
nfsproc_rmdir_2(argp
, rqstp
)
return unlink_or_rmdir(argp
, rqstp
, FALSE
);
nfsproc_readdir_2(argp
, rqstp
)
static entry e_res
[MAX_READDIR_ENTRIES
];
plog(XLOG_DEBUG
, "readdir:");
mp
= fh_to_mp2(&argp
->dir
, &retry
);
res
.status
= nfs_error(retry
);
plog(XLOG_DEBUG
, "\treaddir(%s)", mp
->am_path
);
res
.status
= nfs_error((*mp
->am_mnt
->mf_ops
->readdir
)(mp
, argp
->cookie
,
&res
.readdirres_u
.reply
, e_res
, argp
->count
));
mp
->am_stats
.s_readdir
++;
nfsproc_statfs_2(argp
, rqstp
)
plog(XLOG_DEBUG
, "statfs:");
mp
= fh_to_mp2(argp
, &retry
);
res
.status
= nfs_error(retry
);
plog(XLOG_DEBUG
, "\tstat_fs(%s)", mp
->am_path
);
* just return faked up file system information
fp
= &res
.statfsres_u
.reply
;
#ifdef HAS_EMPTY_AUTOMOUNTS