Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / isofs / namei.c
index 8d525f6..e7ba0c3 100644 (file)
@@ -6,19 +6,9 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <linux/time.h>
-#include <linux/iso_fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
 #include <linux/config.h>      /* Joliet? */
 #include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
-
-#include <asm/uaccess.h>
+#include "isofs.h"
 
 /*
  * ok, we cannot use strncmp, as the name is not in our data space.
@@ -59,12 +49,12 @@ isofs_cmp(struct dentry * dentry, const char * compare, int dlen)
  */
 static unsigned long
 isofs_find_entry(struct inode *dir, struct dentry *dentry,
+       unsigned long *block_rv, unsigned long* offset_rv,
        char * tmpname, struct iso_directory_record * tmpde)
 {
-       unsigned long inode_number;
        unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
        unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
-       unsigned int block, f_pos, offset;
+       unsigned long block, f_pos, offset, block_saved, offset_saved;
        struct buffer_head * bh = NULL;
        struct isofs_sb_info *sbi = ISOFS_SB(dir->i_sb);
 
@@ -87,7 +77,6 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
                }
 
                de = (struct iso_directory_record *) (bh->b_data + offset);
-               inode_number = (bh->b_blocknr << bufbits) + offset;
 
                de_len = *(unsigned char *) de;
                if (!de_len) {
@@ -99,6 +88,8 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
                        continue;
                }
 
+               block_saved = bh->b_blocknr;
+               offset_saved = offset;
                offset += de_len;
                f_pos += de_len;
 
@@ -140,27 +131,35 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
                }
 
                /*
-                * Skip hidden or associated files unless unhide is set 
+                * Skip hidden or associated files unless hide or showassoc,
+                * respectively, is set
                 */
                match = 0;
                if (dlen > 0 &&
-                   (!(de->flags[-sbi->s_high_sierra] & 5)
-                    || sbi->s_unhide == 'y'))
-               {
-                       match = (isofs_cmp(dentry,dpnt,dlen) == 0);
+                       (sbi->s_hide =='n' ||
+                               (!(de->flags[-sbi->s_high_sierra] & 1))) &&
+                       (sbi->s_showassoc =='y' ||
+                               (!(de->flags[-sbi->s_high_sierra] & 4)))) {
+                       match = (isofs_cmp(dentry, dpnt, dlen) == 0);
                }
                if (match) {
-                       if (bh) brelse(bh);
-                       return inode_number;
+                       isofs_normalize_block_and_offset(de,
+                                                        &block_saved,
+                                                        &offset_saved);
+                        *block_rv = block_saved;
+                        *offset_rv = offset_saved;
+                       brelse(bh);
+                       return 1;
                }
        }
-       if (bh) brelse(bh);
+       brelse(bh);
        return 0;
 }
 
 struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
 {
-       unsigned long ino;
+       int found;
+       unsigned long block, offset;
        struct inode *inode;
        struct page *page;
 
@@ -171,19 +170,20 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct n
                return ERR_PTR(-ENOMEM);
 
        lock_kernel();
-       ino = isofs_find_entry(dir, dentry, page_address(page),
-                              1024 + page_address(page));
+       found = isofs_find_entry(dir, dentry,
+                                &block, &offset,
+                                page_address(page),
+                                1024 + page_address(page));
        __free_page(page);
 
        inode = NULL;
-       if (ino) {
-               inode = iget(dir->i_sb, ino);
+       if (found) {
+               inode = isofs_iget(dir->i_sb, block, offset);
                if (!inode) {
                        unlock_kernel();
                        return ERR_PTR(-EACCES);
                }
        }
        unlock_kernel();
-       d_add(dentry, inode);
-       return NULL;
+       return d_splice_alias(inode, dentry);
 }