@@ -1303,51 +1303,55 @@ cifs_push_locks(struct cifsFileInfo *cfile)
return rc;
}
-static void
-cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock,
- bool *wait_flag, struct TCP_Server_Info *server)
+static int cifs_read_flock(struct file_lock *flock, __u32 *type, bool *lock,
+ bool *wait_flag, struct TCP_Server_Info *server)
{
+ unsigned int flags = FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS |
+ FL_LEASE | FL_CLOSE;
+
+ if (flock->fl_flags & ~flags) {
+ cifs_dbg(FYI, "Unknown lock flags 0x%x\n", flock->fl_flags);
+ return -EOPNOTSUPP;
+ }
+
+#ifdef CONFIG_CIFS_DEBUG2
if (flock->fl_flags & FL_POSIX)
cifs_dbg(FYI, "Posix\n");
if (flock->fl_flags & FL_FLOCK)
cifs_dbg(FYI, "Flock\n");
- if (flock->fl_flags & FL_SLEEP) {
- cifs_dbg(FYI, "Blocking lock\n");
- *wait_flag = true;
- }
if (flock->fl_flags & FL_ACCESS)
cifs_dbg(FYI, "Process suspended by mandatory locking - not implemented yet\n");
if (flock->fl_flags & FL_LEASE)
cifs_dbg(FYI, "Lease on file - not implemented yet\n");
- if (flock->fl_flags &
- (~(FL_POSIX | FL_FLOCK | FL_SLEEP |
- FL_ACCESS | FL_LEASE | FL_CLOSE)))
- cifs_dbg(FYI, "Unknown lock flags 0x%x\n", flock->fl_flags);
+#endif
+ if (flock->fl_flags & FL_SLEEP) {
+ cifs_dbg(FYI, "Blocking lock\n");
+ *wait_flag = true;
+ }
+
+ cifs_dbg(FYI, "Lock type: 0x%02x\n", flock->fl_type);
*type = server->vals->large_lock_type;
- if (flock->fl_type == F_WRLCK) {
- cifs_dbg(FYI, "F_WRLCK\n");
- *type |= server->vals->exclusive_lock_type;
- *lock = 1;
- } else if (flock->fl_type == F_UNLCK) {
- cifs_dbg(FYI, "F_UNLCK\n");
- *type |= server->vals->unlock_lock_type;
- *unlock = 1;
- /* Check if unlock includes more than one lock range */
- } else if (flock->fl_type == F_RDLCK) {
- cifs_dbg(FYI, "F_RDLCK\n");
+
+ switch (flock->fl_type) {
+ case F_RDLCK:
+ case F_SHLCK:
*type |= server->vals->shared_lock_type;
- *lock = 1;
- } else if (flock->fl_type == F_EXLCK) {
- cifs_dbg(FYI, "F_EXLCK\n");
+ break;
+ case F_WRLCK:
+ case F_EXLCK:
*type |= server->vals->exclusive_lock_type;
- *lock = 1;
- } else if (flock->fl_type == F_SHLCK) {
- cifs_dbg(FYI, "F_SHLCK\n");
- *type |= server->vals->shared_lock_type;
- *lock = 1;
- } else
- cifs_dbg(FYI, "Unknown type of lock\n");
+ break;
+ case F_UNLCK:
+ *type |= server->vals->unlock_lock_type;
+ break;
+ default:
+ cifs_dbg(FYI, "Unknown lock type\n");
+ return -EINVAL;
+ }
+
+ *lock = !(*type & server->vals->unlock_lock_type);
+ return 0;
}
static int
@@ -1547,10 +1551,9 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
return rc;
}
-static int
-cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
- bool wait_flag, bool posix_lck, int lock, int unlock,
- unsigned int xid)
+static int cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
+ bool wait_flag, bool posix_lck, bool lock,
+ unsigned int xid)
{
int rc = 0;
__u64 length = 1 + flock->fl_end - flock->fl_start;
@@ -1571,7 +1574,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
else
posix_lock_type = CIFS_WRLCK;
- if (unlock == 1)
+ if (!lock)
posix_lock_type = CIFS_UNLCK;
rc = CIFSSMBPosixLock(xid, tcon, cfile->fid.netfid,
@@ -1619,8 +1622,9 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
}
cifs_lock_add(cfile, lock);
- } else if (unlock)
+ } else {
rc = server->ops->mand_unlock_range(cfile, flock, xid);
+ }
out:
if (flock->fl_flags & FL_POSIX && !rc)
@@ -1631,7 +1635,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
{
int rc, xid;
- int lock = 0, unlock = 0;
+ bool lock = false;
bool wait_flag = false;
bool posix_lck = false;
struct cifs_sb_info *cifs_sb;
@@ -1651,8 +1655,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
cfile = (struct cifsFileInfo *)file->private_data;
tcon = tlink_tcon(cfile->tlink);
- cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag,
- tcon->ses->server);
+ rc = cifs_read_flock(flock, &type, &lock, &wait_flag,
+ tcon->ses->server);
+ if (rc)
+ goto out;
cifs_sb = CIFS_FILE_SB(file);
netfid = cfile->fid.netfid;
@@ -1668,21 +1674,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
*/
if (IS_GETLK(cmd)) {
rc = cifs_getlk(file, flock, type, wait_flag, posix_lck, xid);
- free_xid(xid);
- return rc;
- }
-
- if (!lock && !unlock) {
- /*
- * if no lock or unlock then nothing to do since we do not
- * know what it is
- */
- free_xid(xid);
- return -EOPNOTSUPP;
+ } else {
+ rc = cifs_setlk(file, flock, type, wait_flag, posix_lck, lock,
+ xid);
}
- rc = cifs_setlk(file, flock, type, wait_flag, posix_lck, lock, unlock,
- xid);
+out:
free_xid(xid);
return rc;
}
In case we don't support a specific file lock (that being determined by looking at fl_flags or fl_type), return an appropriate error back to userspace. Also, do some cleanup in cifs_lock() and its friends. Signed-off-by: Paulo Alcantara <palcantara@suse.de> --- fs/cifs/file.c | 105 ++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 54 deletions(-)