/* #Specification: pseudo root / rmdir /DOS * The pseudo sub-directory /DOS can't be removed! * This is done even if the pseudo root is not a Umsdos * directory anymore (very unlikely), but an accident (under * MS-DOS) is always possible. * * EPERM is returned. */ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry) { int ret, empty; ret = -EPERM; if (umsdos_is_pseudodos (dir, dentry)) goto out; ret = -EBUSY; if (!d_unhashed(dentry)) goto out; ret = msdos_rmdir (dir, dentry); if (ret != -ENOTEMPTY) goto out; empty = umsdos_isempty (dentry); if (empty == 1) { struct dentry *demd; /* We have to remove the EMD file. */ demd = umsdos_get_emd_dentry(dentry); ret = PTR_ERR(demd); if (!IS_ERR(demd)) { ret = 0; if (demd->d_inode) ret = msdos_unlink (dentry->d_inode, demd); if (!ret) d_delete(demd); dput(demd); } } if (ret) goto out; /* now retry the original ... */ ret = msdos_rmdir (dir, dentry); out: return ret; }
static int UMSDOS_rrmdir ( struct inode *dir, const char *name, int len) { /* #Specification: dual mode / rmdir in a DOS directory In a DOS (not EMD in it) directory, we use a reverse strategy compared with an Umsdos directory. We assume that a subdirectory of a DOS directory is also a DOS directory. This is not always true (umssync may be used anywhere), but make sense. So we call msdos_rmdir() directly. If it failed with a -ENOTEMPTY then we check if it is a Umsdos directory. We check if it is really empty (only . .. and --linux-.--- in it). If it is true we remove the EMD and do a msdos_rmdir() again. In a Umsdos directory, we assume all subdirectory are also Umsdos directory, so we check the EMD file first. */ int ret; if (umsdos_is_pseudodos(dir,name,len)){ /* #Specification: pseudo root / rmdir /DOS The pseudo sub-directory /DOS can't be removed! This is done even if the pseudo root is not a Umsdos directory anymore (very unlikely), but an accident (under MsDOS) is always possible. EPERM is returned. */ ret = -EPERM; }else{ umsdos_lockcreate (dir); dir->i_count++; ret = msdos_rmdir (dir,name,len); if (ret == -ENOTEMPTY){ struct inode *sdir; dir->i_count++; ret = UMSDOS_rlookup (dir,name,len,&sdir); PRINTK (("rrmdir lookup %d ",ret)); if (ret == 0){ int empty; if ((empty = umsdos_isempty (sdir)) != 0){ PRINTK (("isempty %d i_count %d ",empty,sdir->i_count)); if (empty == 2){ /* Not a Umsdos directory, so the previous msdos_rmdir was not lying :-) */ ret = -ENOTEMPTY; }else if (empty == 1){ /* We have to removed the EMD file */ ret = msdos_unlink(sdir,UMSDOS_EMD_FILE ,UMSDOS_EMD_NAMELEN); sdir = NULL; if (ret == 0){ dir->i_count++; ret = msdos_rmdir (dir,name,len); } } }else{ ret = -ENOTEMPTY; } iput (sdir); } } umsdos_unlockcreate (dir); } iput (dir); return ret; }