Correct rmdir behavior

From: Britt Park (britt@drscience.sciencething.org)
Date: Sun Dec 16 2001 - 12:41:53 EST


I'm in the process of revivifying a user space filesystem I wrote for
2.0 kernels several years ago. I have a simple pass through
filesystem basically working. However, if I run a busy loop such as

while true
do
    ls -l >/dev/null
done

in a directory within the filesystem and then do a rmdir on that
directory, strange behavior follows. The directory is indeed removed.
I can then create a new directory with the same name as the deleted
directory, but if I then try to create any files or directories within
the new directory I fail. VFS traffic shows that lookups are made for
the files or directories I try to create but no create or mkdir calls.
It appears that some artifacts are left either in the inode cache or
the dentry cache. I'm not sure, but I believe that the problem lies in
my inode_operations::rmdir function which I list below. If I insert a

if (!d_unhashed(entry))
{
    return -EBUSY;
}

into the code, as coda does, I am forbidden from deleting a directory
in which processes are active. Any clues as to how to handle rmdir so
that I get ext2 behavior? TIA for any help.

Britt

int uvfs_rmdir(struct inode* dir, struct dentry* entry)
{
    int i;
    int slot;
    int error = 0;
    uvfs_rmdir_req_s* request;
    uvfs_rmdir_rep_s* reply;
    
    spin_lock(&Uvfs_lock);
    /* Grabs a communications slot. */
    slot = uvfs_find_accepting_slot();
    if (slot < 0)
    {
        spin_unlock(&Uvfs_lock);
        return slot;
    }
    
    request = &Uvfs_slots[slot].request.rmdir;
    request->type = UVFS_RMDIR;
    request->slot = slot;
    request->size = sizeof(*request);
    request->dir_inode = dir->i_ino;
    memcpy(request->name, entry->d_name.name, entry->d_name.len);
    request->namelen = entry->d_name.len;
    
    wake_up_interruptible(&Uvfs_slots[slot].driver_queue);
    /* This is just an unrolled version of interruptible_sleep_on */
    safe_sleep_on(&Uvfs_slots[slot].fs_queue, &Uvfs_lock);
    
    if (signal_pending(current))
    {
        error = -ERESTARTSYS;
        goto out;
    }

    reply = &Uvfs_slots[slot].reply.rmdir;
    error = reply->error;
    if (error == 0)
    {
        entry->d_inode->i_nlink = 0;
        d_drop(entry);
    }
out:
    /* Releases communication slot */
    uvfs_empty_slot(slot);
    spin_unlock(&Uvfs_lock);
    dprintk("<1>Exited uvfs_rmdir. %d\n", error);
    return error;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Dec 23 2001 - 21:00:11 EST