Revert the r167541: "Remove unneeded getinoquota() call in the

ufs_access()." The call to getinoquota in ufs_access() serves the
purpose of instantiating inode dquot from the vn_open(). Since quotas
are accounted only for the inodes with already attached dquot, removal
of the call prevented opened inodes from participation in the quota
calculations.

Since ufs_access() may be called with the vnode being only shared
locked, upgrade (and then downgrade) vnode lock if calling
getinoquota().

Reported by:	simon at optinet com
In collaboration with:	pho
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2008-08-24 17:24:22 +00:00
parent bdebc2daa5
commit 689eae1d90
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182111

View File

@ -309,7 +309,7 @@ ufs_access(ap)
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
mode_t mode = ap->a_mode;
int error;
int error, relocked;
#ifdef UFS_ACL
struct acl *acl;
#endif
@ -326,6 +326,28 @@ ufs_access(ap)
case VREG:
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
#ifdef QUOTA
if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
relocked = 1;
vhold(vp);
vn_lock(vp, LK_UPGRADE | LK_RETRY);
VI_LOCK(vp);
vdropl(vp);
if (vp->v_iflag & VI_DOOMED) {
VI_UNLOCK(vp);
error = ENOENT;
goto relock;
}
VI_UNLOCK(vp);
} else
relocked = 0;
error = getinoquota(ip);
relock:
if (relocked)
vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
if (error != 0)
return (error);
#endif
break;
default:
break;