Re: [PATCH 11/12] locks: break delegations on link

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed,  3 Jul 2013 16:12:35 -0400
"J. Bruce Fields" <bfields@xxxxxxxxxx> wrote:

> From: "J. Bruce Fields" <bfields@xxxxxxxxxx>
> 
> Cc: Tyler Hicks <tyhicks@xxxxxxxxxxxxx>
> Cc: Dustin Kirkland <dustin.kirkland@xxxxxxxxxxx>
> Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxx>
> ---
>  fs/ecryptfs/inode.c |    2 +-
>  fs/namei.c          |   17 +++++++++++++----
>  fs/nfsd/vfs.c       |    2 +-
>  include/linux/fs.h  |    2 +-
>  4 files changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
> index af42d88..19e4435 100644
> --- a/fs/ecryptfs/inode.c
> +++ b/fs/ecryptfs/inode.c
> @@ -475,7 +475,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
>  	dget(lower_new_dentry);
>  	lower_dir_dentry = lock_parent(lower_new_dentry);
>  	rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
> -		      lower_new_dentry);
> +		      lower_new_dentry, NULL);
>  	if (rc || !lower_new_dentry->d_inode)
>  		goto out_lock;
>  	rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
> diff --git a/fs/namei.c b/fs/namei.c
> index be00d37..18267e0 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3566,7 +3566,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newn
>  	return sys_symlinkat(oldname, AT_FDCWD, newname);
>  }
>  
> -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
> +int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode)

A kerneldoc comment would be nice here. Ditto for vfs_rename* in the
previous patch...

>  {
>  	struct inode *inode = old_dentry->d_inode;
>  	unsigned max_links = dir->i_sb->s_max_links;
> @@ -3602,8 +3602,11 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
>  		error =  -ENOENT;
>  	else if (max_links && inode->i_nlink >= max_links)
>  		error = -EMLINK;
> -	else
> -		error = dir->i_op->link(old_dentry, dir, new_dentry);
> +	else {
> +		error = try_break_deleg(inode, delegated_inode);
> +		if (!error)
> +			error = dir->i_op->link(old_dentry, dir, new_dentry);
> +	}
>  	mutex_unlock(&inode->i_mutex);
>  	if (!error)
>  		fsnotify_link(dir, inode, new_dentry);
> @@ -3624,6 +3627,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
>  {
>  	struct dentry *new_dentry;
>  	struct path old_path, new_path;
> +	struct inode *delegated_inode = NULL;
>  	int how = 0;
>  	int error;
>  
> @@ -3662,9 +3666,14 @@ retry:
>  	error = security_path_link(old_path.dentry, &new_path, new_dentry);
>  	if (error)
>  		goto out_dput;
> -	error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry);
> +	error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode);
>  out_dput:
>  	done_path_create(&new_path, new_dentry);
> +	if (delegated_inode) {
> +		error = break_deleg_wait(&delegated_inode);
> +		if (!error)
> +			goto retry;
> +	}
>  	if (retry_estale(error, how)) {
>  		how |= LOOKUP_REVAL;
>  		goto retry;
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index 54ac814..b9740cb 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -1708,7 +1708,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
>  		err = nfserrno(host_err);
>  		goto out_dput;
>  	}
> -	host_err = vfs_link(dold, dirp, dnew);
> +	host_err = vfs_link(dold, dirp, dnew, NULL);
>  	if (!host_err) {
>  		err = nfserrno(commit_metadata(ffhp));
>  		if (!err)
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index a35dadb..936413c 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1461,7 +1461,7 @@ extern int vfs_create(struct inode *, struct dentry *, umode_t, bool);
>  extern int vfs_mkdir(struct inode *, struct dentry *, umode_t);
>  extern int vfs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
>  extern int vfs_symlink(struct inode *, struct dentry *, const char *);
> -extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
> +extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **);
>  extern int vfs_rmdir(struct inode *, struct dentry *);
>  extern int vfs_unlink(struct inode *, struct dentry *, struct inode **);
>  extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **);

Acked-by: Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux