diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /fs/umsdos/rdir.c | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff) |
o Merge with Linux 2.1.116.
o New Newport console code.
o New G364 console code.
Diffstat (limited to 'fs/umsdos/rdir.c')
-rw-r--r-- | fs/umsdos/rdir.c | 488 |
1 files changed, 248 insertions, 240 deletions
diff --git a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c index 612002c3b..f0252254a 100644 --- a/fs/umsdos/rdir.c +++ b/fs/umsdos/rdir.c @@ -30,276 +30,284 @@ struct RDIR_FILLDIR { int real_root; }; -static int rdir_filldir( - void * buf, - const char *name, - int name_len, - off_t offset, - ino_t ino) +static int rdir_filldir ( + void *buf, + const char *name, + int name_len, + off_t offset, + ino_t ino) { - int ret = 0; - struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR*) buf; - PRINTK ((KERN_DEBUG "rdir_filldir /mn/: entering\n")); - 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] == '.'){ + int ret = 0; + struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR *) buf; + + PRINTK ((KERN_DEBUG "rdir_filldir /mn/: entering\n")); + 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); - } - }else{ - /* Any DOS directory */ - PRINTK ((KERN_DEBUG "rdir_filldir /mn/: calling d->filldir (%p) for %.*s (%lu)\n", d->filldir, name_len, name, ino)); - ret = d->filldir (d->dirbuf, name, name_len, offset, ino); - } - return ret; + ino = pseudo_root->i_ino; + } + ret = d->filldir (d->dirbuf, name, name_len, offset, ino); + } + } else { + /* Any DOS directory */ + PRINTK ((KERN_DEBUG "rdir_filldir /mn/: calling d->filldir (%p) for %.*s (%lu)\n", d->filldir, name_len, name, ino)); + ret = d->filldir (d->dirbuf, name, name_len, offset, ino); + } + return ret; } static int UMSDOS_rreaddir ( - struct file *filp, - void *dirbuf, - filldir_t filldir) + struct file *filp, + void *dirbuf, + filldir_t filldir) { - struct RDIR_FILLDIR bufk; - struct inode *dir = filp->f_dentry->d_inode; - - PRINTK ((KERN_DEBUG "UMSDOS_rreaddir /mn/: entering %p %p\n", filldir, dirbuf)); + struct RDIR_FILLDIR bufk; + struct inode *dir = filp->f_dentry->d_inode; + + PRINTK ((KERN_DEBUG "UMSDOS_rreaddir /mn/: entering %p %p\n", filldir, dirbuf)); - - bufk.filldir = filldir; - bufk.dirbuf = dirbuf; - bufk.real_root = pseudo_root - && dir == iget(dir->i_sb,UMSDOS_ROOT_INO) - && dir == iget(pseudo_root->i_sb,UMSDOS_ROOT_INO); - PRINTK ((KERN_DEBUG "UMSDOS_rreaddir /mn/: calling fat_readdir with filldir=%p and exiting\n",filldir)); - return fat_readdir(filp, &bufk, rdir_filldir); + + bufk.filldir = filldir; + bufk.dirbuf = dirbuf; + bufk.real_root = pseudo_root + && dir == iget (dir->i_sb, UMSDOS_ROOT_INO) + && dir == iget (pseudo_root->i_sb, UMSDOS_ROOT_INO); + PRINTK ((KERN_DEBUG "UMSDOS_rreaddir /mn/: calling fat_readdir with filldir=%p and exiting\n", filldir)); + return fat_readdir (filp, &bufk, rdir_filldir); } /* - 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)). -*/ -int umsdos_rlookup_x( - struct inode *dir, - struct dentry *dentry, - int nopseudo) /* Don't care about pseudo root mode */ - /* so locating "linux" will work */ -{ - int len = dentry->d_name.len; - const char *name = dentry->d_name.name; - struct inode *inode; - int ret; - if (pseudo_root - && len == 2 - && name[0] == '.' - && name[1] == '.' - && dir == iget(dir->i_sb,UMSDOS_ROOT_INO) - && dir == iget(pseudo_root->i_sb,UMSDOS_ROOT_INO) ){ - /* *result = pseudo_root;*/ - Printk ((KERN_WARNING "umsdos_rlookup_x: we are at pseudo-root thingy?\n")); - pseudo_root->i_count++; - ret = 0; - /* #Specification: pseudo root / DOS/.. - In the real root directory (c:\), the directory .. - is the pseudo root (c:\linux). - */ - }else{ - ret = umsdos_real_lookup (dir, dentry); inode=dentry->d_inode; + * 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)). + */ +int umsdos_rlookup_x ( + struct inode *dir, + struct dentry *dentry, + int nopseudo) +{ /* Don't care about pseudo root mode */ + /* so locating "linux" will work */ + int len = dentry->d_name.len; + const char *name = dentry->d_name.name; + struct inode *inode; + int ret; + + if (pseudo_root + && len == 2 + && name[0] == '.' + && name[1] == '.' + && dir == iget (dir->i_sb, UMSDOS_ROOT_INO) + && dir == iget (pseudo_root->i_sb, UMSDOS_ROOT_INO)) { + /* *result = pseudo_root; */ + Printk ((KERN_WARNING "umsdos_rlookup_x: we are at pseudo-root thingy?\n")); + inc_count (pseudo_root); + ret = 0; + /* #Specification: pseudo root / DOS/.. + * In the real root directory (c:\), the directory .. + * is the pseudo root (c:\linux). + */ + } else { + ret = umsdos_real_lookup (dir, dentry); + inode = dentry->d_inode; #if 0 - Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup for %.*s in %lu returned %d\n", len, name, dir->i_ino, ret)); - Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup: inode is %p resolving to ", inode)); - if (inode) { /* /mn/ FIXME: DEL_ME */ - Printk ((KERN_DEBUG "i_ino=%lu\n", inode->i_ino)); - } else { - Printk ((KERN_DEBUG "NONE!\n")); - } + Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup for %.*s in %lu returned %d\n", len, name, dir->i_ino, ret)); + Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup: inode is %p resolving to ", inode)); + if (inode) { /* /mn/ FIXME: DEL_ME */ + Printk ((KERN_DEBUG "i_ino=%lu\n", inode->i_ino)); + } else { + Printk ((KERN_DEBUG "NONE!\n")); + } #endif - - if ((ret == 0) && inode){ - - if (pseudo_root && inode == pseudo_root && !nopseudo){ - /* #Specification: pseudo root / DOS/linux - Even in the real root directory (c:\), the directory - /linux won't show - */ - Printk ((KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n")); - ret = -ENOENT; - /* iput (pseudo_root); FIXME */ - - }else if (S_ISDIR(inode->i_mode)){ - /* We must place the proper function table */ - /* depending if this is a MsDOS directory or an UMSDOS directory */ - Printk ((KERN_DEBUG "umsdos_rlookup_x: setting up setup_dir_inode %lu...\n", inode->i_ino)); - umsdos_setup_dir_inode (inode); - } - } - } - /* iput (dir); FIXME */ - PRINTK ((KERN_DEBUG "umsdos_rlookup_x: returning %d\n", ret)); - return ret; + + if ((ret == 0) && inode) { + + if (pseudo_root && inode == pseudo_root && !nopseudo) { + /* #Specification: pseudo root / DOS/linux + * Even in the real root directory (c:\), the directory + * /linux won't show + */ + Printk ((KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n")); + ret = -ENOENT; + iput (pseudo_root); /* FIXME? */ + + } else if (S_ISDIR (inode->i_mode)) { + /* We must place the proper function table */ + /* depending if this is a MsDOS directory or an UMSDOS directory */ + Printk ((KERN_DEBUG "umsdos_rlookup_x: setting up setup_dir_inode %lu...\n", inode->i_ino)); + umsdos_setup_dir_inode (inode); + } + } + } + iput (dir); /* FIXME? */ + PRINTK ((KERN_DEBUG "umsdos_rlookup_x: returning %d\n", ret)); + return ret; } -int UMSDOS_rlookup( - struct inode *dir, - struct dentry *dentry - ) +int UMSDOS_rlookup ( + struct inode *dir, + struct dentry *dentry +) { - PRINTK ((KERN_DEBUG "UMSDOS_rlookup /mn/: executing umsdos_rlookup_x for ino=%lu in %.*s\n", dir->i_ino, (int) dentry->d_name.len, dentry->d_name.name)); - return umsdos_rlookup_x(dir,dentry,0); + PRINTK ((KERN_DEBUG "UMSDOS_rlookup /mn/: executing umsdos_rlookup_x for ino=%lu in %.*s\n", dir->i_ino, (int) dentry->d_name.len, dentry->d_name.name)); + return umsdos_rlookup_x (dir, dentry, 0); } static int UMSDOS_rrmdir ( - struct inode *dir, - struct dentry *dentry) + struct inode *dir, + struct dentry *dentry) { - /* #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. + /* #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; - 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,dentry)){ - /* #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,dentry); - if (ret == -ENOTEMPTY){ - struct inode *sdir; - dir->i_count++; - - ret = UMSDOS_rlookup (dir,dentry); - sdir = dentry->d_inode; - PRINTK (("rrmdir lookup %d ",ret)); - if (ret == 0){ - int empty; - if ((empty = umsdos_isempty (sdir)) != 0){ - PRINTK (("isempty %d i_count %d ",empty, - atomic_read(&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 */ - struct dentry *temp; - temp = creat_dentry (UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN, NULL, NULL); /* FIXME: prolly should fill inode part ? */ - ret = msdos_unlink(sdir, temp); - sdir = NULL; - if (ret == 0){ - dir->i_count++; - ret = msdos_rmdir (dir,dentry); - } - } - }else{ - ret = -ENOTEMPTY; - } - /* iput (sdir); FIXME */ - } - } - umsdos_unlockcreate (dir); - } - /* iput (dir); FIXME */ - return ret; -} - -/* #Specification: dual mode / introduction - One goal of UMSDOS is to allow a practical and simple coexistence - between MsDOS and Linux in a single partition. Using the EMD file - in each directory, UMSDOS add Unix semantics and capabilities to - normal DOS file system. 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 MsDOS driver. - The names are limited to DOS limits (8.3). No links, no device special - and pipe and so on. + if (umsdos_is_pseudodos (dir, dentry)) { + /* #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); + inc_count (dir); + ret = msdos_rmdir (dir, dentry); + if (ret == -ENOTEMPTY) { + struct inode *sdir; - 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. + inc_count (dir); - Whenever umssync is applied to a directory without EMD, one is - created on the fly. The directory is promoted to full unix semantic. - Of course, the ls command will show exactly the same content as before - the umssync session. + ret = UMSDOS_rlookup (dir, dentry); + sdir = dentry->d_inode; + PRINTK (("rrmdir lookup %d ", ret)); + if (ret == 0) { + int empty; - It is believed that the user/admin will promote directories to unix - semantic as needed. + if ((empty = umsdos_isempty (sdir)) != 0) { + PRINTK (("isempty %d i_count %d ", empty, + atomic_read (&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 */ + struct dentry *temp; - 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. + Printk ((KERN_WARNING "UMSDOS_rmdir: hmmm... whatabout inode ? FIXME\n")); + temp = creat_dentry (UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN, NULL, NULL); /* FIXME: prolly should fill inode part ? */ + ret = msdos_unlink (sdir, temp); + sdir = NULL; + if (ret == 0) { + inc_count (dir); + ret = msdos_rmdir (dir, dentry); + } + } + } else { + ret = -ENOTEMPTY; + } + /* iput (sdir); FIXME */ + } + } + umsdos_unlockcreate (dir); + } + /* iput (dir); FIXME */ + return ret; +} - 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 semantic. -*/ -static struct file_operations umsdos_rdir_operations = { - NULL, /* lseek - default */ - UMSDOS_dir_read, /* read */ - NULL, /* write - bad */ - UMSDOS_rreaddir, /* readdir */ - NULL, /* poll - default */ - UMSDOS_ioctl_dir, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - NULL /* fsync */ +/* #Specification: dual mode / introduction + * One goal of UMSDOS is to allow a practical and simple coexistence + * between MsDOS and Linux in a single partition. Using the EMD file + * in each directory, UMSDOS add Unix semantics and capabilities to + * normal DOS file system. 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 MsDOS 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 semantic. + * 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 + * semantic 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 semantic. + */ +static struct file_operations umsdos_rdir_operations = +{ + NULL, /* lseek - default */ + UMSDOS_dir_read, /* read */ + NULL, /* write - bad */ + UMSDOS_rreaddir, /* readdir */ + NULL, /* poll - default */ + UMSDOS_ioctl_dir, /* ioctl - default */ + NULL, /* mmap */ + NULL, /* no special open code */ + NULL, /* no special release code */ + NULL /* fsync */ }; -struct inode_operations umsdos_rdir_inode_operations = { - &umsdos_rdir_operations, /* default directory file-ops */ - msdos_create, /* create */ - UMSDOS_rlookup, /* lookup */ - NULL, /* link */ - msdos_unlink, /* unlink */ - NULL, /* symlink */ - msdos_mkdir, /* mkdir */ - UMSDOS_rrmdir, /* rmdir */ - NULL, /* mknod */ - msdos_rename, /* rename */ - NULL, /* readlink */ - NULL, /* followlink */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL, /* updatepage */ - NULL, /* revalidate */ +struct inode_operations umsdos_rdir_inode_operations = +{ + &umsdos_rdir_operations, /* default directory file-ops */ + msdos_create, /* create */ + UMSDOS_rlookup, /* lookup */ + NULL, /* link */ + msdos_unlink, /* unlink */ + NULL, /* symlink */ + msdos_mkdir, /* mkdir */ + UMSDOS_rrmdir, /* rmdir */ + NULL, /* mknod */ + msdos_rename, /* rename */ + NULL, /* readlink */ + NULL, /* followlink */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ }; - - |