nfsd4: set shorter timeout
[safe/jmp/linux-2.6] / fs / isofs / dir.c
index 6030956..2f0dc5a 100644 (file)
@@ -7,35 +7,18 @@
  *
  *  Steve Beynon                      : Missing last directory entries fixed
  *  (stephen@askone.demon.co.uk)      : 21st June 1996
- * 
+ *
  *  isofs directory handling functions
  */
-#include <linux/config.h>
 #include <linux/smp_lock.h>
 #include "isofs.h"
 
-static int isofs_readdir(struct file *, void *, filldir_t);
-
-struct file_operations isofs_dir_operations =
-{
-       .read           = generic_read_dir,
-       .readdir        = isofs_readdir,
-};
-
-/*
- * directories can handle most operations...
- */
-struct inode_operations isofs_dir_inode_operations =
-{
-       .lookup         = isofs_lookup,
-};
-
 int isofs_name_translate(struct iso_directory_record *de, char *new, struct inode *inode)
 {
        char * old = de->name;
        int len = de->name_len[0];
        int i;
-                       
+
        for (i = 0; i < len; i++) {
                unsigned char c = old[i];
                if (!c)
@@ -63,22 +46,27 @@ int isofs_name_translate(struct iso_directory_record *de, char *new, struct inod
 }
 
 /* Acorn extensions written by Matthew Wilcox <willy@bofh.ai> 1998 */
-int get_acorn_filename(struct iso_directory_record * de,
-                           char * retname, struct inode * inode)
+int get_acorn_filename(struct iso_directory_record *de,
+                           char *retname, struct inode *inode)
 {
        int std;
-       unsigned char * chr;
+       unsigned char *chr;
        int retnamlen = isofs_name_translate(de, retname, inode);
-       if (retnamlen == 0) return 0;
+
+       if (retnamlen == 0)
+               return 0;
        std = sizeof(struct iso_directory_record) + de->name_len[0];
-       if (std & 1) std++;
-       if ((*((unsigned char *) de) - std) != 32) return retnamlen;
+       if (std & 1)
+               std++;
+       if ((*((unsigned char *) de) - std) != 32)
+               return retnamlen;
        chr = ((unsigned char *) de) + std;
-       if (strncmp(chr, "ARCHIMEDES", 10)) return retnamlen;
-       if ((*retname == '_') && ((chr[19] & 1) == 1)) *retname = '!';
+       if (strncmp(chr, "ARCHIMEDES", 10))
+               return retnamlen;
+       if ((*retname == '_') && ((chr[19] & 1) == 1))
+               *retname = '!';
        if (((de->flags[0] & 2) == 0) && (chr[13] == 0xff)
-               && ((chr[12] & 0xf0) == 0xf0))
-       {
+               && ((chr[12] & 0xf0) == 0xf0)) {
                retname[retnamlen] = ',';
                sprintf(retname+retnamlen+1, "%3.3x",
                        ((chr[12] & 0xf) << 8) | chr[11]);
@@ -92,7 +80,7 @@ int get_acorn_filename(struct iso_directory_record * de,
  */
 static int do_isofs_readdir(struct inode *inode, struct file *filp,
                void *dirent, filldir_t filldir,
-               char * tmpname, struct iso_directory_record * tmpde)
+               char *tmpname, struct iso_directory_record *tmpde)
 {
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
        unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
@@ -122,9 +110,11 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                de_len = *(unsigned char *) de;
 
-               /* If the length byte is zero, we should move on to the next
-                  CDROM sector.  If we are at the end of the directory, we
-                  kick out of the while loop. */
+               /*
+                * If the length byte is zero, we should move on to the next
+                * CDROM sector.  If we are at the end of the directory, we
+                * kick out of the while loop.
+                */
 
                if (de_len == 0) {
                        brelse(bh);
@@ -155,14 +145,21 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                        }
                        de = tmpde;
                }
+               /* Basic sanity check, whether name doesn't exceed dir entry */
+               if (de_len < de->name_len[0] +
+                                       sizeof(struct iso_directory_record)) {
+                       printk(KERN_NOTICE "iso9660: Corrupted directory entry"
+                              " in block %lu of inode %lu\n", block,
+                              inode->i_ino);
+                       return -EIO;
+               }
 
                if (first_de) {
                        isofs_normalize_block_and_offset(de,
-                                                        &block_saved,
-                                                        &offset_saved);
+                                                       &block_saved,
+                                                       &offset_saved);
                        inode_number = isofs_get_ino(block_saved,
-                                                    offset_saved,
-                                                    bufbits);
+                                                       offset_saved, bufbits);
                }
 
                if (de->flags[-sbi->s_high_sierra] & 0x80) {
@@ -184,7 +181,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                /* Handle the case of the '..' directory */
                if (de->name_len[0] == 1 && de->name[0] == 1) {
-                       inode_number = parent_ino(filp->f_dentry);
+                       inode_number = parent_ino(filp->f_path.dentry);
                        if (filldir(dirent, "..", 2, filp->f_pos, inode_number, DT_DIR) < 0)
                                break;
                        filp->f_pos += de_len;
@@ -193,12 +190,17 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                /* Handle everything else.  Do name translation if there
                   is no Rock Ridge NM field. */
-               if (sbi->s_unhide == 'n') {
-                       /* Do not report hidden or associated files */
-                       if (de->flags[-sbi->s_high_sierra] & 5) {
-                               filp->f_pos += de_len;
-                               continue;
-                       }
+
+               /*
+                * Do not report hidden files if so instructed, or associated
+                * files unless instructed to do so
+                */
+               if ((sbi->s_hide == 'y' &&
+                               (de->flags[-sbi->s_high_sierra] & 1)) ||
+                               (sbi->s_showassoc =='n' &&
+                               (de->flags[-sbi->s_high_sierra] & 4))) {
+                       filp->f_pos += de_len;
+                       continue;
                }
 
                map = 1;
@@ -236,7 +238,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                continue;
        }
-       if (bh) brelse(bh);
+       if (bh)
+               brelse(bh);
        return 0;
 }
 
@@ -249,10 +252,9 @@ static int isofs_readdir(struct file *filp,
                void *dirent, filldir_t filldir)
 {
        int result;
-       char * tmpname;
-       struct iso_directory_record * tmpde;
-       struct inode *inode = filp->f_dentry->d_inode;
-
+       char *tmpname;
+       struct iso_directory_record *tmpde;
+       struct inode *inode = filp->f_path.dentry->d_inode;
 
        tmpname = (char *)__get_free_page(GFP_KERNEL);
        if (tmpname == NULL)
@@ -267,3 +269,19 @@ static int isofs_readdir(struct file *filp,
        unlock_kernel();
        return result;
 }
+
+const struct file_operations isofs_dir_operations =
+{
+       .read = generic_read_dir,
+       .readdir = isofs_readdir,
+};
+
+/*
+ * directories can handle most operations...
+ */
+const struct inode_operations isofs_dir_inode_operations =
+{
+       .lookup = isofs_lookup,
+};
+
+