Commit e5d74a2d authored by Yu Hsiang Huang's avatar Yu Hsiang Huang Committed by J. Bruce Fields
Browse files

nfsd: Prevent truncation of an unlinked inode from blocking access to its directory



Truncation of an unlinked inode may take a long time for I/O waiting, and
it doesn't have to prevent access to the directory. Thus, let truncation
occur outside the directory's mutex, just like do_unlinkat() does.

Signed-off-by: default avatarYu Hsiang Huang <nickhuang@synology.com>
Signed-off-by: default avatarBing Jing Chang <bingjingc@synology.com>
Signed-off-by: default avatarRobbie Ko <robbieko@synology.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent d6cbe98f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1859,6 +1859,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
{
	struct dentry	*dentry, *rdentry;
	struct inode	*dirp;
	struct inode	*rinode;
	__be32		err;
	int		host_err;

@@ -1887,6 +1888,8 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
		host_err = -ENOENT;
		goto out_drop_write;
	}
	rinode = d_inode(rdentry);
	ihold(rinode);

	if (!type)
		type = d_inode(rdentry)->i_mode & S_IFMT;
@@ -1902,6 +1905,8 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
	if (!host_err)
		host_err = commit_metadata(fhp);
	dput(rdentry);
	fh_unlock(fhp);
	iput(rinode);    /* truncate the inode here */

out_drop_write:
	fh_drop_write(fhp);