Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2612435imm; Thu, 9 Aug 2018 16:42:04 -0700 (PDT) X-Google-Smtp-Source: AA+uWPz1qwaQjsWBxDRWDbO6zMCVup7ds5UYiXJHdi4AAP7wXKvU7hE3U7M0opHXjegojMfGUos9 X-Received: by 2002:a62:f0d:: with SMTP id x13-v6mr4328081pfi.123.1533858124781; Thu, 09 Aug 2018 16:42:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533858124; cv=none; d=google.com; s=arc-20160816; b=rOkbHlxM/OvEAtkm5xJAm+tC1Yi+6kOmgeT9yTx0wnZwdijLyIFmLPixNTDVYkhHaz CmKiGJ3+I2dIiGG7yfkXktPVJZsKhW2sBhXM4jLtZ4bFVBCEdXcMTHGLtRwuu6HjHAEc khw3Pkv5IdigYy0H0L1Ozf0zyM0Gq1UsndPhOkI3q7K4oDcp/36er4qhEcfSpWEVtpKX z21n2NkLmx9w6GZdmWq1OYen4boWcCF4rVRpB1KqrrourVqDNnzlTpAD0OpQfqhOj4Ve LWHFBN3+O6bU9zElEPD02t0yURByifqKLLlyl1OajXyqzvQip4PHbg9IU7YNmXOzwVJS Rm2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:references :in-reply-to:subject:cc:date:to:from:arc-authentication-results; bh=F6x1y4oXPwrbNlD0NzEI+0m9bsTgDXQjqHc0fXhEggc=; b=iApZT06dQQ6KZ034794JoSRMsNe1DqrjF4hdn2yuRMHAcWuvPSf81Mhk4Xfv9z3ccZ QOnYq87OSFZsg0T73pCBnimQZpcFfhHL4bnPi69XKT6NNYMcogW1Fqa7ZsoSdfCghrfs pNKNp2LF0DR48RRxBo+jcU5HI90GaJqFK1f58icsykv7wsNC7PbM2SwV9tN4WbBUw84Q 8lWdLNFDcGGgZQdI+hRQdPAUOSbPDINYAbm0Oy0Sf7g4QubP9fAdIYCMwQKg2SQxUPI0 2d9KqOBKNskGCX+ksPGKYDEThU31dfXFifmUZzgEjr91c1NzrCyfJVw2F8P8ccpGC5j0 ze4A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a5-v6si6476077plh.312.2018.08.09.16.41.50; Thu, 09 Aug 2018 16:42:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727754AbeHJCHz (ORCPT + 99 others); Thu, 9 Aug 2018 22:07:55 -0400 Received: from mx2.suse.de ([195.135.220.15]:42398 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727552AbeHJCHz (ORCPT ); Thu, 9 Aug 2018 22:07:55 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 54E14AF40; Thu, 9 Aug 2018 23:40:42 +0000 (UTC) From: NeilBrown To: "J. Bruce Fields" Date: Fri, 10 Aug 2018 09:40:35 +1000 Cc: Jeff Layton , Alexander Viro , Martin Wilck , linux-fsdevel@vger.kernel.org, Frank Filz , linux-kernel@vger.kernel.org Subject: Re: [PATCH 3/5] fs/locks: change all *_conflict() functions to return a new enum. In-Reply-To: <20180809130959.GH23873@fieldses.org> References: <153378012255.1220.6754153662007899557.stgit@noble> <153378028114.1220.3708291796442871726.stgit@noble> <20180809130959.GH23873@fieldses.org> Message-ID: <87d0urrtvw.fsf@notabene.neil.brown.name> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Thu, Aug 09 2018, J. Bruce Fields wrote: > On Thu, Aug 09, 2018 at 12:04:41PM +1000, NeilBrown wrote: >> In a future patch we will need to differentiate between conflicts that >> are "transitive" and those that aren't. >> A "transitive" conflict is defined as one where any lock that >> conflicts with the first (newly requested) lock would conflict with >> the existing lock. >>=20 >> So change posix_locks_conflict(), flock_locks_conflict() (both >> currently returning int) and leases_conflict() (currently returning >> bool) to return "enum conflict". >> Add locks_transitive_overlap() to make it possible to compute the >> correct conflict for posix locks. >>=20 >> The FL_NO_CONFLICT value is zero, so current code which only tests the >> truth value of these functions will still work the same way. >>=20 >> And convert some >> return (foo); >> to >> return foo; >>=20 >> Signed-off-by: NeilBrown >> --- >> fs/locks.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++-------= ------- >> 1 file changed, 49 insertions(+), 15 deletions(-) >>=20 >> diff --git a/fs/locks.c b/fs/locks.c >> index b4812da2a374..d06658b2dc7a 100644 >> --- a/fs/locks.c >> +++ b/fs/locks.c >> @@ -139,6 +139,16 @@ >> #define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) >> #define IS_REMOTELCK(fl) (fl->fl_pid <=3D 0) >>=20=20 >> +/* A transitive conflict is one where the first lock conflicts with >> + * the second lock, and any other lock that conflicts with the >> + * first lock, also conflicts with the second lock. >> + */ >> +enum conflict { >> + FL_NO_CONFLICT =3D 0, >> + FL_CONFLICT, >> + FL_TRANSITIVE_CONFLICT, >> +}; >> + >> static inline bool is_remote_lock(struct file *filp) >> { >> return likely(!(filp->f_path.dentry->d_sb->s_flags & SB_NOREMOTELOCK)); >> @@ -612,6 +622,15 @@ static inline int locks_overlap(struct file_lock *f= l1, struct file_lock *fl2) >> (fl2->fl_end >=3D fl1->fl_start)); >> } >>=20=20 >> +/* Check for transitive-overlap - true if any lock that overlaps >> + * the first lock must overlap the seconds >> + */ >> +static inline bool locks_transitive_overlap(struct file_lock *fl1, >> + struct file_lock *fl2) >> +{ >> + return (fl1->fl_start >=3D fl2->fl_start) && >> + (fl1->fl_end <=3D fl2->fl_end); >> +} >> /* >> * Check whether two locks have the same owner. >> */ >> @@ -793,47 +812,61 @@ locks_delete_lock_ctx(struct file_lock *fl, struct= list_head *dispose) >> /* Determine if lock sys_fl blocks lock caller_fl. Common functionality >> * checks for shared/exclusive status of overlapping locks. >> */ >> -static int locks_conflict(struct file_lock *caller_fl, struct file_lock= *sys_fl) >> +static enum conflict locks_conflict(struct file_lock *caller_fl, >> + struct file_lock *sys_fl) >> { >> if (sys_fl->fl_type =3D=3D F_WRLCK) >> - return 1; >> + return FL_TRANSITIVE_CONFLICT; >> if (caller_fl->fl_type =3D=3D F_WRLCK) >> - return 1; >> - return 0; >> + return FL_CONFLICT; >> + return FL_NO_CONFLICT; >> } >>=20=20 >> /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific >> * checking before calling the locks_conflict(). >> */ >> -static int posix_locks_conflict(struct file_lock *caller_fl, struct fil= e_lock *sys_fl) >> +static enum conflict posix_locks_conflict(struct file_lock *caller_fl, >> + struct file_lock *sys_fl) >> { >> /* POSIX locks owned by the same process do not conflict with >> * each other. >> */ >> if (posix_same_owner(caller_fl, sys_fl)) >> - return (0); >> + return FL_NO_CONFLICT; >>=20=20 >> /* Check whether they overlap */ >> if (!locks_overlap(caller_fl, sys_fl)) >> - return 0; >> + return FL_NO_CONFLICT; >>=20=20 >> - return (locks_conflict(caller_fl, sys_fl)); >> + switch (locks_conflict(caller_fl, sys_fl)) { >> + default: >> + case FL_NO_CONFLICT: >> + return FL_NO_CONFLICT; >> + case FL_CONFLICT: >> + return FL_CONFLICT; > > If I'm understanding the logic here and in locks_conflict correctly, > you're telling me that in the case where sys_fl is a read lock, and > caller_fl is a write lock, then any lock which conflicts with sys_fl > must conflict with caller_fl? Or do I have that backwards? It doesn't > sound right, in any case. As I was writing this code, I was thinking that I'd probably end up getting something backwards.... Let's see. I wrote: >> +/* A transitive conflict is one where the first lock conflicts with >> + * the second lock, and any other lock that conflicts with the >> + * first lock, also conflicts with the second lock. >> + */ caller_fl is first and sys_fl is second. if sys_fl, the second, is a read lock, and caller_fl, the first, is a write lock, they clearly conflict but any other lock that conflict with caller_fl (The write lock) would *not* necessarily conflict with the read lock. So this situation is *not* FL_TRANSITIVE_CONFLICT. locks_conflict() only returns FL_TRANSITIVE_CONFLICT when sys_fl (the second) is a write lock, which it isn't in this case. So I think that this case is handled correctly. posix_locks_conflict() will return FL_CONFLICT, but not FL_TRANSITIVE_CONFLICT. Have I convinced you, or have I missed your point? Thanks, NeilBrown > > --b. > >> + case FL_TRANSITIVE_CONFLICT: >> + if (locks_transitive_overlap(caller_fl, sys_fl)) >> + return FL_TRANSITIVE_CONFLICT; >> + else >> + return FL_CONFLICT; >> + } >> } --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEG8Yp69OQ2HB7X0l6Oeye3VZigbkFAlts0PMACgkQOeye3VZi gbkanA/+OcY8v/5/aMt6pw45V2Q3P6W2O2oaUHU1eqC0SehcYoOivJ7xTykB1Jqk Tl6dLs2x/A7AkyFDUt5S2zEq8qQhAsH3k0WTznYvCSov+DGBd/jQ2Bb+Vk5NqEiU frPrgHrY1IIthCA7nx2Z6e9u+noynn1J8g+uWj+qZ78p2B5n4LFcSKEw49H6DpjO GCMbhz0lXYyR90XXgNgqseK2r1s0QCS4Fo6jodxAwkXXvMs6yn13jzdaEWw45C1p YTizgE5Rs1+I81UJgETDegIS6d/GzIqK113vKj53PlIat/C+u6NOZEv93g7XiJ1B NbaPMq49k5FFPFPNIus3sWM0yze7EC1lzFtV2ydk6DsCPbHm7FhN1shl/1QvYnw6 4B8gvm0N7rBVpoFb1+5VsLG82OZSX+uDCinWM1IERn5+opMD3dsDqXtSveurB3/g tXA/rwEuSkZIEYR456/W8Gt5mlcNhudDnhojN/7mVtDTSob78uj3vEjuUXhc85+6 eWUQIgqoQqmPvpuYEGPyjlq3iNP12ahcv516QuIe3Y7n0RodnnKGCwFc5BiajpKC q379qSxVlxaTPWf9tpDL76NR9vtrYYINSaksD+12J76VO9MbDxB03K39yZsiFwth SvTk7RPahly2MyhKwFQOmBGnXv2Ioteg74ooVKYSKrqcNkCQ0sI= =lLDt -----END PGP SIGNATURE----- --=-=-=--