//==================================================================== // 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; }
int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, struct inode *dir, struct path *path) { int err; struct path tmp = { .mnt = path->mnt }; struct dentry *d; IMustLock(dir); IMustLock(src_dir); d = path->dentry; path->dentry = d->d_parent; tmp.dentry = src_dentry->d_parent; err = security_path_rename(&tmp, src_dentry, path, d); path->dentry = d; if (unlikely(err)) goto out; lockdep_off(); err = vfs_rename(src_dir, src_dentry, dir, path->dentry); lockdep_on(); if (!err) { int did; tmp.dentry = d->d_parent; vfsub_update_h_iattr(&tmp, &did); if (did) { tmp.dentry = src_dentry; vfsub_update_h_iattr(&tmp, /*did*/NULL); tmp.dentry = src_dentry->d_parent; vfsub_update_h_iattr(&tmp, /*did*/NULL); } /*ignore*/ } out: return err; } int vfsub_mkdir(struct inode *dir, struct path *path, int mode) { int err; struct dentry *d; IMustLock(dir); d = path->dentry; path->dentry = d->d_parent; err = security_path_mkdir(path, d, mode); path->dentry = d; if (unlikely(err)) goto out; err = vfs_mkdir(dir, path->dentry, mode); if (!err) { struct path tmp = *path; int did; vfsub_update_h_iattr(&tmp, &did); if (did) { tmp.dentry = path->dentry->d_parent; vfsub_update_h_iattr(&tmp, /*did*/NULL); } /*ignore*/ } out: return err; }