ARM: 6165/1: trap overflows on highmem pages from kmap_atomic when debugging
[safe/jmp/linux-2.6] / fs / udf / symlink.c
index 674bb40..1606478 100644 (file)
@@ -11,7 +11,7 @@
  *     Each contributing author retains all rights to their own work.
  *
  *  (C) 1998-2001 Ben Fennema
- *  (C) 1999 Stelias Computing Inc 
+ *  (C) 1999 Stelias Computing Inc
  *
  * HISTORY
  *
 #include <asm/uaccess.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/udf_fs.h>
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include "udf_i.h"
 
-static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to)
+static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
+                          int fromlen, unsigned char *to)
 {
        struct pathComponent *pc;
        int elen = 0;
-       char *p = to;
+       unsigned char *p = to;
 
-       while (elen < fromlen)
-       {
+       while (elen < fromlen) {
                pc = (struct pathComponent *)(from + elen);
-               switch (pc->componentType)
-               {
-                       case 1:
-                               if (pc->lengthComponentIdent == 0)
-                               {
-                                       p = to;
-                                       *p++ = '/';
-                               }
-                               break;
-                       case 3:
-                               memcpy(p, "../", 3);
-                               p += 3;
-                               break;
-                       case 4:
-                               memcpy(p, "./", 2);
-                               p += 2;
-                               /* that would be . - just ignore */
-                               break;
-                       case 5:
-                               p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);
+               switch (pc->componentType) {
+               case 1:
+                       if (pc->lengthComponentIdent == 0) {
+                               p = to;
                                *p++ = '/';
-                               break;
+                       }
+                       break;
+               case 3:
+                       memcpy(p, "../", 3);
+                       p += 3;
+                       break;
+               case 4:
+                       memcpy(p, "./", 2);
+                       p += 2;
+                       /* that would be . - just ignore */
+                       break;
+               case 5:
+                       p += udf_get_filename(sb, pc->componentIdent, p,
+                                             pc->lengthComponentIdent);
+                       *p++ = '/';
+                       break;
                }
                elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
        }
-       if (p > to+1)
+       if (p > to + 1)
                p[-1] = '\0';
        else
                p[0] = '\0';
@@ -77,15 +74,16 @@ static int udf_symlink_filler(struct file *file, struct page *page)
 {
        struct inode *inode = page->mapping->host;
        struct buffer_head *bh = NULL;
-       char *symlink;
+       unsigned char *symlink;
        int err = -EIO;
-       char *p = kmap(page);
+       unsigned char *p = kmap(page);
+       struct udf_inode_info *iinfo;
 
        lock_kernel();
-       if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
-               symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
-       else
-       {
+       iinfo = UDF_I(inode);
+       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+               symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
+       } else {
                bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
 
                if (!bh)
@@ -95,13 +93,14 @@ static int udf_symlink_filler(struct file *file, struct page *page)
        }
 
        udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
-       udf_release_data(bh);
+       brelse(bh);
 
        unlock_kernel();
        SetPageUptodate(page);
        kunmap(page);
        unlock_page(page);
        return 0;
+
 out:
        unlock_kernel();
        SetPageError(page);
@@ -113,6 +112,6 @@ out:
 /*
  * symlinks can't do much...
  */
-struct address_space_operations udf_symlink_aops = {
+const struct address_space_operations udf_symlink_aops = {
        .readpage               = udf_symlink_filler,
 };