[linux-cifs-client] F_GETLK request - returning value
diff mbox

Message ID 200903282051.08380.piastry@etersoft.ru
State New, archived
Headers show

Commit Message

Pavel Shilovsky March 28, 2009, 5:51 p.m. UTC
Sorry, my e-mail client broke patch.
This is correct one.

Comments

Jeff Layton March 29, 2009, 11:05 a.m. UTC | #1
On Sat, 28 Mar 2009 20:51:08 +0300
Pavel Shilovsky <piastry@etersoft.ru> wrote:

> Sorry, my e-mail client broke patch.
> This is correct one.
> 
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 8f0f86d..aa26a3a 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -1882,6 +1882,16 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
>                         ((char *)&pSMBr->hdr.Protocol + data_offset);
>                 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
>                         pLockData->fl_type = F_UNLCK;
> +               else {
> +                       if (parm_data->lock_type == cpu_to_le16(CIFS_RDLCK))
> +                               pLockData->fl_type = F_RDLCK;
> +                       else if (parm_data->lock_type == cpu_to_le16(CIFS_WRLCK))
> +                               pLockData->fl_type = F_WRLCK;
> +

Minor nit: the cpu_to_le16 calls here should probably be
__constant_cpu_to_le16 (including the CIFS_UNLCK one).

> +                       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 6851043..92474f0 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -896,8 +896,28 @@ 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, pTcon, netfid, length, pfLock->fl_start,
> +                                        0, 1, lockType | LOCKING_ANDX_SHARED_LOCK, 0 /* wait flag */ );
> +                               if (rc == 0) {
> +                                       rc = CIFSSMBLock(xid, pTcon, netfid, length,
> +                                                pfLock->fl_start, 1 /* numUnlock */ ,
> +                                                0 /* numLock */ , 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;
> +                               }
> +                       }
>                 }
> 

It would be nice if these checks were less invasive, but I guess we're
constrained by the CIFS protocol here. Looks fine to me, though to be
consistent with kernel coding style you should try to keep the code
within 80 columns.

Patch
diff mbox

diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 8f0f86d..aa26a3a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1882,6 +1882,16 @@  CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                        ((char *)&pSMBr->hdr.Protocol + data_offset);
                if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
                        pLockData->fl_type = F_UNLCK;
+               else {
+                       if (parm_data->lock_type == cpu_to_le16(CIFS_RDLCK))
+                               pLockData->fl_type = F_RDLCK;
+                       else if (parm_data->lock_type == 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 6851043..92474f0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -896,8 +896,28 @@  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, pTcon, netfid, length, pfLock->fl_start,
+                                        0, 1, lockType | LOCKING_ANDX_SHARED_LOCK, 0 /* wait flag */ );
+                               if (rc == 0) {
+                                       rc = CIFSSMBLock(xid, pTcon, netfid, length,
+                                                pfLock->fl_start, 1 /* numUnlock */ ,
+                                                0 /* numLock */ , 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;
+                               }
+                       }
                }

Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com>