diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-12-01 17:12:45 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-01-05 11:53:07 -0500 |
commit | 8e6c848eceaa38a7e0192953b08162467e51f852 (patch) | |
tree | 8f398c5af7e2c5f0d116fcf01860dafc0077ab40 | |
parent | ae64f9bd1d3621b5e60d7363bc20afb46aede215 (diff) | |
download | op-kernel-dev-8e6c848eceaa38a7e0192953b08162467e51f852.zip op-kernel-dev-8e6c848eceaa38a7e0192953b08162467e51f852.tar.gz |
new primitive: vfs_mkobj()
Similar to vfs_create(), but with caller-supplied callback (and
argument for it) to be used instead of ->create().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namei.c | 21 | ||||
-rw-r--r-- | include/linux/fs.h | 4 |
2 files changed, 25 insertions, 0 deletions
@@ -2898,6 +2898,27 @@ int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, } EXPORT_SYMBOL(vfs_create); +int vfs_mkobj(struct dentry *dentry, umode_t mode, + int (*f)(struct dentry *, umode_t, void *), + void *arg) +{ + struct inode *dir = dentry->d_parent->d_inode; + int error = may_create(dir, dentry); + if (error) + return error; + + mode &= S_IALLUGO; + mode |= S_IFREG; + error = security_inode_create(dir, dentry, mode); + if (error) + return error; + error = f(dentry, mode, arg); + if (!error) + fsnotify_create(dir, dentry); + return error; +} +EXPORT_SYMBOL(vfs_mkobj); + bool may_open_dev(const struct path *path) { return !(path->mnt->mnt_flags & MNT_NODEV) && diff --git a/include/linux/fs.h b/include/linux/fs.h index 511fbaa..aad23d4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1608,6 +1608,10 @@ extern int vfs_whiteout(struct inode *, struct dentry *); extern struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag); +int vfs_mkobj(struct dentry *, umode_t, + int (*f)(struct dentry *, umode_t, void *), + void *); + /* * VFS file helper functions. */ |