version 1.59, 2008/03/21 21:55:01 |
version 1.59.4.6, 2010/08/11 22:55:15 |
Line 41 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 41 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/kernel.h> |
#include <sys/kernel.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/namei.h> |
#include <sys/namei.h> |
#include <sys/malloc.h> |
|
#include <sys/file.h> |
#include <sys/file.h> |
#include <sys/proc.h> |
#include <sys/proc.h> |
#include <sys/vnode.h> |
#include <sys/vnode.h> |
Line 222 chkdq(struct inode *ip, int64_t change, |
|
Line 221 chkdq(struct inode *ip, int64_t change, |
|
return (0); |
return (0); |
} |
} |
if ((flags & FORCE) == 0 && |
if ((flags & FORCE) == 0 && |
kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0) { |
kauth_authorize_system(cred, KAUTH_SYSTEM_FS_QUOTA, |
|
KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, NULL, NULL, NULL) != 0) { |
for (i = 0; i < MAXQUOTAS; i++) { |
for (i = 0; i < MAXQUOTAS; i++) { |
if ((dq = ip->i_dquot[i]) == NODQUOT) |
if ((dq = ip->i_dquot[i]) == NODQUOT) |
continue; |
continue; |
Line 326 chkiq(struct inode *ip, int32_t change, |
|
Line 326 chkiq(struct inode *ip, int32_t change, |
|
} |
} |
return (0); |
return (0); |
} |
} |
if ((flags & FORCE) == 0 && kauth_authorize_generic(cred, |
if ((flags & FORCE) == 0 && kauth_authorize_system(cred, |
KAUTH_GENERIC_ISSUSER, NULL) != 0) { |
KAUTH_SYSTEM_FS_QUOTA, KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, NULL, |
|
NULL, NULL) != 0) { |
for (i = 0; i < MAXQUOTAS; i++) { |
for (i = 0; i < MAXQUOTAS; i++) { |
if ((dq = ip->i_dquot[i]) == NODQUOT) |
if ((dq = ip->i_dquot[i]) == NODQUOT) |
continue; |
continue; |
Line 417 quotaon(struct lwp *l, struct mount *mp, |
|
Line 418 quotaon(struct lwp *l, struct mount *mp, |
|
int error; |
int error; |
struct nameidata nd; |
struct nameidata nd; |
|
|
|
/* XXX XXX XXX */ |
|
if (mp->mnt_wapbl != NULL) { |
|
printf("%s: quotas cannot yet be used with -o log\n", |
|
mp->mnt_stat.f_mntonname); |
|
return (EOPNOTSUPP); |
|
} |
|
|
vpp = &ump->um_quotas[type]; |
vpp = &ump->um_quotas[type]; |
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname); |
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname); |
if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) |
if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) |
return (error); |
return (error); |
vp = nd.ni_vp; |
vp = nd.ni_vp; |
VOP_UNLOCK(vp, 0); |
VOP_UNLOCK(vp); |
if (vp->v_type != VREG) { |
if (vp->v_type != VREG) { |
(void) vn_close(vp, FREAD|FWRITE, l->l_cred); |
(void) vn_close(vp, FREAD|FWRITE, l->l_cred); |
return (EACCES); |
return (EACCES); |
|
|
for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { |
for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { |
vmark(mvp, vp); |
vmark(mvp, vp); |
mutex_enter(&vp->v_interlock); |
mutex_enter(&vp->v_interlock); |
if (vp->v_mount != mp || vismarker(vp) || |
if (VTOI(vp) == NULL || vp->v_mount != mp || vismarker(vp) || |
vp->v_type == VNON || vp->v_writecount == 0 || |
vp->v_type == VNON || vp->v_writecount == 0 || |
(vp->v_iflag & VI_CLEAN) != 0) { |
(vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) { |
mutex_exit(&vp->v_interlock); |
mutex_exit(&vp->v_interlock); |
continue; |
continue; |
} |
} |
mutex_exit(&mntvnode_lock); |
mutex_exit(&mntvnode_lock); |
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) { |
if (vget(vp, LK_EXCLUSIVE)) { |
mutex_enter(&mntvnode_lock); |
mutex_enter(&mntvnode_lock); |
(void)vunmark(mvp); |
(void)vunmark(mvp); |
goto again; |
goto again; |
|
|
for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { |
for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { |
vmark(mvp, vp); |
vmark(mvp, vp); |
mutex_enter(&vp->v_interlock); |
mutex_enter(&vp->v_interlock); |
if (vp->v_mount != mp || vismarker(vp) || vp->v_type == VNON || |
if (VTOI(vp) == NULL || vp->v_mount != mp || vismarker(vp) || |
(vp->v_iflag & VI_CLEAN) != 0) { |
vp->v_type == VNON || |
|
(vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) { |
mutex_exit(&vp->v_interlock); |
mutex_exit(&vp->v_interlock); |
continue; |
continue; |
} |
} |
mutex_exit(&mntvnode_lock); |
mutex_exit(&mntvnode_lock); |
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) { |
if (vget(vp, LK_EXCLUSIVE)) { |
mutex_enter(&mntvnode_lock); |
mutex_enter(&mntvnode_lock); |
(void)vunmark(mvp); |
(void)vunmark(mvp); |
goto again; |
goto again; |
Line 722 qsync(struct mount *mp) |
|
Line 731 qsync(struct mount *mp) |
|
for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { |
for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { |
vmark(mvp, vp); |
vmark(mvp, vp); |
mutex_enter(&vp->v_interlock); |
mutex_enter(&vp->v_interlock); |
if (vp->v_mount != mp || vismarker(vp) || vp->v_type == VNON || |
if (VTOI(vp) == NULL || vp->v_mount != mp || vismarker(vp) || |
(vp->v_iflag & VI_CLEAN) != 0) { |
vp->v_type == VNON || |
|
(vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) { |
mutex_exit(&vp->v_interlock); |
mutex_exit(&vp->v_interlock); |
continue; |
continue; |
} |
} |
mutex_exit(&mntvnode_lock); |
mutex_exit(&mntvnode_lock); |
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK); |
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT); |
if (error) { |
if (error) { |
mutex_enter(&mntvnode_lock); |
mutex_enter(&mntvnode_lock); |
if (error == ENOENT) { |
if (error == ENOENT) { |
Line 763 static LIST_HEAD(dqhashhead, dquot) *dqh |
|
Line 773 static LIST_HEAD(dqhashhead, dquot) *dqh |
|
static u_long dqhash; |
static u_long dqhash; |
static pool_cache_t dquot_cache; |
static pool_cache_t dquot_cache; |
|
|
MALLOC_JUSTDEFINE(M_DQUOT, "UFS quota", "UFS quota entries"); |
|
|
|
/* |
/* |
* Initialize the quota system. |
* Initialize the quota system. |
*/ |
*/ |
|
|
|
|
mutex_init(&dqlock, MUTEX_DEFAULT, IPL_NONE); |
mutex_init(&dqlock, MUTEX_DEFAULT, IPL_NONE); |
cv_init(&dqcv, "quota"); |
cv_init(&dqcv, "quota"); |
malloc_type_attach(M_DQUOT); |
dqhashtbl = hashinit(desiredvnodes, HASH_LIST, true, &dqhash); |
dqhashtbl = |
|
hashinit(desiredvnodes, HASH_LIST, M_DQUOT, M_WAITOK, &dqhash); |
|
dquot_cache = pool_cache_init(sizeof(struct dquot), 0, 0, 0, "ufsdq", |
dquot_cache = pool_cache_init(sizeof(struct dquot), 0, 0, 0, "ufsdq", |
NULL, IPL_NONE, NULL, NULL, NULL); |
NULL, IPL_NONE, NULL, NULL, NULL); |
} |
} |
|
|
u_long oldmask, mask, hashval; |
u_long oldmask, mask, hashval; |
int i; |
int i; |
|
|
hash = hashinit(desiredvnodes, HASH_LIST, M_DQUOT, M_WAITOK, &mask); |
hash = hashinit(desiredvnodes, HASH_LIST, true, &mask); |
mutex_enter(&dqlock); |
mutex_enter(&dqlock); |
oldhash = dqhashtbl; |
oldhash = dqhashtbl; |
oldmask = dqhash; |
oldmask = dqhash; |
|
|
} |
} |
} |
} |
mutex_exit(&dqlock); |
mutex_exit(&dqlock); |
hashdone(oldhash, M_DQUOT); |
hashdone(oldhash, HASH_LIST, oldmask); |
} |
} |
|
|
/* |
/* |
|
|
{ |
{ |
|
|
pool_cache_destroy(dquot_cache); |
pool_cache_destroy(dquot_cache); |
hashdone(dqhashtbl, M_DQUOT); |
hashdone(dqhashtbl, HASH_LIST, dqhash); |
malloc_type_detach(M_DQUOT); |
|
cv_destroy(&dqcv); |
cv_destroy(&dqcv); |
mutex_destroy(&dqlock); |
mutex_destroy(&dqlock); |
} |
} |
Line 886 dqget(struct vnode *vp, u_long id, struc |
|
Line 891 dqget(struct vnode *vp, u_long id, struc |
|
KASSERT(dq->dq_cnt > 0); |
KASSERT(dq->dq_cnt > 0); |
dqref(dq); |
dqref(dq); |
mutex_exit(&dqlock); |
mutex_exit(&dqlock); |
|
mutex_destroy(&ndq->dq_interlock); |
pool_cache_put(dquot_cache, ndq); |
pool_cache_put(dquot_cache, ndq); |
*dqp = dq; |
*dqp = dq; |
return 0; |
return 0; |
Line 907 dqget(struct vnode *vp, u_long id, struc |
|
Line 913 dqget(struct vnode *vp, u_long id, struc |
|
error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]); |
error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]); |
if (auio.uio_resid == sizeof(struct dqblk) && error == 0) |
if (auio.uio_resid == sizeof(struct dqblk) && error == 0) |
memset((void *)&dq->dq_dqb, 0, sizeof(struct dqblk)); |
memset((void *)&dq->dq_dqb, 0, sizeof(struct dqblk)); |
VOP_UNLOCK(dqvp, 0); |
VOP_UNLOCK(dqvp); |
/* |
/* |
* I/O error in reading quota file, release |
* I/O error in reading quota file, release |
* quota structure and reflect problem to caller. |
* quota structure and reflect problem to caller. |
Line 1014 dqsync(struct vnode *vp, struct dquot *d |
|
Line 1020 dqsync(struct vnode *vp, struct dquot *d |
|
if (auio.uio_resid && error == 0) |
if (auio.uio_resid && error == 0) |
error = EIO; |
error = EIO; |
dq->dq_flags &= ~DQ_MOD; |
dq->dq_flags &= ~DQ_MOD; |
VOP_UNLOCK(dqvp, 0); |
VOP_UNLOCK(dqvp); |
return (error); |
return (error); |
} |
} |
|
|