From patchwork Fri Jun 29 20:54:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paulo Alcantara (SUSE)" X-Patchwork-Id: 10497497 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id ED855602CC for ; Fri, 29 Jun 2018 20:55:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF02B291D2 for ; Fri, 29 Jun 2018 20:55:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D355E29779; Fri, 29 Jun 2018 20:55:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BB30291D2 for ; Fri, 29 Jun 2018 20:55:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935472AbeF2Uzn (ORCPT ); Fri, 29 Jun 2018 16:55:43 -0400 Received: from mail.paulo.ac ([34.238.86.106]:34958 "EHLO mail.paulo.ac" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933489AbeF2Uzm (ORCPT ); Fri, 29 Jun 2018 16:55:42 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.paulo.ac (Postfix) with ESMTP id 2F090C78F26; Fri, 29 Jun 2018 20:55:42 +0000 (UTC) X-Virus-Scanned: amavisd-new at paulo.ac Authentication-Results: mail.paulo.ac (amavisd-new); dkim=pass (1024-bit key) header.d=paulo.ac Received: from mail.paulo.ac ([127.0.0.1]) by localhost (mail.paulo.ac [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id X4CL3Ikbvhsc; Fri, 29 Jun 2018 20:55:37 +0000 (UTC) Received: from localhost.localdomain (189.27.149.191.dynamic.adsl.gvt.net.br [189.27.149.191]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.paulo.ac (Postfix) with ESMTPSA id 3487DC78F24; Fri, 29 Jun 2018 20:55:36 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.paulo.ac 3487DC78F24 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=paulo.ac; s=default; t=1530305737; bh=iEqog4KOvvbywK7Gwns1aqXkAsWnWYeVKpLQu8TTj+0=; h=From:To:Cc:Subject:Date:From; b=N6PPE9jfm197Oq3SgtIaFYXtVdttLa0EdvcmCzZRMZVRGuQpDkVT+NAkrKAzurEM0 i9SadNfVyyOIdVlgZpKcnCBiC4Sh3DxP5KdDulKuDh+ILiR2/MnWTlA72Q9QztWHC1 53W+mc0i7zriptGYTqQD5KTlaFeBpL/feQQQ7Y64= From: Paulo Alcantara To: linux-cifs@vger.kernel.org Cc: smfrench@gmail.com, Paulo Alcantara , Paulo Alcantara Subject: [PATCH 1/2] cifs: Handle unsupported file locks gracefully Date: Fri, 29 Jun 2018 17:54:59 -0300 Message-Id: <20180629205500.7950-1-paulo@paulo.ac> X-Mailer: git-send-email 2.17.1 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- fs/cifs/file.c | 105 ++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8d41ca7bfcf1..259167f32580 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -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; }