static int handle_create(const char *nodename, umode_t mode, kuid_t uid, kgid_t gid, struct device *dev) { struct dentry *dentry; struct path path; int err; dentry = kern_path_create(AT_FDCWD, nodename, &path, 0); if (dentry == ERR_PTR(-ENOENT)) { create_path(nodename); dentry = kern_path_create(AT_FDCWD, nodename, &path, 0); } if (IS_ERR(dentry)) return PTR_ERR(dentry); err = vfs_mknod(d_inode(path.dentry), dentry, mode, dev->devt, &path); if (!err) { struct iattr newattrs; newattrs.ia_mode = mode; newattrs.ia_uid = uid; newattrs.ia_gid = gid; newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID; mutex_lock(&d_inode(dentry)->i_mutex); notify_change(dentry, &newattrs, NULL); mutex_unlock(&d_inode(dentry)->i_mutex); /* mark as kernel-created inode */ d_inode(dentry)->i_private = &thread; } done_path_create(&path, dentry); return err; }
static int handle_create(const char *nodename, umode_t mode, struct device *dev) { struct dentry *dentry; struct path path; int err; dentry = kern_path_create(AT_FDCWD, nodename, &path, 0); if (dentry == ERR_PTR(-ENOENT)) { create_path(nodename); dentry = kern_path_create(AT_FDCWD, nodename, &path, 0); } if (IS_ERR(dentry)) return PTR_ERR(dentry); err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt); if (!err) { struct iattr newattrs; /* fixup possibly umasked mode */ newattrs.ia_mode = mode; newattrs.ia_valid = ATTR_MODE; mutex_lock(&dentry->d_inode->i_mutex); notify_change(dentry, &newattrs); mutex_unlock(&dentry->d_inode->i_mutex); /* mark as kernel-created inode */ dentry->d_inode->i_private = &thread; } done_path_create(&path, dentry); return err; }
static int bpf_obj_do_pin(const struct filename *pathname, void *raw, enum bpf_type type) { struct dentry *dentry; struct inode *dir; struct path path; umode_t mode; dev_t devt; int ret; dentry = kern_path_create(AT_FDCWD, pathname->name, &path, 0); if (IS_ERR(dentry)) return PTR_ERR(dentry); mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask()); devt = MKDEV(UNNAMED_MAJOR, type); ret = security_path_mknod(&path, dentry, mode, devt); if (ret) goto out; dir = d_inode(path.dentry); if (dir->i_op != &bpf_dir_iops) { ret = -EPERM; goto out; } dentry->d_fsdata = raw; ret = vfs_mknod(dir, dentry, mode, devt); dentry->d_fsdata = NULL; out: done_path_create(&path, dentry); return ret; }
static int dev_mkdir(const char *name, umode_t mode) { struct dentry *dentry; struct path path; int err; dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY); if (IS_ERR(dentry)) return PTR_ERR(dentry); err = vfs_mkdir(path.dentry->d_inode, dentry, mode); if (!err) /* mark as kernel-created inode */ dentry->d_inode->i_private = &thread; done_path_create(&path, dentry); return err; }
//==================================================================== // Create a directory for this device under the given path. Returns // 0 on success and non-zero on failure. static int create_dev_dir(const char *dev_dir_path) { struct dentry *dentry; struct path path; int lookup_flags = LOOKUP_DIRECTORY; umode_t mode = S_IRUGO | S_IXUGO; int err; dentry = kern_path_create(AT_FDCWD, dev_dir_path, &path, lookup_flags); if (IS_ERR(dentry)) { return PTR_ERR(dentry); } err = security_path_mkdir(&path, dentry, mode); if (!err) { err = vfs_mkdir(path.dentry->d_inode, dentry, mode); } done_path_create(&path, dentry); return err; }
//==================================================================== // Create a node for this device under the given path using the given // device number. Returns 0 on success and non-zero on failure. static int create_fs_node(const char *dev_path, dev_t undelete_minor_devnode) { struct dentry *dentry; struct path path; int lookup_flags = 0; umode_t mode = S_IRUGO | S_IFCHR; int err; dentry = kern_path_create(AT_FDCWD, dev_path, &path, lookup_flags); if (IS_ERR(dentry)) { return PTR_ERR(dentry); } err = security_path_mknod(&path, dentry, mode, undelete_minor_devnode); if (!err) { err = vfs_mknod(path.dentry->d_inode, dentry, mode, undelete_minor_devnode); } done_path_create(&path, dentry); return err; }
static int dev_mkdir(const char *name, mode_t mode) { struct dentry *dentry; struct path path; int err; dentry = kern_path_create(AT_FDCWD, name, &path, 1); if (IS_ERR(dentry)) return PTR_ERR(dentry); err = vfs_mkdir(path.dentry->d_inode, dentry, mode); if (!err) /* mark as kernel-created inode */ dentry->d_inode->i_private = &thread; dput(dentry); mutex_unlock(&path.dentry->d_inode->i_mutex); path_put(&path); return err; }
int file_mkdir(const char * pathname, unsigned short perms, int recurse) { /* Welcome to the jungle... */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,41) /* DO NOT REFERENCE THIS VARIABLE */ /* It only exists to provide version compatibility */ struct path tmp_path; #endif struct path * path_ptr = NULL; struct dentry * dentry; int ret = 0; if (recurse != 0) { return mkdir_recursive(pathname, perms); } /* Before Linux 3.1 this was somewhat more difficult */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,41) { struct nameidata nd; // I'm not 100% sure about the version here, but it was around this time that the API changed #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38) ret = kern_path_parent(pathname, &nd); #else if (path_lookup(pathname, LOOKUP_DIRECTORY | LOOKUP_FOLLOW, &nd) == 0) { return 0; } if (path_lookup(pathname, LOOKUP_PARENT | LOOKUP_FOLLOW, &nd) != 0) { return -1; } #endif if (ret != 0) { printk(KERN_ERR "%s:%d - Error: kern_path_parent() returned error for (%s)\n", __FILE__, __LINE__, pathname); return -1; } dentry = lookup_create(&nd, 1); path_ptr = &(nd.path); } #else { dentry = kern_path_create(AT_FDCWD, pathname, &tmp_path, 1); if (IS_ERR(dentry)) { return 0; } path_ptr = &tmp_path; } #endif if (!IS_ERR(dentry)) { ret = vfs_mkdir(path_ptr->dentry->d_inode, dentry, perms); } mutex_unlock(&(path_ptr->dentry->d_inode->i_mutex)); path_put(path_ptr); return ret; }