Commit 75c3f29d authored by Dave Hansen's avatar Dave Hansen Committed by Al Viro
Browse files

[PATCH] r/o bind mounts: write counts for link/symlink



[AV: add missing nfsd pieces]

Acked-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDave Hansen <haveblue@us.ibm.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 463c3197
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -2387,7 +2387,12 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
	if (IS_ERR(dentry))
		goto out_unlock;

	error = mnt_want_write(nd.path.mnt);
	if (error)
		goto out_dput;
	error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
	mnt_drop_write(nd.path.mnt);
out_dput:
	dput(dentry);
out_unlock:
	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
@@ -2482,7 +2487,12 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
	error = PTR_ERR(new_dentry);
	if (IS_ERR(new_dentry))
		goto out_unlock;
	error = mnt_want_write(nd.path.mnt);
	if (error)
		goto out_dput;
	error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
	mnt_drop_write(nd.path.mnt);
out_dput:
	dput(new_dentry);
out_unlock:
	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+13 −1
Original line number Diff line number Diff line
@@ -1542,6 +1542,10 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
	if (iap && (iap->ia_valid & ATTR_MODE))
		mode = iap->ia_mode & S_IALLUGO;

	host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
	if (host_err)
		goto out_nfserr;

	if (unlikely(path[plen] != 0)) {
		char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
		if (path_alloced == NULL)
@@ -1562,6 +1566,8 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
	err = nfserrno(host_err);
	fh_unlock(fhp);

	mnt_drop_write(fhp->fh_export->ex_path.mnt);

	cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
	dput(dnew);
	if (err==0) err = cerr;
@@ -1612,6 +1618,11 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
	dold = tfhp->fh_dentry;
	dest = dold->d_inode;

	host_err = mnt_want_write(tfhp->fh_export->ex_path.mnt);
	if (host_err) {
		err = nfserrno(host_err);
		goto out_dput;
	}
	host_err = vfs_link(dold, dirp, dnew);
	if (!host_err) {
		if (EX_ISSYNC(ffhp->fh_export)) {
@@ -1625,7 +1636,8 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
		else
			err = nfserrno(host_err);
	}

	mnt_drop_write(tfhp->fh_export->ex_path.mnt);
out_dput:
	dput(dnew);
out_unlock:
	fh_unlock(ffhp);