diff options
Diffstat (limited to 'fs/umsdos/ioctl.c')
-rw-r--r-- | fs/umsdos/ioctl.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c index 84e1f5034..f26d19ba8 100644 --- a/fs/umsdos/ioctl.c +++ b/fs/umsdos/ioctl.c @@ -78,6 +78,9 @@ int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd, struct file new_filp; struct umsdos_ioctl data; +Printk(("UMSDOS_ioctl_dir: %s/%s, cmd=%d, data=%08lx\n", +dentry->d_parent->d_name.name, dentry->d_name.name, cmd, data_ptr)); + /* forward non-umsdos ioctls - this hopefully doesn't cause conflicts */ if (cmd != UMSDOS_GETVERSION && cmd != UMSDOS_READDIR_DOS @@ -164,20 +167,19 @@ int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd, ret = PTR_ERR(demd); if (IS_ERR(demd)) goto out; + ret = 0; + if (!demd->d_inode) + goto read_dput; + fill_new_filp(&new_filp, demd); new_filp.f_pos = filp->f_pos; - - while (1) { + while (new_filp.f_pos < demd->d_inode->i_size) { off_t f_pos = new_filp.f_pos; struct umsdos_dirent entry; struct umsdos_info info; - ret = 0; - if (new_filp.f_pos >= demd->d_inode->i_size) - break; - ret = umsdos_emd_dir_readentry (&new_filp, &entry); - if (ret < 0) + if (ret) break; if (entry.name_len <= 0) continue; @@ -198,6 +200,7 @@ int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd, } /* update the original f_pos */ filp->f_pos = new_filp.f_pos; + read_dput: d_drop(demd); dput(demd); goto out; @@ -217,6 +220,8 @@ int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd, extern struct inode_operations umsdos_rdir_inode_operations; ret = umsdos_make_emd(dentry); +Printk(("UMSDOS_ioctl_dir: INIT_EMD %s/%s, ret=%d\n", +dentry->d_parent->d_name.name, dentry->d_name.name, ret)); dir->i_op = (ret == 0) ? &umsdos_dir_inode_operations : &umsdos_rdir_inode_operations; @@ -257,18 +262,18 @@ int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd, * is in the dos_dirent.name field and the destination * is in umsdos_dirent.name field. * - * This ioctl allows umssync to rename a mangle file + * This ioctl allows umssync to rename a mangled file * name before syncing it back in the EMD. */ old_dentry = umsdos_lookup_dentry (dentry, data.dos_dirent.d_name, - data.dos_dirent.d_reclen); + data.dos_dirent.d_reclen ,1); ret = PTR_ERR(old_dentry); if (IS_ERR(old_dentry)) goto out; new_dentry = umsdos_lookup_dentry (dentry, data.umsdos_dirent.name, - data.umsdos_dirent.name_len); + data.umsdos_dirent.name_len, 1); ret = PTR_ERR(new_dentry); if (!IS_ERR(new_dentry)) { printk("umsdos_ioctl: renaming %s/%s to %s/%s\n", @@ -277,7 +282,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); ret = msdos_rename (dir, old_dentry, dir, new_dentry); dput(new_dentry); } - d_drop(old_dentry); dput(old_dentry); goto out; } @@ -301,6 +305,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); data.umsdos_dirent.name_len, &info); ret = umsdos_delentry (dentry, &info, S_ISDIR (data.umsdos_dirent.mode)); + if (ret) { + printk(KERN_WARNING + "umsdos_ioctl: delentry %s/%s failed, ret=%d\n", + dentry->d_name.name, info.entry.name, ret); + } goto out; } else if (cmd == UMSDOS_UNLINK_DOS) { @@ -314,14 +323,16 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); * Return 0 if success. */ temp = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name, - data.dos_dirent.d_reclen); + data.dos_dirent.d_reclen, 1); ret = PTR_ERR(temp); if (IS_ERR(temp)) goto out; ret = -ENOENT; - if (temp->d_inode) - ret = msdos_unlink (dir, temp); - d_drop(temp); + if (temp->d_inode) { + ret = -EISDIR; + if (!S_ISDIR(temp->d_inode->i_mode)) + ret = msdos_unlink (dir, temp); + } dput (temp); goto out; } @@ -336,14 +347,16 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); * Return 0 if success. */ temp = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name, - data.dos_dirent.d_reclen); + data.dos_dirent.d_reclen, 1); ret = PTR_ERR(temp); if (IS_ERR(temp)) goto out; ret = -ENOENT; - if (temp->d_inode) - ret = msdos_rmdir (dir, temp); - d_drop(temp); + if (temp->d_inode) { + ret = -ENOTDIR; + if (S_ISDIR(temp->d_inode->i_mode)) + ret = msdos_rmdir (dir, temp); + } dput (temp); goto out; @@ -362,7 +375,7 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); struct inode *inode; dret = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name, - data.dos_dirent.d_reclen); + data.dos_dirent.d_reclen, 1); ret = PTR_ERR(dret); if (IS_ERR(dret)) goto out; @@ -380,7 +393,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); sizeof (data.stat))) ret = 0; } - d_drop(dret); dput(dret); goto out; } |