Re: [PATCH] not overwriting file_lock structure after GET_LK

Jeff Layton <[email protected]>
Newsgroups gmane.linux.file-systems.cifs
Message-ID <[email protected]>
On Mon, 5 Apr 2010 09:59:14 +0400
[email protected] wrote:

> From: Pavel Shilovsky <[email protected]>
> 
> If we have preventing lock, cifs should overwrite file_lock structure
> with info about preventing lock. If we haven't preventing lock, cifs
> should leave it unchanged except for the lock type (change it to F_UNLCK).
> 
> Signed-off-by: Pavel Shilovsky <[email protected]>
> Reviewed-by: Jeff Layton <[email protected]>
> ---
>  fs/cifs/cifssmb.c |   15 ++++++++++++++-
>  fs/cifs/file.c    |   28 ++++++++++++++++++++++++++--
>  2 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 7cc7f83..b3bbb2b 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -1793,8 +1793,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
>  		}
>  		parm_data = (struct cifs_posix_lock *)
>  			((char *)&pSMBr->hdr.Protocol + data_offset);
> -		if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
> +		if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
>  			pLockData->fl_type = F_UNLCK;
> +		else {
> +			if (parm_data->lock_type ==
> +					__constant_cpu_to_le16(CIFS_RDLCK))
> +				pLockData->fl_type = F_RDLCK;
> +			else if (parm_data->lock_type ==
> +					__constant_cpu_to_le16(CIFS_WRLCK))
> +				pLockData->fl_type = F_WRLCK;
> +
> +			pLockData->fl_start = parm_data->start;
> +			pLockData->fl_end = parm_data->start +
> +						parm_data->length - 1;
> +			pLockData->fl_pid = parm_data->pid;
> +		}
>  	}
>  
>  plk_err_exit:
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index ca2ba7a..d9e8650 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -838,8 +838,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
>  
>  		} else {
>  			/* if rc == ERR_SHARING_VIOLATION ? */
> -			rc = 0;	/* do not change lock type to unlock
> -				   since range in use */
> +			rc = 0;
> +
> +			if (lockType & LOCKING_ANDX_SHARED_LOCK) {
> +				pfLock->fl_type = F_WRLCK;
> +			} else {
> +				rc = CIFSSMBLock(xid, tcon, netfid, length,
> +					pfLock->fl_start, 0, 1,
> +					lockType | LOCKING_ANDX_SHARED_LOCK,
> +					0 /* wait flag */);
> +				if (rc == 0) {
> +					rc = CIFSSMBLock(xid, tcon, netfid,
> +						length, pfLock->fl_start, 1, 0,
> +						lockType |
> +						LOCKING_ANDX_SHARED_LOCK,
> +						0 /* wait flag */);
> +					pfLock->fl_type = F_RDLCK;
> +					if (rc != 0)
> +						cERROR(1, ("Error unlocking "
> +						"previously locked range %d "
> +						"during test of lock", rc));
> +					rc = 0;
> +				} else {
> +					pfLock->fl_type = F_WRLCK;
> +					rc = 0;
> +				}
> +			}
>  		}
>  
>  		FreeXid(xid);

Looks good -- thanks for sticking with this.

Reviewed-by: Jeff Layton <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.