* SUCH DAMAGE.
*
* from: @(#)ufs_vnops.c 7.64 (Berkeley) 5/16/91
- * $Id$
+ * $Id: ufs_vnops.c,v 1.8 1993/11/25 01:38:40 wollman Exp $
*/
#include "param.h"
#include "dir.h"
#include "fs.h"
+/* Get the current value of _POSIX_CHOWN_RESTRICTED */
+#include "sys/unistd.h" /* make sure to get sys/ version. */
+
+static int maknode(int, struct nameidata *, struct inode **);
+
+/* XXX - don't want to change ucred.h again */
+extern int groupmember(int /*gid_t*/, struct ucred *);
+
/*
* Create a regular file
*/
+int
ufs_create(ndp, vap, p)
struct nameidata *ndp;
struct vattr *vap;
* Mknod vnode call
*/
/* ARGSUSED */
+int
ufs_mknod(ndp, vap, cred, p)
struct nameidata *ndp;
struct ucred *cred;
* Nothing to do.
*/
/* ARGSUSED */
+int
ufs_open(vp, mode, cred, p)
struct vnode *vp;
int mode;
* Update the times on the inode.
*/
/* ARGSUSED */
+int
ufs_close(vp, fflag, cred, p)
struct vnode *vp;
int fflag;
* The mode is shifted to select the owner/group/other fields. The
* super user is granted all permissions.
*/
+int
ufs_access(vp, mode, cred, p)
struct vnode *vp;
register int mode;
}
/* ARGSUSED */
+int
ufs_getattr(vp, vap, cred, p)
struct vnode *vp;
register struct vattr *vap;
/*
* Set attribute vnode op. called from several syscalls
*/
+int
ufs_setattr(vp, vap, cred, p)
register struct vnode *vp;
register struct vattr *vap;
if (cred->cr_uid == 0) {
ip->i_flags = vap->va_flags;
} else {
- ip->i_flags &= 0xffff0000;
+ ip->i_flags &= 0xffff0000ul;
ip->i_flags |= (vap->va_flags & 0xffff);
}
ip->i_flag |= ICHG;
* Change the mode on a file.
* Inode must be locked before calling.
*/
+int
chmod1(vp, mode, p)
register struct vnode *vp;
register int mode;
* Perform chown operation on inode ip;
* inode must be locked prior to call.
*/
+int
chown1(vp, uid, gid, p)
register struct vnode *vp;
uid_t uid;
* of the file, or are not a member of the target group,
* the caller must be superuser or the call fails.
*/
+#ifdef _POSIX_CHOWN_RESTRICTED
if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
!groupmember((gid_t)gid, cred)) &&
(error = suser(cred, &p->p_acflag)))
return (error);
+#else
+ if ((cred->cr_uid != ip->i_uid || !groupmember((gid_t)gid, cred))
+ && (error = suser(cred, &p->p_acflag)))
+ return error;
+#endif
ouid = ip->i_uid;
ogid = ip->i_gid;
#ifdef QUOTA
* Vnode op for reading.
*/
/* ARGSUSED */
+int
ufs_read(vp, uio, ioflag, cred)
struct vnode *vp;
register struct uio *uio;
/*
* Vnode op for writing.
*/
+int
ufs_write(vp, uio, ioflag, cred)
register struct vnode *vp;
struct uio *uio;
}
/* ARGSUSED */
+int
ufs_ioctl(vp, com, data, fflag, cred, p)
struct vnode *vp;
int com;
}
/* ARGSUSED */
+int
ufs_select(vp, which, fflags, cred, p)
struct vnode *vp;
int which, fflags;
* NB Currently unsupported.
*/
/* ARGSUSED */
+int
ufs_mmap(vp, fflags, cred, p)
struct vnode *vp;
int fflags;
* Synch an open file.
*/
/* ARGSUSED */
+int
ufs_fsync(vp, fflags, cred, waitfor, p)
struct vnode *vp;
int fflags;
* Nothing to do, so just return.
*/
/* ARGSUSED */
+int
ufs_seek(vp, oldoff, newoff, cred)
struct vnode *vp;
off_t oldoff, newoff;
* Hard to avoid races here, especially
* in unlinking directories.
*/
+int
ufs_remove(ndp, p)
struct nameidata *ndp;
struct proc *p;
/*
* link vnode call
*/
+int
ufs_link(vp, ndp, p)
register struct vnode *vp;
register struct nameidata *ndp;
register struct inode *ip = VTOI(vp);
int error;
-#ifdef DIANOSTIC
+#ifdef DIAGNOSTIC
if ((ndp->ni_nameiop & HASBUF) == 0)
panic("ufs_link: no name");
#endif
* is different from the source, patch the ".." entry in the
* directory.
*/
+int
ufs_rename(fndp, tndp, p)
register struct nameidata *fndp, *tndp;
struct proc *p;
int doingdirectory = 0, oldparent = 0, newparent = 0;
int error = 0;
-#ifdef DIANOSTIC
+#ifdef DIAGNOSTIC
if ((tndp->ni_nameiop & HASBUF) == 0 ||
(fndp->ni_nameiop & HASBUF) == 0)
panic("ufs_rename: no name");
/*
* Mkdir system call
*/
+int
ufs_mkdir(ndp, vap, p)
struct nameidata *ndp;
struct vattr *vap;
int error;
int dmode;
-#ifdef DIANOSTIC
+#ifdef DIAGNOSTIC
if ((ndp->ni_nameiop & HASBUF) == 0)
panic("ufs_mkdir: no name");
#endif
/*
* Rmdir system call.
*/
+int
ufs_rmdir(ndp, p)
register struct nameidata *ndp;
struct proc *p;
/*
* symlink -- make a symbolic link
*/
+int
ufs_symlink(ndp, vap, target, p)
struct nameidata *ndp;
struct vattr *vap;
/*
* Vnode op for read and write
*/
+int
ufs_readdir(vp, uio, cred, eofflagp)
struct vnode *vp;
register struct uio *uio;
/*
* Return target name of a symbolic link
*/
+int
ufs_readlink(vp, uiop, cred)
struct vnode *vp;
struct uio *uiop;
* done. If a buffer has been saved in anticipation of a CREATE, delete it.
*/
/* ARGSUSED */
+int
ufs_abortop(ndp)
struct nameidata *ndp;
{
/*
* Lock an inode.
*/
+int
ufs_lock(vp)
struct vnode *vp;
{
/*
* Unlock an inode.
*/
+int
ufs_unlock(vp)
struct vnode *vp;
{
/*
* Check for a locked inode.
*/
+int
ufs_islocked(vp)
struct vnode *vp;
{
/*
* Get access to bmap
*/
+int
ufs_bmap(vp, bn, vpp, bnp)
struct vnode *vp;
daddr_t bn;
*/
int checkoverlap = 0;
+int
ufs_strategy(bp)
register struct buf *bp;
{
/*
* Print out the contents of an inode.
*/
+void
ufs_print(vp)
struct vnode *vp;
{
/*
* Read wrapper for special devices.
*/
+int
ufsspec_read(vp, uio, ioflag, cred)
struct vnode *vp;
struct uio *uio;
/*
* Write wrapper for special devices.
*/
+int
ufsspec_write(vp, uio, ioflag, cred)
struct vnode *vp;
struct uio *uio;
*
* Update the times on the inode then do device close.
*/
+int
ufsspec_close(vp, fflag, cred, p)
struct vnode *vp;
int fflag;
/*
* Read wrapper for fifo's
*/
+int
ufsfifo_read(vp, uio, ioflag, cred)
struct vnode *vp;
struct uio *uio;
/*
* Write wrapper for fifo's.
*/
+int
ufsfifo_write(vp, uio, ioflag, cred)
struct vnode *vp;
struct uio *uio;
*
* Update the times on the inode then do device close.
*/
+int
ufsfifo_close(vp, fflag, cred, p)
struct vnode *vp;
int fflag;
/*
* Allocate a new inode.
*/
+static int
maknode(mode, ndp, ipp)
int mode;
register struct nameidata *ndp;
ino_t ipref;
int error;
-#ifdef DIANOSTIC
+#ifdef DIAGNOSTIC
if ((ndp->ni_nameiop & HASBUF) == 0)
panic("maknode: no name");
#endif
/*
* Advisory record locking support
*/
+int
ufs_advlock(vp, id, op, fl, flags)
struct vnode *vp;
caddr_t id;
int flags;
{
register struct inode *ip = VTOI(vp);
- register struct lockf *lock;
- off_t start, end;
- int error;
-
- /*
- * Avoid the common case of unlocking when inode has no locks.
- */
- if (ip->i_lockf == (struct lockf *)0) {
- if (op != F_SETLK) {
- fl->l_type = F_UNLCK;
- return (0);
- }
- }
- /*
- * Convert the flock structure into a start and end.
- */
- switch (fl->l_whence) {
-
- case SEEK_SET:
- case SEEK_CUR:
- /*
- * Caller is responsible for adding any necessary offset
- * when SEEK_CUR is used.
- */
- start = fl->l_start;
- break;
-
- case SEEK_END:
- start = ip->i_size + fl->l_start;
- break;
-
- default:
- return (EINVAL);
- }
- if (start < 0)
- return (EINVAL);
- if (fl->l_len == 0)
- end = -1;
- else
- end = start + fl->l_len - 1;
- /*
- * Create the lockf structure
- */
- MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK);
- lock->lf_start = start;
- lock->lf_end = end;
- lock->lf_id = id;
- lock->lf_inode = ip;
- lock->lf_type = fl->l_type;
- lock->lf_next = (struct lockf *)0;
- lock->lf_block = (struct lockf *)0;
- lock->lf_flags = flags;
- /*
- * Do the requested operation.
- */
- switch(op) {
- case F_SETLK:
- return (lf_setlock(lock));
-
- case F_UNLCK:
- error = lf_clearlock(lock);
- FREE(lock, M_LOCKF);
- return (error);
- case F_GETLK:
- error = lf_getlock(lock, fl);
- FREE(lock, M_LOCKF);
- return (error);
-
- default:
- free(lock, M_LOCKF);
- return (EINVAL);
- }
- /* NOTREACHED */
+ return (lf_advlock(&(ip->i_lockf), ip->i_size, id, op, fl, flags));
}
/*