diff options
Diffstat (limited to 'fs/umsdos/rdir.c')
| -rw-r--r-- | fs/umsdos/rdir.c | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c deleted file mode 100644 index 2f32539b1a37..000000000000 --- a/fs/umsdos/rdir.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * linux/fs/umsdos/rdir.c - * - * Written 1994 by Jacques Gelinas - * - * Extended MS-DOS directory pure MS-DOS handling functions - * (For directory without EMD file). - */ - -#include <linux/time.h> -#include <linux/fs.h> -#include <linux/msdos_fs.h> -#include <linux/errno.h> -#include <linux/stat.h> -#include <linux/limits.h> -#include <linux/umsdos_fs.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> - -#include <asm/uaccess.h> - - -extern struct dentry *saved_root; -extern struct inode *pseudo_root; -extern struct dentry_operations umsdos_dentry_operations; - -struct RDIR_FILLDIR { - void *dirbuf; - filldir_t filldir; - int real_root; -}; - -static int rdir_filldir ( void *buf, - const char *name, - int name_len, - loff_t offset, - ino_t ino, - unsigned int d_type) -{ - int ret = 0; - struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR *) buf; - - if (d->real_root) { - PRINTK ((KERN_DEBUG "rdir_filldir /mn/: real root!\n")); - /* real root of a pseudo_rooted partition */ - if (name_len != UMSDOS_PSDROOT_LEN - || memcmp (name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN) != 0) { - /* So it is not the /linux directory */ - if (name_len == 2 && name[0] == '.' && name[1] == '.') { - /* Make sure the .. entry points back to the pseudo_root */ - ino = pseudo_root->i_ino; - } - ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN); - } - } else { - /* Any DOS directory */ - ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN); - } - return ret; -} - - -static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir) -{ - struct inode *dir = filp->f_dentry->d_inode; - struct RDIR_FILLDIR bufk; - int ret; - - lock_kernel(); - bufk.filldir = filldir; - bufk.dirbuf = dirbuf; - bufk.real_root = pseudo_root && (dir == saved_root->d_inode); - ret = fat_readdir (filp, &bufk, rdir_filldir); - unlock_kernel(); - return ret; -} - - -/* - * Lookup into a non promoted directory. - * If the result is a directory, make sure we find out if it is - * a promoted one or not (calling umsdos_setup_dir_inode(inode)). - */ -/* #Specification: pseudo root / DOS/.. - * In the real root directory (c:\), the directory .. - * is the pseudo root (c:\linux). - */ -struct dentry *umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo) -{ - struct dentry *ret; - - if (saved_root && dir == saved_root->d_inode && !nopseudo && - dentry->d_name.len == UMSDOS_PSDROOT_LEN && - memcmp (dentry->d_name.name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN) == 0) { - /* #Specification: pseudo root / DOS/linux - * Even in the real root directory (c:\), the directory - * /linux won't show - */ - - ret = ERR_PTR(-ENOENT); - goto out; - } - - ret = msdos_lookup (dir, dentry, NULL); - if (ret) { - printk(KERN_WARNING - "umsdos_rlookup_x: %s/%s failed, ret=%ld\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - PTR_ERR(ret)); - goto out; - } - if (dentry->d_inode) { - /* We must install the proper function table - * depending on whether this is an MS-DOS or - * a UMSDOS directory - */ -Printk ((KERN_DEBUG "umsdos_rlookup_x: patch_dentry_inode %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name)); -/* only patch if needed (because we get called even for lookup - (not only rlookup) stuff sometimes, like in umsdos_covered() */ - if (UMSDOS_I(dentry->d_inode)->i_patched == 0) - umsdos_patch_dentry_inode(dentry, 0); - - } -out: - /* always install our dentry ops ... */ - dentry->d_op = &umsdos_dentry_operations; - return ret; -} - - -struct dentry *UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry, struct nameidata *nd) -{ - return umsdos_rlookup_x (dir, dentry, 0); -} - - -/* #Specification: dual mode / rmdir in a DOS directory - * In a DOS (not EMD in it) directory, we use a reverse strategy - * compared with a 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 makes 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 subdirectories are also - * Umsdos directories, so we check the EMD file first. - */ -/* #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; -} - -/* #Specification: dual mode / introduction - * One goal of UMSDOS is to allow a practical and simple coexistence - * between MS-DOS and Linux in a single partition. Using the EMD file - * in each directory, UMSDOS adds Unix semantics and capabilities to - * a normal DOS filesystem. To help and simplify coexistence, here is - * the logic related to the EMD file. - * - * If it is missing, then the directory is managed by the MS-DOS driver. - * The names are limited to DOS limits (8.3). No links, no device special - * and pipe and so on. - * - * If it is there, it is the directory. If it is there but empty, then - * the directory looks empty. The utility umssync allows synchronisation - * of the real DOS directory and the EMD. - * - * Whenever umssync is applied to a directory without EMD, one is - * created on the fly. The directory is promoted to full Unix semantics. - * Of course, the ls command will show exactly the same content as before - * the umssync session. - * - * It is believed that the user/admin will promote directories to Unix - * semantics as needed. - * - * The strategy to implement this is to use two function table (struct - * inode_operations). One for true UMSDOS directory and one for directory - * with missing EMD. - * - * Functions related to the DOS semantic (but aware of UMSDOS) generally - * have a "r" prefix (r for real) such as UMSDOS_rlookup, to differentiate - * from the one with full UMSDOS semantics. - */ -struct file_operations umsdos_rdir_operations = -{ - .read = generic_read_dir, - .readdir = UMSDOS_rreaddir, - .ioctl = UMSDOS_ioctl_dir, -}; - -struct inode_operations umsdos_rdir_inode_operations = -{ - .create = msdos_create, - .lookup = UMSDOS_rlookup, - .unlink = msdos_unlink, - .mkdir = msdos_mkdir, - .rmdir = UMSDOS_rrmdir, - .rename = msdos_rename, - .setattr = UMSDOS_notify_change, -}; |
