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.

vfs: make vfs_mknod break delegations on parent directory

In order to add directory delegation support, we need to break
delegations on the parent whenever there is going to be a change in the
directory.

Add a new delegated_inode pointer to vfs_mknod() and have the
appropriate callers wait when there is an outstanding delegation. All
other callers just set the pointer to NULL.

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

authored by

Jeff Layton and committed by
Christian Brauner
e8960c1b c826229c

+23 -16
+1 -1
drivers/base/devtmpfs.c
··· 231 231 return PTR_ERR(dentry); 232 232 233 233 err = vfs_mknod(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode, 234 - dev->devt); 234 + dev->devt, NULL); 235 235 if (!err) { 236 236 struct iattr newattrs; 237 237
+1 -1
fs/ecryptfs/inode.c
··· 564 564 rc = lock_parent(dentry, &lower_dentry, &lower_dir); 565 565 if (!rc) 566 566 rc = vfs_mknod(&nop_mnt_idmap, lower_dir, 567 - lower_dentry, mode, dev); 567 + lower_dentry, mode, dev, NULL); 568 568 if (rc || d_really_is_negative(lower_dentry)) 569 569 goto out; 570 570 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
+1 -1
fs/init.c
··· 157 157 error = security_path_mknod(&path, dentry, mode, dev); 158 158 if (!error) 159 159 error = vfs_mknod(mnt_idmap(path.mnt), path.dentry->d_inode, 160 - dentry, mode, new_decode_dev(dev)); 160 + dentry, mode, new_decode_dev(dev), NULL); 161 161 end_creating_path(&path, dentry); 162 162 return error; 163 163 }
+15 -8
fs/namei.c
··· 4295 4295 } 4296 4296 EXPORT_SYMBOL(start_creating_user_path); 4297 4297 4298 + 4298 4299 /** 4299 4300 * vfs_mknod - create device node or file 4300 - * @idmap: idmap of the mount the inode was found from 4301 - * @dir: inode of the parent directory 4302 - * @dentry: dentry of the child device node 4303 - * @mode: mode of the child device node 4304 - * @dev: device number of device to create 4301 + * @idmap: idmap of the mount the inode was found from 4302 + * @dir: inode of the parent directory 4303 + * @dentry: dentry of the child device node 4304 + * @mode: mode of the child device node 4305 + * @dev: device number of device to create 4306 + * @delegated_inode: returns parent inode, if the inode is delegated. 4305 4307 * 4306 4308 * Create a device node or file. 4307 4309 * ··· 4314 4312 * raw inode simply pass @nop_mnt_idmap. 4315 4313 */ 4316 4314 int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir, 4317 - struct dentry *dentry, umode_t mode, dev_t dev) 4315 + struct dentry *dentry, umode_t mode, dev_t dev, 4316 + struct delegated_inode *delegated_inode) 4318 4317 { 4319 4318 bool is_whiteout = S_ISCHR(mode) && dev == WHITEOUT_DEV; 4320 4319 int error = may_create(idmap, dir, dentry); ··· 4336 4333 return error; 4337 4334 4338 4335 error = security_inode_mknod(dir, dentry, mode, dev); 4336 + if (error) 4337 + return error; 4338 + 4339 + error = try_break_deleg(dir, delegated_inode); 4339 4340 if (error) 4340 4341 return error; 4341 4342 ··· 4400 4393 break; 4401 4394 case S_IFCHR: case S_IFBLK: 4402 4395 error = vfs_mknod(idmap, path.dentry->d_inode, 4403 - dentry, mode, new_decode_dev(dev)); 4396 + dentry, mode, new_decode_dev(dev), &di); 4404 4397 break; 4405 4398 case S_IFIFO: case S_IFSOCK: 4406 4399 error = vfs_mknod(idmap, path.dentry->d_inode, 4407 - dentry, mode, 0); 4400 + dentry, mode, 0, &di); 4408 4401 break; 4409 4402 } 4410 4403 out2:
+1 -1
fs/nfsd/vfs.c
··· 1573 1573 case S_IFIFO: 1574 1574 case S_IFSOCK: 1575 1575 host_err = vfs_mknod(&nop_mnt_idmap, dirp, dchild, 1576 - iap->ia_mode, rdev); 1576 + iap->ia_mode, rdev, NULL); 1577 1577 break; 1578 1578 default: 1579 1579 printk(KERN_WARNING "nfsd: bad file type %o in nfsd_create\n",
+1 -1
fs/overlayfs/overlayfs.h
··· 257 257 struct inode *dir, struct dentry *dentry, 258 258 umode_t mode, dev_t dev) 259 259 { 260 - int err = vfs_mknod(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, dev); 260 + int err = vfs_mknod(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, dev, NULL); 261 261 262 262 pr_debug("mknod(%pd2, 0%o, 0%o) = %i\n", dentry, mode, dev, err); 263 263 return err;
+2 -2
include/linux/fs.h
··· 2116 2116 struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, 2117 2117 struct dentry *, umode_t, struct delegated_inode *); 2118 2118 int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, 2119 - umode_t, dev_t); 2119 + umode_t, dev_t, struct delegated_inode *); 2120 2120 int vfs_symlink(struct mnt_idmap *, struct inode *, 2121 2121 struct dentry *, const char *); 2122 2122 int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, ··· 2152 2152 struct inode *dir, struct dentry *dentry) 2153 2153 { 2154 2154 return vfs_mknod(idmap, dir, dentry, S_IFCHR | WHITEOUT_MODE, 2155 - WHITEOUT_DEV); 2155 + WHITEOUT_DEV, NULL); 2156 2156 } 2157 2157 2158 2158 struct file *kernel_tmpfile_open(struct mnt_idmap *idmap,
+1 -1
net/unix/af_unix.c
··· 1399 1399 idmap = mnt_idmap(parent.mnt); 1400 1400 err = security_path_mknod(&parent, dentry, mode, 0); 1401 1401 if (!err) 1402 - err = vfs_mknod(idmap, d_inode(parent.dentry), dentry, mode, 0); 1402 + err = vfs_mknod(idmap, d_inode(parent.dentry), dentry, mode, 0, NULL); 1403 1403 if (err) 1404 1404 goto out_path; 1405 1405 err = mutex_lock_interruptible(&u->bindlock);