Beispiel #1
0
static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
	struct autofs_dirhash *dh = &sbi->dirhash;
	struct autofs_dir_ent *ent;

	lock_kernel();
	if (!autofs_oz_mode(sbi)) {
		unlock_kernel();
		return -EACCES;
	}

	ent = autofs_hash_lookup(dh, &dentry->d_name);
	if (!ent) {
		unlock_kernel();
		return -ENOENT;
	}

	if ((unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO) {
		unlock_kernel();
		return -ENOTDIR; /* Not a directory */
	}

	if (ent->dentry != dentry) {
		printk("autofs_rmdir: odentry != dentry for entry %s\n", dentry->d_name.name);
	}

	dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL;
	autofs_hash_delete(ent);
	drop_nlink(dir);
	d_drop(dentry);
	unlock_kernel();

	return 0;
}
Beispiel #2
0
/*
 * NOTE!
 *
 * Normal filesystems would do a "d_delete()" to tell the VFS dcache
 * that the file no longer exists. However, doing that means that the
 * VFS layer can turn the dentry into a negative dentry, which we
 * obviously do not want (we're dropping the entry not because it
 * doesn't exist, but because it has timed out).
 *
 * Also see autofs_root_rmdir()..
 */
static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
{
    struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
    struct autofs_dirhash *dh = &sbi->dirhash;
    struct autofs_dir_ent *ent;
    unsigned int n;

    /* This allows root to remove symlinks */
    if ( !autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
        return -EACCES;

    ent = autofs_hash_lookup(dh, &dentry->d_name);
    if ( !ent )
        return -ENOENT;

    n = ent->ino - AUTOFS_FIRST_SYMLINK;
    if ( n >= AUTOFS_MAX_SYMLINKS )
        return -EISDIR;	/* It's a directory, dummy */
    if ( !test_bit(n,sbi->symlink_bitmap) )
        return -EINVAL;	/* Nonexistent symlink?  Shouldn't happen */

    dentry->d_time = (unsigned long)(struct autofs_dirhash *)NULL;
    autofs_hash_delete(ent);
    clear_bit(n,sbi->symlink_bitmap);
    kfree(sbi->symlink[n].data);
    d_drop(dentry);

    return 0;
}