summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-12-01 17:12:45 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-01-05 11:53:07 -0500
commit8e6c848eceaa38a7e0192953b08162467e51f852 (patch)
tree8f398c5af7e2c5f0d116fcf01860dafc0077ab40
parentae64f9bd1d3621b5e60d7363bc20afb46aede215 (diff)
downloadop-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.c21
-rw-r--r--include/linux/fs.h4
2 files changed, 25 insertions, 0 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 9cc91fb..1c0fb97 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -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.
*/
OpenPOWER on IntegriCloud