NFSD: fix regression with setting ACLs.
[ Upstream commit 00801cd92d91e94aa04d687f9bb9a9104e7c3d46 ]
A recent patch moved ACL setting into nfsd_setattr().
Unfortunately it didn't work as nfsd_setattr() aborts early if
iap->ia_valid is 0.
Remove this test, and instead avoid calling notify_change() when
ia_valid is 0.
This means that nfsd_setattr() will now *always* lock the inode.
Previously it didn't if only a ATTR_MODE change was requested on a
symlink (see Commit 15b7a1b86d
("[PATCH] knfsd: fix setattr-on-symlink
error return")). I don't think this change really matters.
Fixes: c0cbe70742f4 ("NFSD: add posix ACLs to struct nfsd_attrs")
Signed-off-by: NeilBrown <neilb@suse.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
[ cel: backported to 5.10.y, prior to idmapped mounts ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
1f87122d34
commit
c7d320e620
@@ -299,6 +299,10 @@ commit_metadata(struct svc_fh *fhp)
|
|||||||
static void
|
static void
|
||||||
nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
|
nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
|
||||||
{
|
{
|
||||||
|
/* Ignore mode updates on symlinks */
|
||||||
|
if (S_ISLNK(inode->i_mode))
|
||||||
|
iap->ia_valid &= ~ATTR_MODE;
|
||||||
|
|
||||||
/* sanitize the mode change */
|
/* sanitize the mode change */
|
||||||
if (iap->ia_valid & ATTR_MODE) {
|
if (iap->ia_valid & ATTR_MODE) {
|
||||||
iap->ia_mode &= S_IALLUGO;
|
iap->ia_mode &= S_IALLUGO;
|
||||||
@@ -366,7 +370,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||||||
int accmode = NFSD_MAY_SATTR;
|
int accmode = NFSD_MAY_SATTR;
|
||||||
umode_t ftype = 0;
|
umode_t ftype = 0;
|
||||||
__be32 err;
|
__be32 err;
|
||||||
int host_err;
|
int host_err = 0;
|
||||||
bool get_write_count;
|
bool get_write_count;
|
||||||
bool size_change = (iap->ia_valid & ATTR_SIZE);
|
bool size_change = (iap->ia_valid & ATTR_SIZE);
|
||||||
|
|
||||||
@@ -404,13 +408,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||||||
dentry = fhp->fh_dentry;
|
dentry = fhp->fh_dentry;
|
||||||
inode = d_inode(dentry);
|
inode = d_inode(dentry);
|
||||||
|
|
||||||
/* Ignore any mode updates on symlinks */
|
|
||||||
if (S_ISLNK(inode->i_mode))
|
|
||||||
iap->ia_valid &= ~ATTR_MODE;
|
|
||||||
|
|
||||||
if (!iap->ia_valid)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
nfsd_sanitize_attrs(inode, iap);
|
nfsd_sanitize_attrs(inode, iap);
|
||||||
|
|
||||||
if (check_guard && guardtime != inode->i_ctime.tv_sec)
|
if (check_guard && guardtime != inode->i_ctime.tv_sec)
|
||||||
@@ -461,8 +458,10 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
iap->ia_valid |= ATTR_CTIME;
|
if (iap->ia_valid) {
|
||||||
host_err = notify_change(dentry, iap, NULL);
|
iap->ia_valid |= ATTR_CTIME;
|
||||||
|
host_err = notify_change(dentry, iap, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
if (attr->na_seclabel && attr->na_seclabel->len)
|
if (attr->na_seclabel && attr->na_seclabel->len)
|
||||||
|
Reference in New Issue
Block a user