Esempio n. 1
0
/*! 2017. 8.12 study -ing */
static int handle_remove(const char *nodename, struct device *dev)
{
	struct path parent;
	struct dentry *dentry;
	int deleted = 0;
	int err;

	dentry = kern_path_locked(nodename, &parent);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	if (dentry->d_inode) {
		struct kstat stat;
		struct path p = {.mnt = parent.mnt, .dentry = dentry};
		err = vfs_getattr(&p, &stat);
		if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
			struct iattr newattrs;
			/*
			 * before unlinking this node, reset permissions
			 * of possible references like hardlinks
			 */
			newattrs.ia_uid = GLOBAL_ROOT_UID;
			newattrs.ia_gid = GLOBAL_ROOT_GID;
			newattrs.ia_mode = stat.mode & ~0777;
			newattrs.ia_valid =
				ATTR_UID|ATTR_GID|ATTR_MODE;
			mutex_lock(&dentry->d_inode->i_mutex);
			notify_change(dentry, &newattrs, NULL);
			mutex_unlock(&dentry->d_inode->i_mutex);
			err = vfs_unlink(parent.dentry->d_inode, dentry, NULL);
			if (!err || err == -ENOENT)
				deleted = 1;
		}
	} else {
		err = -ENOENT;
	}
	dput(dentry);
	mutex_unlock(&parent.dentry->d_inode->i_mutex);

	path_put(&parent);
	if (deleted && strchr(nodename, '/'))
		delete_path(nodename);
	return err;
}
Esempio n. 2
0
static int dev_rmdir(const char *name)
{
    struct path parent;
    struct dentry *dentry;
    int err;

    dentry = kern_path_locked(name, &parent);
    if (IS_ERR(dentry))
        return PTR_ERR(dentry);
    if (dentry->d_inode) {
        if (dentry->d_inode->i_private == &thread)
            err = vfs_rmdir(parent.dentry->d_inode, dentry);
        else
            err = -EPERM;
    } else {
        err = -ENOENT;
    }
    dput(dentry);
    mutex_unlock(&parent.dentry->d_inode->i_mutex);
    path_put(&parent);
    return err;
}
Esempio n. 3
0
struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pathname, int len)
{
	struct audit_fsnotify_mark *audit_mark;
	struct path path;
	struct dentry *dentry;
	struct inode *inode;
	int ret;

	if (pathname[0] != '/' || pathname[len-1] == '/')
		return ERR_PTR(-EINVAL);

	dentry = kern_path_locked(pathname, &path);
	if (IS_ERR(dentry))
		return (void *)dentry; /* returning an error */
	inode = path.dentry->d_inode;
	inode_unlock(inode);

	audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL);
	if (unlikely(!audit_mark)) {
		audit_mark = ERR_PTR(-ENOMEM);
		goto out;
	}

	fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_free_mark);
	audit_mark->mark.mask = AUDIT_FS_EVENTS;
	audit_mark->path = pathname;
	audit_update_mark(audit_mark, dentry->d_inode);
	audit_mark->rule = krule;

	ret = fsnotify_add_mark(&audit_mark->mark, audit_fsnotify_group, inode, NULL, true);
	if (ret < 0) {
		audit_fsnotify_mark_free(audit_mark);
		audit_mark = ERR_PTR(ret);
	}
out:
	dput(dentry);
	path_put(&path);
	return audit_mark;
}