Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

filelock: push the S_ISREG check down to ->setlease handlers

When nfsd starts requesting directory delegations, setlease handlers may
see requests for leases on directories. Push the !S_ISREG check down
into the non-trivial setlease handlers, so we can selectively enable
them where they're supported.

FUSE is special: It's the only filesystem that supports atomic_open and
allows kernel-internal leases. atomic_open is issued when the VFS
doesn't know the state of the dentry being opened. If the file doesn't
exist, it may be created, in which case the dir lease should be broken.

The existing kernel-internal lease implementation has no provision for
this. Ensure that we don't allow directory leases by default going
forward by explicitly disabling them there.

Reviewed-by: NeilBrown <neil@brown.name>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20251111-dir-deleg-ro-v6-4-52f3feebb2f2@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Jeff Layton and committed by
Christian Brauner
e6d28ebc 6976ed2d

+9 -2
+1
fs/fuse/dir.c
··· 2230 2230 .fsync = fuse_dir_fsync, 2231 2231 .unlocked_ioctl = fuse_dir_ioctl, 2232 2232 .compat_ioctl = fuse_dir_compat_ioctl, 2233 + .setlease = simple_nosetlease, 2233 2234 }; 2234 2235 2235 2236 static const struct inode_operations fuse_common_inode_operations = {
+3 -2
fs/locks.c
··· 1935 1935 int generic_setlease(struct file *filp, int arg, struct file_lease **flp, 1936 1936 void **priv) 1937 1937 { 1938 + if (!S_ISREG(file_inode(filp)->i_mode)) 1939 + return -EINVAL; 1940 + 1938 1941 switch (arg) { 1939 1942 case F_UNLCK: 1940 1943 return generic_delete_lease(filp, *priv); ··· 2027 2024 2028 2025 if ((!vfsuid_eq_kuid(vfsuid, current_fsuid())) && !capable(CAP_LEASE)) 2029 2026 return -EACCES; 2030 - if (!S_ISREG(inode->i_mode)) 2031 - return -EINVAL; 2032 2027 error = security_file_lock(filp, arg); 2033 2028 if (error) 2034 2029 return error;
+2
fs/nfs/nfs4file.c
··· 431 431 static int nfs4_setlease(struct file *file, int arg, struct file_lease **lease, 432 432 void **priv) 433 433 { 434 + if (!S_ISREG(file_inode(file)->i_mode)) 435 + return -EINVAL; 434 436 return nfs4_proc_setlease(file, arg, lease, priv); 435 437 } 436 438
+3
fs/smb/client/cifsfs.c
··· 1149 1149 struct inode *inode = file_inode(file); 1150 1150 struct cifsFileInfo *cfile = file->private_data; 1151 1151 1152 + if (!S_ISREG(inode->i_mode)) 1153 + return -EINVAL; 1154 + 1152 1155 /* Check if file is oplocked if this is request for new lease */ 1153 1156 if (arg == F_UNLCK || 1154 1157 ((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) ||