From nobody Wed Dec 17 09:42:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9040C82D98; Tue, 16 Jan 2024 19:48:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705434485; cv=none; b=eDkMvitPo098i+SoHZPF1hu6bSYOLfYm43IxlXKgMxNPEx2TTBQNYNiCJ49tXBFvekw7oEQMMq5bNfYvQYLqpqdynbE26yssr/d0C4NvjC3hVpZIOeT4+eUr6ITPXHR/CWLJfun9IxV9+CfveMyuIOSNgxzxbqM2VaAmAdDaJ7k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705434485; c=relaxed/simple; bh=tUgny3IKWhbScVuSTLV7DUCLBlNMDIBoYB+H+8vByek=; h=Received:DKIM-Signature:From:Date:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding:Message-Id:References: In-Reply-To:To:Cc:X-Mailer:X-Developer-Signature:X-Developer-Key; b=Ijjr46swxTtkkyEmT5ZA7x5MrPRWyqH7eYitX4NWucYNJmwr8CXn239gQ4yJvYhqkbPakhELuKTQf2mNhP9N9zyn4KT21fTKvscClPLJTSZuSukjE3ui/BPjlrhHWtl7qUZ3gn02QV0XF7lvA1xwgOEuNb6R+HMSnn7D9S8BzNk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=esBeGGdE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="esBeGGdE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ADCAEC433F1; Tue, 16 Jan 2024 19:48:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1705434485; bh=tUgny3IKWhbScVuSTLV7DUCLBlNMDIBoYB+H+8vByek=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=esBeGGdEninZHvph53qN//97ESmW2HYfWhrFu7zRRzGq66gsFHoCtvnDXQaUpwNpU v5MpOBDb3FK1gnycr/rm8PMcQSzkREvDuIfKg4QQM+n+eww23mHGBQ4sQE/E/a6w25 tLHS56E7ecolnIO4NqIBD9CaghHdnpCwc9b8wTpILaWJE4ElG5DS6LSeeWxFg0ybE7 tsuJEf5B4W9dqNX/ACQQ87/yY1/+a0Tnp2BCKnoXRabbXibmty1qcs0jA7WPJrVVDO erOIyLKM5L72csfZhgl81y2mFnSM6PnrKwJ63i7rhik6ZWJoisdP2IbD6g4fibMeoU OiAS2zJJVwWwA== From: Jeff Layton Date: Tue, 16 Jan 2024 14:46:16 -0500 Subject: [PATCH 20/20] filelock: split leases out of struct file_lock Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240116-flsplit-v1-20-c9d0f4370a5d@kernel.org> References: <20240116-flsplit-v1-0-c9d0f4370a5d@kernel.org> In-Reply-To: <20240116-flsplit-v1-0-c9d0f4370a5d@kernel.org> To: Christian Brauner , Alexander Viro , Eric Van Hensbergen , Latchesar Ionkov , Dominique Martinet , Christian Schoenebeck , David Howells , Marc Dionne , Xiubo Li , Ilya Dryomov , Alexander Aring , David Teigland , Miklos Szeredi , Andreas Gruenbacher , Trond Myklebust , Anna Schumaker , Chuck Lever , Neil Brown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Jan Kara , Mark Fasheh , Joel Becker , Joseph Qi , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Namjae Jeon , Sergey Senozhatsky , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers Cc: linux-kernel@vger.kernel.org, v9fs@lists.linux.dev, linux-afs@lists.infradead.org, ceph-devel@vger.kernel.org, gfs2@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, ocfs2-devel@lists.linux.dev, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-trace-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=32025; i=jlayton@kernel.org; h=from:subject:message-id; bh=tUgny3IKWhbScVuSTLV7DUCLBlNMDIBoYB+H+8vByek=; b=owEBbQKS/ZANAwAIAQAOaEEZVoIVAcsmYgBlpt0i1dB3Oo3SpA6n32QmMmESoKqFsJEotRttN e3Un3ICfnyJAjMEAAEIAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCZabdIgAKCRAADmhBGVaC FSGEEACG4VI4KJIOEol/8Wvcq9bT8SZEY/46btJujElDZuyEB1QsZhwZYfaGpiWV5LUvSwM/OYV 7wyzrlEYShy6Sm6QOgyapNYDTCEV26q+puaJv6XKC1DN6Yd5KEvcyWcIOm4TnHsH2QZyj2e8J3z F8Qti36s55qijnFc1btze7OBMwR3MFKcs7JGlEzrdDY+uThnQ2agTPY5vpS1+G1Uv1ASNyicWip ik0HyeqU6Zr4o0EohAIBh4pPJop0ehnGpX65rZlnjblpE3sENAQ95p50Nol/WhdBee3A3oOLJZq WXk1+4z1tLT+IF5i6uiWDfMM1/gl70Hh092YmAQAoPLXEb7l5eD71yapern6FlLjUhzVHLR6vuU QCs8lQujMCUnvt7ByIGCQuSz5HlL100KEUhowjpHKIE2ILk4ziAOlfEMUDffVSYyjrzfOo+KZ3c sz7JJWcTr+kB9EMKlpUfX+aUkbppSPNodEwWBaw/at4+NUsWGapn9Vw2wsCYpw1WR1UjHYhkE4z fIksLsuXTHcza7oct6zMJn3e16k5GfYA2P/KYw52jC7DivZi9FW6b8p9BnOoMp4jhwbKw31DE7d ADxp4+Ivs0s8gzkT+1uCsE2lBYZll7u2Bi4glmSe/7tPWKcPyiuTSCtn3Zda3kibx1BqL8zzTJ8 n0lIX3KYCHdUBRg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new struct file_lease and move the lease-specific fields from struct file_lock to it. Convert the appropriate API calls to take struct file_lease instead, and convert the callers to use them. Signed-off-by: Jeff Layton --- fs/libfs.c | 2 +- fs/locks.c | 130 ++++++++++++++++++++++++++----------= ---- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4file.c | 2 +- fs/nfs/nfs4proc.c | 4 +- fs/nfsd/nfs4layouts.c | 17 +++--- fs/nfsd/nfs4state.c | 21 ++++--- fs/smb/client/cifsfs.c | 2 +- include/linux/filelock.h | 49 ++++++++++----- include/linux/fs.h | 5 +- include/trace/events/filelock.h | 18 +++--- 11 files changed, 154 insertions(+), 98 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index eec6031b0155..8b67cb4655d5 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1580,7 +1580,7 @@ EXPORT_SYMBOL(alloc_anon_inode); * All arguments are ignored and it just returns -EINVAL. */ int -simple_nosetlease(struct file *filp, int arg, struct file_lock **flp, +simple_nosetlease(struct file *filp, int arg, struct file_lease **flp, void **priv) { return -EINVAL; diff --git a/fs/locks.c b/fs/locks.c index 6d24cf2525ec..014cc984e295 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -92,17 +92,22 @@ static inline bool IS_LEASE(struct file_lock_core *flc) =20 #define IS_REMOTELCK(fl) (fl->fl_core.fl_pid <=3D 0) =20 -struct file_lock *file_lock(struct file_lock_core *flc) +static struct file_lock *file_lock(struct file_lock_core *flc) { return container_of(flc, struct file_lock, fl_core); } =20 -static bool lease_breaking(struct file_lock *fl) +static struct file_lease *file_lease(struct file_lock_core *flc) +{ + return container_of(flc, struct file_lease, fl_core); +} + +static bool lease_breaking(struct file_lease *fl) { return fl->fl_core.fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING); } =20 -static int target_leasetype(struct file_lock *fl) +static int target_leasetype(struct file_lease *fl) { if (fl->fl_core.fl_flags & FL_UNLOCK_PENDING) return F_UNLCK; @@ -189,6 +194,7 @@ static DEFINE_SPINLOCK(blocked_lock_lock); =20 static struct kmem_cache *flctx_cache __ro_after_init; static struct kmem_cache *filelock_cache __ro_after_init; +static struct kmem_cache *filelease_cache __ro_after_init; =20 static struct file_lock_context * locks_get_lock_context(struct inode *inode, int type) @@ -298,6 +304,18 @@ struct file_lock *locks_alloc_lock(void) } EXPORT_SYMBOL_GPL(locks_alloc_lock); =20 +/* Allocate an empty lock structure. */ +struct file_lease *locks_alloc_lease(void) +{ + struct file_lease *fl =3D kmem_cache_zalloc(filelease_cache, GFP_KERNEL); + + if (fl) + locks_init_lock_heads(&fl->fl_core); + + return fl; +} +EXPORT_SYMBOL_GPL(locks_alloc_lease); + void locks_release_private(struct file_lock *fl) { struct file_lock_core *flc =3D &fl->fl_core; @@ -359,15 +377,25 @@ void locks_free_lock(struct file_lock *fl) } EXPORT_SYMBOL(locks_free_lock); =20 +/* Free a lease which is not in use. */ +void locks_free_lease(struct file_lease *fl) +{ + kmem_cache_free(filelease_cache, fl); +} +EXPORT_SYMBOL(locks_free_lease); + static void locks_dispose_list(struct list_head *dispose) { - struct file_lock *fl; + struct file_lock_core *flc; =20 while (!list_empty(dispose)) { - fl =3D list_first_entry(dispose, struct file_lock, fl_core.fl_list); - list_del_init(&fl->fl_core.fl_list); - locks_free_lock(fl); + flc =3D list_first_entry(dispose, struct file_lock_core, fl_list); + list_del_init(&flc->fl_list); + if (IS_LEASE(flc)) + locks_free_lease(file_lease(flc)); + else + locks_free_lock(file_lock(flc)); } } =20 @@ -378,6 +406,13 @@ void locks_init_lock(struct file_lock *fl) } EXPORT_SYMBOL(locks_init_lock); =20 +void locks_init_lease(struct file_lease *fl) +{ + memset(fl, 0, sizeof(*fl)); + locks_init_lock_heads(&fl->fl_core); +} +EXPORT_SYMBOL(locks_init_lease); + /* * Initialize a new lock from an existing file_lock structure. */ @@ -541,14 +576,14 @@ static int flock_to_posix_lock(struct file *filp, str= uct file_lock *fl, =20 /* default lease lock manager operations */ static bool -lease_break_callback(struct file_lock *fl) +lease_break_callback(struct file_lease *fl) { kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); return false; } =20 static void -lease_setup(struct file_lock *fl, void **priv) +lease_setup(struct file_lease *fl, void **priv) { struct file *filp =3D fl->fl_core.fl_file; struct fasync_struct *fa =3D *priv; @@ -564,7 +599,7 @@ lease_setup(struct file_lock *fl, void **priv) __f_setown(filp, task_pid(current), PIDTYPE_TGID, 0); } =20 -static const struct lock_manager_operations lease_manager_ops =3D { +static const struct lease_manager_operations lease_manager_ops =3D { .lm_break =3D lease_break_callback, .lm_change =3D lease_modify, .lm_setup =3D lease_setup, @@ -573,7 +608,7 @@ static const struct lock_manager_operations lease_manag= er_ops =3D { /* * Initialize a lease, use the default lock manager operations */ -static int lease_init(struct file *filp, int type, struct file_lock *fl) +static int lease_init(struct file *filp, int type, struct file_lease *fl) { if (assign_type(&fl->fl_core, type) !=3D 0) return -EINVAL; @@ -583,17 +618,14 @@ static int lease_init(struct file *filp, int type, st= ruct file_lock *fl) =20 fl->fl_core.fl_file =3D filp; fl->fl_core.fl_flags =3D FL_LEASE; - fl->fl_start =3D 0; - fl->fl_end =3D OFFSET_MAX; - fl->fl_ops =3D NULL; fl->fl_lmops =3D &lease_manager_ops; return 0; } =20 /* Allocate a file_lock initialised to this type of lease */ -static struct file_lock *lease_alloc(struct file *filp, int type) +static struct file_lease *lease_alloc(struct file *filp, int type) { - struct file_lock *fl =3D locks_alloc_lock(); + struct file_lease *fl =3D locks_alloc_lease(); int error =3D -ENOMEM; =20 if (fl =3D=3D NULL) @@ -601,7 +633,7 @@ static struct file_lock *lease_alloc(struct file *filp,= int type) =20 error =3D lease_init(filp, type, fl); if (error) { - locks_free_lock(fl); + locks_free_lease(fl); return ERR_PTR(error); } return fl; @@ -1418,7 +1450,7 @@ static int posix_lock_inode_wait(struct inode *inode,= struct file_lock *fl) return error; } =20 -static void lease_clear_pending(struct file_lock *fl, int arg) +static void lease_clear_pending(struct file_lease *fl, int arg) { switch (arg) { case F_UNLCK: @@ -1430,7 +1462,7 @@ static void lease_clear_pending(struct file_lock *fl,= int arg) } =20 /* We already had a lease on this file; just change its type */ -int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) +int lease_modify(struct file_lease *fl, int arg, struct list_head *dispose) { int error =3D assign_type(&fl->fl_core, arg); =20 @@ -1465,7 +1497,7 @@ static bool past_time(unsigned long then) static void time_out_leases(struct inode *inode, struct list_head *dispose) { struct file_lock_context *ctx =3D inode->i_flctx; - struct file_lock *fl, *tmp; + struct file_lease *fl, *tmp; =20 lockdep_assert_held(&ctx->flc_lock); =20 @@ -1481,8 +1513,8 @@ static void time_out_leases(struct inode *inode, stru= ct list_head *dispose) static bool leases_conflict(struct file_lock_core *lc, struct file_lock_co= re *bc) { bool rc; - struct file_lock *lease =3D file_lock(lc); - struct file_lock *breaker =3D file_lock(bc); + struct file_lease *lease =3D file_lease(lc); + struct file_lease *breaker =3D file_lease(bc); =20 if (lease->fl_lmops->lm_breaker_owns_lease && lease->fl_lmops->lm_breaker_owns_lease(lease)) @@ -1503,7 +1535,7 @@ static bool leases_conflict(struct file_lock_core *lc= , struct file_lock_core *bc } =20 static bool -any_leases_conflict(struct inode *inode, struct file_lock *breaker) +any_leases_conflict(struct inode *inode, struct file_lease *breaker) { struct file_lock_context *ctx =3D inode->i_flctx; struct file_lock_core *flc; @@ -1534,7 +1566,7 @@ int __break_lease(struct inode *inode, unsigned int m= ode, unsigned int type) { int error =3D 0; struct file_lock_context *ctx; - struct file_lock *new_fl, *fl, *tmp; + struct file_lease *new_fl, *fl, *tmp; unsigned long break_time; int want_write =3D (mode & O_ACCMODE) !=3D O_RDONLY; LIST_HEAD(dispose); @@ -1594,7 +1626,7 @@ int __break_lease(struct inode *inode, unsigned int m= ode, unsigned int type) } =20 restart: - fl =3D list_first_entry(&ctx->flc_lease, struct file_lock, fl_core.fl_lis= t); + fl =3D list_first_entry(&ctx->flc_lease, struct file_lease, fl_core.fl_li= st); break_time =3D fl->fl_break_time; if (break_time !=3D 0) break_time -=3D jiffies; @@ -1613,7 +1645,7 @@ int __break_lease(struct inode *inode, unsigned int m= ode, unsigned int type) percpu_down_read(&file_rwsem); spin_lock(&ctx->flc_lock); trace_break_lease_unblock(inode, new_fl); - locks_delete_block(new_fl); + __locks_delete_block(&new_fl->fl_core); if (error >=3D 0) { /* * Wait for the next conflicting lease that has not been @@ -1630,7 +1662,7 @@ int __break_lease(struct inode *inode, unsigned int m= ode, unsigned int type) percpu_up_read(&file_rwsem); locks_dispose_list(&dispose); free_lock: - locks_free_lock(new_fl); + locks_free_lease(new_fl); return error; } EXPORT_SYMBOL(__break_lease); @@ -1648,13 +1680,13 @@ void lease_get_mtime(struct inode *inode, struct ti= mespec64 *time) { bool has_lease =3D false; struct file_lock_context *ctx; - struct file_lock *fl; + struct file_lease *fl; =20 ctx =3D locks_inode_context(inode); if (ctx && !list_empty_careful(&ctx->flc_lease)) { spin_lock(&ctx->flc_lock); fl =3D list_first_entry_or_null(&ctx->flc_lease, - struct file_lock, fl_core.fl_list); + struct file_lease, fl_core.fl_list); if (fl && (fl->fl_core.fl_type =3D=3D F_WRLCK)) has_lease =3D true; spin_unlock(&ctx->flc_lock); @@ -1690,7 +1722,7 @@ EXPORT_SYMBOL(lease_get_mtime); */ int fcntl_getlease(struct file *filp) { - struct file_lock *fl; + struct file_lease *fl; struct inode *inode =3D file_inode(filp); struct file_lock_context *ctx; int type =3D F_UNLCK; @@ -1762,9 +1794,9 @@ check_conflicting_open(struct file *filp, const int a= rg, int flags) } =20 static int -generic_add_lease(struct file *filp, int arg, struct file_lock **flp, void= **priv) +generic_add_lease(struct file *filp, int arg, struct file_lease **flp, voi= d **priv) { - struct file_lock *fl, *my_fl =3D NULL, *lease; + struct file_lease *fl, *my_fl =3D NULL, *lease; struct inode *inode =3D file_inode(filp); struct file_lock_context *ctx; bool is_deleg =3D (*flp)->fl_core.fl_flags & FL_DELEG; @@ -1873,7 +1905,7 @@ generic_add_lease(struct file *filp, int arg, struct = file_lock **flp, void **pri static int generic_delete_lease(struct file *filp, void *owner) { int error =3D -EAGAIN; - struct file_lock *fl, *victim =3D NULL; + struct file_lease *fl, *victim =3D NULL; struct inode *inode =3D file_inode(filp); struct file_lock_context *ctx; LIST_HEAD(dispose); @@ -1913,7 +1945,7 @@ static int generic_delete_lease(struct file *filp, vo= id *owner) * The (input) flp->fl_lmops->lm_break function is required * by break_lease(). */ -int generic_setlease(struct file *filp, int arg, struct file_lock **flp, +int generic_setlease(struct file *filp, int arg, struct file_lease **flp, void **priv) { struct inode *inode =3D file_inode(filp); @@ -1960,7 +1992,7 @@ lease_notifier_chain_init(void) } =20 static inline void -setlease_notifier(int arg, struct file_lock *lease) +setlease_notifier(int arg, struct file_lease *lease) { if (arg !=3D F_UNLCK) srcu_notifier_call_chain(&lease_notifier_chain, arg, lease); @@ -1996,7 +2028,7 @@ EXPORT_SYMBOL_GPL(lease_unregister_notifier); * may be NULL if the lm_setup operation doesn't require it. */ int -vfs_setlease(struct file *filp, int arg, struct file_lock **lease, void **= priv) +vfs_setlease(struct file *filp, int arg, struct file_lease **lease, void *= *priv) { if (lease) setlease_notifier(arg, *lease); @@ -2009,7 +2041,7 @@ EXPORT_SYMBOL_GPL(vfs_setlease); =20 static int do_fcntl_add_lease(unsigned int fd, struct file *filp, int arg) { - struct file_lock *fl; + struct file_lease *fl; struct fasync_struct *new; int error; =20 @@ -2019,14 +2051,14 @@ static int do_fcntl_add_lease(unsigned int fd, stru= ct file *filp, int arg) =20 new =3D fasync_alloc(); if (!new) { - locks_free_lock(fl); + locks_free_lease(fl); return -ENOMEM; } new->fa_fd =3D fd; =20 error =3D vfs_setlease(filp, arg, &fl, (void **)&new); if (fl) - locks_free_lock(fl); + locks_free_lease(fl); if (new) fasync_free(new); return error; @@ -2646,7 +2678,7 @@ locks_remove_flock(struct file *filp, struct file_loc= k_context *flctx) static void locks_remove_lease(struct file *filp, struct file_lock_context *ctx) { - struct file_lock *fl, *tmp; + struct file_lease *fl, *tmp; LIST_HEAD(dispose); =20 if (list_empty(&ctx->flc_lease)) @@ -2744,7 +2776,7 @@ static void lock_get_status(struct seq_file *f, struc= t file_lock *fl, struct inode *inode =3D NULL; unsigned int fl_pid; struct pid_namespace *proc_pidns =3D proc_pid_ns(file_inode(f->file)->i_s= b); - int type; + int type =3D fl->fl_core.fl_type; =20 fl_pid =3D locks_translate_pid(fl, proc_pidns); /* @@ -2761,6 +2793,7 @@ static void lock_get_status(struct seq_file *f, struc= t file_lock *fl, if (repeat) seq_printf(f, "%*s", repeat - 1 + (int)strlen(pfx), pfx); =20 + if (IS_POSIX(&fl->fl_core)) { if (fl->fl_core.fl_flags & FL_ACCESS) seq_puts(f, "ACCESS"); @@ -2774,21 +2807,25 @@ static void lock_get_status(struct seq_file *f, str= uct file_lock *fl, } else if (IS_FLOCK(&fl->fl_core)) { seq_puts(f, "FLOCK ADVISORY "); } else if (IS_LEASE(&fl->fl_core)) { - if (fl->fl_core.fl_flags & FL_DELEG) + struct file_lease *lease =3D file_lease(&fl->fl_core); + + type =3D target_leasetype(lease); + + if (lease->fl_core.fl_flags & FL_DELEG) seq_puts(f, "DELEG "); else seq_puts(f, "LEASE "); =20 - if (lease_breaking(fl)) + if (lease_breaking(lease)) seq_puts(f, "BREAKING "); - else if (fl->fl_core.fl_file) + else if (lease->fl_core.fl_file) seq_puts(f, "ACTIVE "); else seq_puts(f, "BREAKER "); } else { seq_puts(f, "UNKNOWN UNKNOWN "); } - type =3D IS_LEASE(&fl->fl_core) ? target_leasetype(fl) : fl->fl_core.fl_t= ype; + =20 seq_printf(f, "%s ", (type =3D=3D F_WRLCK) ? "WRITE" : (type =3D=3D F_RDLCK) ? "READ" : "UNLCK"); @@ -2964,6 +3001,9 @@ static int __init filelock_init(void) filelock_cache =3D kmem_cache_create("file_lock_cache", sizeof(struct file_lock), 0, SLAB_PANIC, NULL); =20 + filelease_cache =3D kmem_cache_create("file_lock_cache", + sizeof(struct file_lease), 0, SLAB_PANIC, NULL); + for_each_possible_cpu(i) { struct file_lock_list_struct *fll =3D per_cpu_ptr(&file_lock_list, i); =20 diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 581698f1b7b2..6ff41ceb9f1c 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -330,7 +330,7 @@ extern int update_open_stateid(struct nfs4_state *state, const nfs4_stateid *deleg_stateid, fmode_t fmode); extern int nfs4_proc_setlease(struct file *file, int arg, - struct file_lock **lease, void **priv); + struct file_lease **lease, void **priv); extern int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo); extern void nfs4_update_changeattr(struct inode *dir, diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index e238abc78a13..1cd9652f3c28 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -439,7 +439,7 @@ void nfs42_ssc_unregister_ops(void) } #endif /* CONFIG_NFS_V4_2 */ =20 -static int nfs4_setlease(struct file *file, int arg, struct file_lock **le= ase, +static int nfs4_setlease(struct file *file, int arg, struct file_lease **l= ease, void **priv) { return nfs4_proc_setlease(file, arg, lease, priv); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a5596007b4d9..e2ef04e88603 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7604,7 +7604,7 @@ static int nfs4_delete_lease(struct file *file, void = **priv) return generic_setlease(file, F_UNLCK, NULL, priv); } =20 -static int nfs4_add_lease(struct file *file, int arg, struct file_lock **l= ease, +static int nfs4_add_lease(struct file *file, int arg, struct file_lease **= lease, void **priv) { struct inode *inode =3D file_inode(file); @@ -7622,7 +7622,7 @@ static int nfs4_add_lease(struct file *file, int arg,= struct file_lock **lease, return -EAGAIN; } =20 -int nfs4_proc_setlease(struct file *file, int arg, struct file_lock **leas= e, +int nfs4_proc_setlease(struct file *file, int arg, struct file_lease **lea= se, void **priv) { switch (arg) { diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 4bef3349bd90..7726aca7ad52 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -25,7 +25,7 @@ static struct kmem_cache *nfs4_layout_cache; static struct kmem_cache *nfs4_layout_stateid_cache; =20 static const struct nfsd4_callback_ops nfsd4_cb_layout_ops; -static const struct lock_manager_operations nfsd4_layouts_lm_ops; +static const struct lease_manager_operations nfsd4_layouts_lm_ops; =20 const struct nfsd4_layout_ops *nfsd4_layout_ops[LAYOUT_TYPE_MAX] =3D { #ifdef CONFIG_NFSD_FLEXFILELAYOUT @@ -182,20 +182,19 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid) static int nfsd4_layout_setlease(struct nfs4_layout_stateid *ls) { - struct file_lock *fl; + struct file_lease *fl; int status; =20 if (nfsd4_layout_ops[ls->ls_layout_type]->disable_recalls) return 0; =20 - fl =3D locks_alloc_lock(); + fl =3D locks_alloc_lease(); if (!fl) return -ENOMEM; - locks_init_lock(fl); + locks_init_lease(fl); fl->fl_lmops =3D &nfsd4_layouts_lm_ops; fl->fl_core.fl_flags =3D FL_LAYOUT; fl->fl_core.fl_type =3D F_RDLCK; - fl->fl_end =3D OFFSET_MAX; fl->fl_core.fl_owner =3D ls; fl->fl_core.fl_pid =3D current->tgid; fl->fl_core.fl_file =3D ls->ls_file->nf_file; @@ -203,7 +202,7 @@ nfsd4_layout_setlease(struct nfs4_layout_stateid *ls) status =3D vfs_setlease(fl->fl_core.fl_file, fl->fl_core.fl_type, &fl, NULL); if (status) { - locks_free_lock(fl); + locks_free_lease(fl); return status; } BUG_ON(fl !=3D NULL); @@ -724,7 +723,7 @@ static const struct nfsd4_callback_ops nfsd4_cb_layout_= ops =3D { }; =20 static bool -nfsd4_layout_lm_break(struct file_lock *fl) +nfsd4_layout_lm_break(struct file_lease *fl) { /* * We don't want the locks code to timeout the lease for us; @@ -737,14 +736,14 @@ nfsd4_layout_lm_break(struct file_lock *fl) } =20 static int -nfsd4_layout_lm_change(struct file_lock *onlist, int arg, +nfsd4_layout_lm_change(struct file_lease *onlist, int arg, struct list_head *dispose) { BUG_ON(!(arg & F_UNLCK)); return lease_modify(onlist, arg, dispose); } =20 -static const struct lock_manager_operations nfsd4_layouts_lm_ops =3D { +static const struct lease_manager_operations nfsd4_layouts_lm_ops =3D { .lm_break =3D nfsd4_layout_lm_break, .lm_change =3D nfsd4_layout_lm_change, }; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index cf5d0b3a553f..8b394f8a14c5 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4922,7 +4922,7 @@ static void nfsd_break_one_deleg(struct nfs4_delegati= on *dp) =20 /* Called from break_lease() with flc_lock held. */ static bool -nfsd_break_deleg_cb(struct file_lock *fl) +nfsd_break_deleg_cb(struct file_lease *fl) { struct nfs4_delegation *dp =3D (struct nfs4_delegation *) fl->fl_core.fl_= owner; struct nfs4_file *fp =3D dp->dl_stid.sc_file; @@ -4960,7 +4960,7 @@ nfsd_break_deleg_cb(struct file_lock *fl) * %true: Lease conflict was resolved * %false: Lease conflict was not resolved. */ -static bool nfsd_breaker_owns_lease(struct file_lock *fl) +static bool nfsd_breaker_owns_lease(struct file_lease *fl) { struct nfs4_delegation *dl =3D fl->fl_core.fl_owner; struct svc_rqst *rqst; @@ -4977,7 +4977,7 @@ static bool nfsd_breaker_owns_lease(struct file_lock = *fl) } =20 static int -nfsd_change_deleg_cb(struct file_lock *onlist, int arg, +nfsd_change_deleg_cb(struct file_lease *onlist, int arg, struct list_head *dispose) { struct nfs4_delegation *dp =3D (struct nfs4_delegation *) onlist->fl_core= .fl_owner; @@ -4991,7 +4991,7 @@ nfsd_change_deleg_cb(struct file_lock *onlist, int ar= g, return -EAGAIN; } =20 -static const struct lock_manager_operations nfsd_lease_mng_ops =3D { +static const struct lease_manager_operations nfsd_lease_mng_ops =3D { .lm_breaker_owns_lease =3D nfsd_breaker_owns_lease, .lm_break =3D nfsd_break_deleg_cb, .lm_change =3D nfsd_change_deleg_cb, @@ -5331,18 +5331,17 @@ static bool nfsd4_cb_channel_good(struct nfs4_clien= t *clp) return clp->cl_minorversion && clp->cl_cb_state =3D=3D NFSD4_CB_UNKNOWN; } =20 -static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, +static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int flag) { - struct file_lock *fl; + struct file_lease *fl; =20 - fl =3D locks_alloc_lock(); + fl =3D locks_alloc_lease(); if (!fl) return NULL; fl->fl_lmops =3D &nfsd_lease_mng_ops; fl->fl_core.fl_flags =3D FL_DELEG; fl->fl_core.fl_type =3D flag =3D=3D NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_W= RLCK; - fl->fl_end =3D OFFSET_MAX; fl->fl_core.fl_owner =3D (fl_owner_t)dp; fl->fl_core.fl_pid =3D current->tgid; fl->fl_core.fl_file =3D dp->dl_stid.sc_file->fi_deleg_file->nf_file; @@ -5463,7 +5462,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, struct nfs4_clnt_odstate *odstate =3D stp->st_clnt_odstate; struct nfs4_delegation *dp; struct nfsd_file *nf =3D NULL; - struct file_lock *fl; + struct file_lease *fl; u32 dl_type; =20 /* @@ -5536,7 +5535,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, status =3D vfs_setlease(fp->fi_deleg_file->nf_file, fl->fl_core.fl_type, &fl, NULL); if (fl) - locks_free_lock(fl); + locks_free_lease(fl); if (status) goto out_clnt_odstate; =20 @@ -8449,7 +8448,7 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, = struct inode *inode) { __be32 status; struct file_lock_context *ctx; - struct file_lock *fl; + struct file_lease *fl; struct nfs4_delegation *dp; =20 ctx =3D locks_inode_context(inode); diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 99b0ade833aa..d053c15d06b3 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1084,7 +1084,7 @@ static loff_t cifs_llseek(struct file *file, loff_t o= ffset, int whence) } =20 static int -cifs_setlease(struct file *file, int arg, struct file_lock **lease, void *= *priv) +cifs_setlease(struct file *file, int arg, struct file_lease **lease, void = **priv) { /* * Note that this is called by vfs setlease with i_lock held to diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 9cf1ee3efeda..fcb3f7e86270 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -27,6 +27,7 @@ #define FILE_LOCK_DEFERRED 1 =20 struct file_lock; +struct file_lease; =20 struct file_lock_operations { void (*fl_copy_lock)(struct file_lock *, struct file_lock *); @@ -39,14 +40,17 @@ struct lock_manager_operations { void (*lm_put_owner)(fl_owner_t); void (*lm_notify)(struct file_lock *); /* unblock callback */ int (*lm_grant)(struct file_lock *, int); - bool (*lm_break)(struct file_lock *); - int (*lm_change)(struct file_lock *, int, struct list_head *); - void (*lm_setup)(struct file_lock *, void **); - bool (*lm_breaker_owns_lease)(struct file_lock *); bool (*lm_lock_expirable)(struct file_lock *cfl); void (*lm_expire_lock)(void); }; =20 +struct lease_manager_operations { + bool (*lm_break)(struct file_lease *); + int (*lm_change)(struct file_lease *, int, struct list_head *); + void (*lm_setup)(struct file_lease *, void **); + bool (*lm_breaker_owns_lease)(struct file_lease *); +}; + struct lock_manager { struct list_head list; /* @@ -110,11 +114,6 @@ struct file_lock { loff_t fl_start; loff_t fl_end; =20 - struct fasync_struct * fl_fasync; /* for lease break notifications */ - /* for lease breaks: */ - unsigned long fl_break_time; - unsigned long fl_downgrade_time; - const struct file_lock_operations *fl_ops; /* Callbacks for filesystems */ const struct lock_manager_operations *fl_lmops; /* Callbacks for lockmana= gers */ union { @@ -131,6 +130,15 @@ struct file_lock { } fl_u; } __randomize_layout; =20 +struct file_lease { + struct file_lock_core fl_core; + struct fasync_struct * fl_fasync; /* for lease break notifications */ + /* for lease breaks: */ + unsigned long fl_break_time; + unsigned long fl_downgrade_time; + const struct lease_manager_operations *fl_lmops; /* Callbacks for lockman= agers */ +} __randomize_layout; + struct file_lock_context { spinlock_t flc_lock; struct list_head flc_flock; @@ -156,7 +164,7 @@ int fcntl_getlease(struct file *filp); void locks_free_lock_context(struct inode *inode); void locks_free_lock(struct file_lock *fl); void locks_init_lock(struct file_lock *); -struct file_lock * locks_alloc_lock(void); +struct file_lock *locks_alloc_lock(void); void locks_copy_lock(struct file_lock *, struct file_lock *); void locks_copy_conflock(struct file_lock *, struct file_lock *); void locks_remove_posix(struct file *, fl_owner_t); @@ -170,11 +178,15 @@ int vfs_lock_file(struct file *, unsigned int, struct= file_lock *, struct file_l int vfs_cancel_lock(struct file *filp, struct file_lock *fl); bool vfs_inode_has_locks(struct inode *inode); int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl); + +void locks_init_lease(struct file_lease *); +void locks_free_lease(struct file_lease *fl); +struct file_lease *locks_alloc_lease(void); int __break_lease(struct inode *inode, unsigned int flags, unsigned int ty= pe); void lease_get_mtime(struct inode *, struct timespec64 *time); -int generic_setlease(struct file *, int, struct file_lock **, void **priv); -int vfs_setlease(struct file *, int, struct file_lock **, void **); -int lease_modify(struct file_lock *, int, struct list_head *); +int generic_setlease(struct file *, int, struct file_lease **, void **priv= ); +int vfs_setlease(struct file *, int, struct file_lease **, void **); +int lease_modify(struct file_lease *, int, struct list_head *); =20 struct notifier_block; int lease_register_notifier(struct notifier_block *); @@ -238,6 +250,11 @@ static inline void locks_init_lock(struct file_lock *f= l) return; } =20 +static inline void locks_init_lease(struct file_lease *fl) +{ + return; +} + static inline void locks_copy_conflock(struct file_lock *new, struct file_= lock *fl) { return; @@ -312,18 +329,18 @@ static inline void lease_get_mtime(struct inode *inod= e, } =20 static inline int generic_setlease(struct file *filp, int arg, - struct file_lock **flp, void **priv) + struct file_lease **flp, void **priv) { return -EINVAL; } =20 static inline int vfs_setlease(struct file *filp, int arg, - struct file_lock **lease, void **priv) + struct file_lease **lease, void **priv) { return -EINVAL; } =20 -static inline int lease_modify(struct file_lock *fl, int arg, +static inline int lease_modify(struct file_lease *fl, int arg, struct list_head *dispose) { return -EINVAL; diff --git a/include/linux/fs.h b/include/linux/fs.h index e6ba0cc6f2ee..07b73e5c8f55 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1064,6 +1064,7 @@ struct file *get_file_active(struct file **f); typedef void *fl_owner_t; =20 struct file_lock; +struct file_lease; =20 /* The following constant reflects the upper bound of the file/locking spa= ce */ #ifndef OFFSET_MAX @@ -2005,7 +2006,7 @@ struct file_operations { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *= , size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *,= size_t, unsigned int); void (*splice_eof)(struct file *file); - int (*setlease)(struct file *, int, struct file_lock **, void **); + int (*setlease)(struct file *, int, struct file_lease **, void **); long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len); void (*show_fdinfo)(struct seq_file *m, struct file *f); @@ -3238,7 +3239,7 @@ extern int simple_write_begin(struct file *file, stru= ct address_space *mapping, extern const struct address_space_operations ram_aops; extern int always_delete_dentry(const struct dentry *); extern struct inode *alloc_anon_inode(struct super_block *); -extern int simple_nosetlease(struct file *, int, struct file_lock **, void= **); +extern int simple_nosetlease(struct file *, int, struct file_lease **, voi= d **); extern const struct dentry_operations simple_dentry_operations; =20 extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsig= ned int flags); diff --git a/include/trace/events/filelock.h b/include/trace/events/fileloc= k.h index 49263b69215e..344753e43aa4 100644 --- a/include/trace/events/filelock.h +++ b/include/trace/events/filelock.h @@ -117,12 +117,12 @@ DEFINE_EVENT(filelock_lock, flock_lock_inode, TP_ARGS(inode, fl, ret)); =20 DECLARE_EVENT_CLASS(filelock_lease, - TP_PROTO(struct inode *inode, struct file_lock *fl), + TP_PROTO(struct inode *inode, struct file_lease *fl), =20 TP_ARGS(inode, fl), =20 TP_STRUCT__entry( - __field(struct file_lock *, fl) + __field(struct file_lease *, fl) __field(unsigned long, i_ino) __field(dev_t, s_dev) __field(struct file_lock_core *, fl_blocker) @@ -153,23 +153,23 @@ DECLARE_EVENT_CLASS(filelock_lease, __entry->fl_break_time, __entry->fl_downgrade_time) ); =20 -DEFINE_EVENT(filelock_lease, break_lease_noblock, TP_PROTO(struct inode *i= node, struct file_lock *fl), +DEFINE_EVENT(filelock_lease, break_lease_noblock, TP_PROTO(struct inode *i= node, struct file_lease *fl), TP_ARGS(inode, fl)); =20 -DEFINE_EVENT(filelock_lease, break_lease_block, TP_PROTO(struct inode *ino= de, struct file_lock *fl), +DEFINE_EVENT(filelock_lease, break_lease_block, TP_PROTO(struct inode *ino= de, struct file_lease *fl), TP_ARGS(inode, fl)); =20 -DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *i= node, struct file_lock *fl), +DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *i= node, struct file_lease *fl), TP_ARGS(inode, fl)); =20 -DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *= inode, struct file_lock *fl), +DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *= inode, struct file_lease *fl), TP_ARGS(inode, fl)); =20 -DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode= , struct file_lock *fl), +DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode= , struct file_lease *fl), TP_ARGS(inode, fl)); =20 TRACE_EVENT(generic_add_lease, - TP_PROTO(struct inode *inode, struct file_lock *fl), + TP_PROTO(struct inode *inode, struct file_lease *fl), =20 TP_ARGS(inode, fl), =20 @@ -204,7 +204,7 @@ TRACE_EVENT(generic_add_lease, ); =20 TRACE_EVENT(leases_conflict, - TP_PROTO(bool conflict, struct file_lock *lease, struct file_lock *breake= r), + TP_PROTO(bool conflict, struct file_lease *lease, struct file_lease *brea= ker), =20 TP_ARGS(conflict, lease, breaker), =20 --=20 2.43.0