version 1.127.2.3, 2007/02/26 09:12:25 |
version 1.127.2.4, 2007/09/03 14:47:02 |
Line 65 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 65 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <miscfs/specfs/specdev.h> |
#include <miscfs/specfs/specdev.h> |
#include <miscfs/fifofs/fifo.h> |
#include <miscfs/fifofs/fifo.h> |
|
|
#include <ufs/ufs/quota.h> |
|
#include <ufs/ufs/inode.h> |
#include <ufs/ufs/inode.h> |
#include <ufs/ufs/dir.h> |
#include <ufs/ufs/dir.h> |
#include <ufs/ufs/ufsmount.h> |
#include <ufs/ufs/ufsmount.h> |
Line 106 ufs_create(void *v) |
|
Line 105 ufs_create(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
int error; |
int error; |
|
|
if ((error = fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
error = |
error = |
ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), |
ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), |
ap->a_dvp, ap->a_vpp, ap->a_cnp); |
ap->a_dvp, ap->a_vpp, ap->a_cnp); |
Line 140 ufs_mknod(void *v) |
|
Line 138 ufs_mknod(void *v) |
|
|
|
vap = ap->a_vap; |
vap = ap->a_vap; |
vpp = ap->a_vpp; |
vpp = ap->a_vpp; |
if ((error = fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
if ((error = |
if ((error = |
ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), |
ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), |
ap->a_dvp, vpp, ap->a_cnp)) != 0) |
ap->a_dvp, vpp, ap->a_cnp)) != 0) |
Line 266 ufs_access(void *v) |
|
Line 263 ufs_access(void *v) |
|
if (vp->v_mount->mnt_flag & MNT_RDONLY) |
if (vp->v_mount->mnt_flag & MNT_RDONLY) |
return (EROFS); |
return (EROFS); |
#ifdef QUOTA |
#ifdef QUOTA |
if ((error = |
fstrans_start(vp->v_mount, FSTRANS_SHARED); |
fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0) |
|
return error; |
|
error = getinoquota(ip); |
error = getinoquota(ip); |
fstrans_done(vp->v_mount); |
fstrans_done(vp->v_mount); |
if (error != 0) |
if (error != 0) |
Line 398 ufs_setattr(void *v) |
|
Line 393 ufs_setattr(void *v) |
|
return (EINVAL); |
return (EINVAL); |
} |
} |
|
|
if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(vp->v_mount, FSTRANS_SHARED); |
return error; |
|
|
|
if (vap->va_flags != VNOVAL) { |
if (vap->va_flags != VNOVAL) { |
if (vp->v_mount->mnt_flag & MNT_RDONLY) { |
if (vp->v_mount->mnt_flag & MNT_RDONLY) { |
Line 587 ufs_chown(struct vnode *vp, uid_t uid, g |
|
Line 581 ufs_chown(struct vnode *vp, uid_t uid, g |
|
#ifdef QUOTA |
#ifdef QUOTA |
uid_t ouid; |
uid_t ouid; |
gid_t ogid; |
gid_t ogid; |
int i; |
|
int64_t change; |
int64_t change; |
#endif |
#endif |
ip = VTOI(vp); |
ip = VTOI(vp); |
Line 615 ufs_chown(struct vnode *vp, uid_t uid, g |
|
Line 608 ufs_chown(struct vnode *vp, uid_t uid, g |
|
#ifdef QUOTA |
#ifdef QUOTA |
ogid = ip->i_gid; |
ogid = ip->i_gid; |
ouid = ip->i_uid; |
ouid = ip->i_uid; |
if ((error = getinoquota(ip)) != 0) |
|
return (error); |
|
if (ouid == uid) { |
|
dqrele(vp, ip->i_dquot[USRQUOTA]); |
|
ip->i_dquot[USRQUOTA] = NODQUOT; |
|
} |
|
if (ogid == gid) { |
|
dqrele(vp, ip->i_dquot[GRPQUOTA]); |
|
ip->i_dquot[GRPQUOTA] = NODQUOT; |
|
} |
|
change = DIP(ip, blocks); |
change = DIP(ip, blocks); |
(void) chkdq(ip, -change, cred, CHOWN); |
(void) chkdq(ip, -change, cred, 0); |
(void) chkiq(ip, -1, cred, CHOWN); |
(void) chkiq(ip, -1, cred, 0); |
for (i = 0; i < MAXQUOTAS; i++) { |
|
dqrele(vp, ip->i_dquot[i]); |
|
ip->i_dquot[i] = NODQUOT; |
|
} |
|
#endif |
#endif |
ip->i_gid = gid; |
ip->i_gid = gid; |
DIP_ASSIGN(ip, gid, gid); |
DIP_ASSIGN(ip, gid, gid); |
ip->i_uid = uid; |
ip->i_uid = uid; |
DIP_ASSIGN(ip, uid, uid); |
DIP_ASSIGN(ip, uid, uid); |
#ifdef QUOTA |
#ifdef QUOTA |
if ((error = getinoquota(ip)) == 0) { |
if ((error = chkdq(ip, change, cred, 0)) == 0) { |
if (ouid == uid) { |
if ((error = chkiq(ip, 1, cred, 0)) == 0) |
dqrele(vp, ip->i_dquot[USRQUOTA]); |
goto good; |
ip->i_dquot[USRQUOTA] = NODQUOT; |
else |
} |
(void) chkdq(ip, -change, cred, FORCE); |
if (ogid == gid) { |
|
dqrele(vp, ip->i_dquot[GRPQUOTA]); |
|
ip->i_dquot[GRPQUOTA] = NODQUOT; |
|
} |
|
if ((error = chkdq(ip, change, cred, CHOWN)) == 0) { |
|
if ((error = chkiq(ip, 1, cred, CHOWN)) == 0) |
|
goto good; |
|
else |
|
(void) chkdq(ip, -change, cred, CHOWN|FORCE); |
|
} |
|
for (i = 0; i < MAXQUOTAS; i++) { |
|
dqrele(vp, ip->i_dquot[i]); |
|
ip->i_dquot[i] = NODQUOT; |
|
} |
|
} |
} |
ip->i_gid = ogid; |
ip->i_gid = ogid; |
DIP_ASSIGN(ip, gid, ogid); |
DIP_ASSIGN(ip, gid, ogid); |
ip->i_uid = ouid; |
ip->i_uid = ouid; |
DIP_ASSIGN(ip, uid, ouid); |
DIP_ASSIGN(ip, uid, ouid); |
if (getinoquota(ip) == 0) { |
(void) chkdq(ip, change, cred, FORCE); |
if (ouid == uid) { |
(void) chkiq(ip, 1, cred, FORCE); |
dqrele(vp, ip->i_dquot[USRQUOTA]); |
|
ip->i_dquot[USRQUOTA] = NODQUOT; |
|
} |
|
if (ogid == gid) { |
|
dqrele(vp, ip->i_dquot[GRPQUOTA]); |
|
ip->i_dquot[GRPQUOTA] = NODQUOT; |
|
} |
|
(void) chkdq(ip, change, cred, FORCE|CHOWN); |
|
(void) chkiq(ip, 1, cred, FORCE|CHOWN); |
|
(void) getinoquota(ip); |
|
} |
|
return (error); |
return (error); |
good: |
good: |
if (getinoquota(ip)) |
|
panic("chown: lost quota"); |
|
#endif /* QUOTA */ |
#endif /* QUOTA */ |
ip->i_flag |= IN_CHANGE; |
ip->i_flag |= IN_CHANGE; |
return (0); |
return (0); |
Line 699 ufs_remove(void *v) |
|
Line 651 ufs_remove(void *v) |
|
vp = ap->a_vp; |
vp = ap->a_vp; |
dvp = ap->a_dvp; |
dvp = ap->a_dvp; |
ip = VTOI(vp); |
ip = VTOI(vp); |
if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
if (vp->v_type == VDIR || (ip->i_flags & (IMMUTABLE | APPEND)) || |
if (vp->v_type == VDIR || (ip->i_flags & (IMMUTABLE | APPEND)) || |
(VTOI(dvp)->i_flags & APPEND)) |
(VTOI(dvp)->i_flags & APPEND)) |
error = EPERM; |
error = EPERM; |
Line 741 ufs_link(void *v) |
|
Line 692 ufs_link(void *v) |
|
if ((cnp->cn_flags & HASBUF) == 0) |
if ((cnp->cn_flags & HASBUF) == 0) |
panic("ufs_link: no name"); |
panic("ufs_link: no name"); |
#endif |
#endif |
if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
if (vp->v_type == VDIR) { |
if (vp->v_type == VDIR) { |
VOP_ABORTOP(dvp, cnp); |
VOP_ABORTOP(dvp, cnp); |
error = EPERM; |
error = EPERM; |
Line 828 ufs_whiteout(void *v) |
|
Line 778 ufs_whiteout(void *v) |
|
|
|
case CREATE: |
case CREATE: |
/* create a new directory whiteout */ |
/* create a new directory whiteout */ |
if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if ((cnp->cn_flags & SAVENAME) == 0) |
if ((cnp->cn_flags & SAVENAME) == 0) |
panic("ufs_whiteout: missing name"); |
panic("ufs_whiteout: missing name"); |
Line 850 ufs_whiteout(void *v) |
|
Line 799 ufs_whiteout(void *v) |
|
|
|
case DELETE: |
case DELETE: |
/* remove an existing directory whiteout */ |
/* remove an existing directory whiteout */ |
if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (ump->um_maxsymlinklen <= 0) |
if (ump->um_maxsymlinklen <= 0) |
panic("ufs_whiteout: old format filesystem"); |
panic("ufs_whiteout: old format filesystem"); |
Line 1023 ufs_rename(void *v) |
|
Line 971 ufs_rename(void *v) |
|
xp = VTOI(tvp); |
xp = VTOI(tvp); |
|
|
mp = fdvp->v_mount; |
mp = fdvp->v_mount; |
if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0) |
fstrans_start(mp, FSTRANS_SHARED); |
return error; |
|
|
|
/* |
/* |
* 1) Bump link count while we're moving stuff |
* 1) Bump link count while we're moving stuff |
Line 1332 ufs_mkdir(void *v) |
|
Line 1279 ufs_mkdir(void *v) |
|
struct ufsmount *ump = dp->i_ump; |
struct ufsmount *ump = dp->i_ump; |
int dirblksiz = ump->um_dirblksiz; |
int dirblksiz = ump->um_dirblksiz; |
|
|
if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if ((cnp->cn_flags & HASBUF) == 0) |
if ((cnp->cn_flags & HASBUF) == 0) |
Line 1359 ufs_mkdir(void *v) |
|
Line 1305 ufs_mkdir(void *v) |
|
ip->i_gid = dp->i_gid; |
ip->i_gid = dp->i_gid; |
DIP_ASSIGN(ip, gid, ip->i_gid); |
DIP_ASSIGN(ip, gid, ip->i_gid); |
#ifdef QUOTA |
#ifdef QUOTA |
if ((error = getinoquota(ip)) || |
if ((error = chkiq(ip, 1, cnp->cn_cred, 0))) { |
(error = chkiq(ip, 1, cnp->cn_cred, 0))) { |
|
PNBUF_PUT(cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
UFS_VFREE(tvp, ip->i_number, dmode); |
UFS_VFREE(tvp, ip->i_number, dmode); |
fstrans_done(dvp->v_mount); |
fstrans_done(dvp->v_mount); |
Line 1428 ufs_mkdir(void *v) |
|
Line 1373 ufs_mkdir(void *v) |
|
DIP_ASSIGN(ip, size, dirblksiz); |
DIP_ASSIGN(ip, size, dirblksiz); |
ip->i_flag |= IN_CHANGE | IN_UPDATE; |
ip->i_flag |= IN_CHANGE | IN_UPDATE; |
uvm_vnp_setsize(tvp, ip->i_size); |
uvm_vnp_setsize(tvp, ip->i_size); |
memcpy((caddr_t)bp->b_data, (caddr_t)&dirtemplate, sizeof dirtemplate); |
memcpy((void *)bp->b_data, (void *)&dirtemplate, sizeof dirtemplate); |
if (DOINGSOFTDEP(tvp)) { |
if (DOINGSOFTDEP(tvp)) { |
/* |
/* |
* Ensure that the entire newly allocated block is a |
* Ensure that the entire newly allocated block is a |
Line 1439 ufs_mkdir(void *v) |
|
Line 1384 ufs_mkdir(void *v) |
|
blkoff = dirblksiz; |
blkoff = dirblksiz; |
while (blkoff < bp->b_bcount) { |
while (blkoff < bp->b_bcount) { |
((struct direct *) |
((struct direct *) |
(bp->b_data + blkoff))->d_reclen = dirblksiz; |
((char *)bp->b_data + blkoff))->d_reclen = dirblksiz; |
blkoff += dirblksiz; |
blkoff += dirblksiz; |
} |
} |
} |
} |
Line 1531 ufs_rmdir(void *v) |
|
Line 1476 ufs_rmdir(void *v) |
|
return (EINVAL); |
return (EINVAL); |
} |
} |
|
|
if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
|
|
/* |
/* |
* Do not remove a directory that is in the process of being renamed. |
* Do not remove a directory that is in the process of being renamed. |
Line 1628 ufs_symlink(void *v) |
|
Line 1572 ufs_symlink(void *v) |
|
int len, error; |
int len, error; |
|
|
vpp = ap->a_vpp; |
vpp = ap->a_vpp; |
if ((error = fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED)) != 0) |
fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); |
return error; |
|
error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, |
error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, |
vpp, ap->a_cnp); |
vpp, ap->a_cnp); |
if (error) |
if (error) |
Line 1854 ufs_strategy(void *v) |
|
Line 1797 ufs_strategy(void *v) |
|
NULL); |
NULL); |
if (error) { |
if (error) { |
bp->b_error = error; |
bp->b_error = error; |
bp->b_flags |= B_ERROR; |
|
biodone(bp); |
biodone(bp); |
return (error); |
return (error); |
} |
} |
Line 2083 ufs_advlock(void *v) |
|
Line 2025 ufs_advlock(void *v) |
|
{ |
{ |
struct vop_advlock_args /* { |
struct vop_advlock_args /* { |
struct vnode *a_vp; |
struct vnode *a_vp; |
caddr_t a_id; |
void * a_id; |
int a_op; |
int a_op; |
struct flock *a_fl; |
struct flock *a_fl; |
int a_flags; |
int a_flags; |
Line 2195 ufs_makeinode(int mode, struct vnode *dv |
|
Line 2137 ufs_makeinode(int mode, struct vnode *dv |
|
ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); |
ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); |
DIP_ASSIGN(ip, uid, ip->i_uid); |
DIP_ASSIGN(ip, uid, ip->i_uid); |
#ifdef QUOTA |
#ifdef QUOTA |
if ((error = getinoquota(ip)) || |
if ((error = chkiq(ip, 1, cnp->cn_cred, 0))) { |
(error = chkiq(ip, 1, cnp->cn_cred, 0))) { |
|
UFS_VFREE(tvp, ip->i_number, mode); |
UFS_VFREE(tvp, ip->i_number, mode); |
vput(tvp); |
vput(tvp); |
PNBUF_PUT(cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
Line 2332 ufs_gop_markupdate(struct vnode *vp, int |
|
Line 2273 ufs_gop_markupdate(struct vnode *vp, int |
|
ip->i_flag |= mask; |
ip->i_flag |= mask; |
} |
} |
} |
} |
|
|
/* |
|
* Lock the node. |
|
*/ |
|
int |
|
ufs_lock(void *v) |
|
{ |
|
struct vop_lock_args /* { |
|
struct vnode *a_vp; |
|
int a_flags; |
|
} */ *ap = v; |
|
struct vnode *vp = ap->a_vp; |
|
struct mount *mp = vp->v_mount; |
|
|
|
/* |
|
* Fake lock during file system suspension. |
|
*/ |
|
if ((vp->v_type == VREG || vp->v_type == VDIR) && |
|
fstrans_is_owner(mp) && |
|
fstrans_getstate(mp) == FSTRANS_SUSPENDING) { |
|
if ((ap->a_flags & LK_INTERLOCK) != 0) |
|
simple_unlock(&vp->v_interlock); |
|
return 0; |
|
} |
|
return (lockmgr(vp->v_vnlock, ap->a_flags, &vp->v_interlock)); |
|
} |
|
|
|
/* |
|
* Unlock the node. |
|
*/ |
|
int |
|
ufs_unlock(void *v) |
|
{ |
|
struct vop_unlock_args /* { |
|
struct vnode *a_vp; |
|
int a_flags; |
|
} */ *ap = v; |
|
struct vnode *vp = ap->a_vp; |
|
struct mount *mp = vp->v_mount; |
|
|
|
/* |
|
* Fake unlock during file system suspension. |
|
*/ |
|
if ((vp->v_type == VREG || vp->v_type == VDIR) && |
|
fstrans_is_owner(mp) && |
|
fstrans_getstate(mp) == FSTRANS_SUSPENDING) { |
|
if ((ap->a_flags & LK_INTERLOCK) != 0) |
|
simple_unlock(&vp->v_interlock); |
|
return 0; |
|
} |
|
return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, |
|
&vp->v_interlock)); |
|
} |
|
|
|
/* |
|
* Return whether or not the node is locked. |
|
*/ |
|
int |
|
ufs_islocked(void *v) |
|
{ |
|
struct vop_islocked_args /* { |
|
struct vnode *a_vp; |
|
} */ *ap = v; |
|
struct vnode *vp = ap->a_vp; |
|
|
|
return (lockstatus(vp->v_vnlock)); |
|
} |
|