fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / udf / super.c
index 54e1ecf..b34a054 100644 (file)
  *    http://www.ecma.ch/
  *    http://www.iso.org/
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *       linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
@@ -45,7 +40,6 @@
 
 #include "udfdecl.h"    
 
-#include <linux/config.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
@@ -85,24 +79,24 @@ static void udf_write_super(struct super_block *);
 static int udf_remount_fs(struct super_block *, int *, char *);
 static int udf_check_valid(struct super_block *, int, int);
 static int udf_vrs(struct super_block *sb, int silent);
-static int udf_load_partition(struct super_block *, lb_addr *);
-static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
-static void udf_load_logicalvolint(struct super_block *, extent_ad);
+static int udf_load_partition(struct super_block *, kernel_lb_addr *);
+static int udf_load_logicalvol(struct super_block *, struct buffer_head *, kernel_lb_addr *);
+static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
 static void udf_find_anchor(struct super_block *);
-static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
+static int udf_find_fileset(struct super_block *, kernel_lb_addr *, kernel_lb_addr *);
 static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
-static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
+static void udf_load_fileset(struct super_block *, struct buffer_head *, kernel_lb_addr *);
 static void udf_load_partdesc(struct super_block *, struct buffer_head *);
 static void udf_open_lvid(struct super_block *);
 static void udf_close_lvid(struct super_block *);
 static unsigned int udf_count_free(struct super_block *);
-static int udf_statfs(struct super_block *, struct kstatfs *);
+static int udf_statfs(struct dentry *, struct kstatfs *);
 
 /* UDF filesystem type */
-static struct super_block *udf_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int udf_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt);
 }
 
 static struct file_system_type udf_fstype = {
@@ -113,14 +107,21 @@ static struct file_system_type udf_fstype = {
        .fs_flags       = FS_REQUIRES_DEV,
 };
 
-static kmem_cache_t * udf_inode_cachep;
+static struct kmem_cache * udf_inode_cachep;
 
 static struct inode *udf_alloc_inode(struct super_block *sb)
 {
        struct udf_inode_info *ei;
-       ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL);
+       ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
+
+       ei->i_unique = 0;
+       ei->i_lenExtents = 0;
+       ei->i_next_alloc_block = 0;
+       ei->i_next_alloc_goal = 0;
+       ei->i_strat4096 = 0;
+
        return &ei->vfs_inode;
 }
 
@@ -129,7 +130,7 @@ static void udf_destroy_inode(struct inode *inode)
        kmem_cache_free(udf_inode_cachep, UDF_I(inode));
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
 {
        struct udf_inode_info *ei = (struct udf_inode_info *) foo;
 
@@ -145,7 +146,8 @@ static int init_inodecache(void)
 {
        udf_inode_cachep = kmem_cache_create("udf_inode_cache",
                                             sizeof(struct udf_inode_info),
-                                            0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (udf_inode_cachep == NULL)
                return -ENOMEM;
@@ -154,17 +156,14 @@ static int init_inodecache(void)
 
 static void destroy_inodecache(void)
 {
-       if (kmem_cache_destroy(udf_inode_cachep))
-               printk(KERN_INFO "udf_inode_cache: not all structures were freed\n");
+       kmem_cache_destroy(udf_inode_cachep);
 }
 
 /* Superblock operations */
 static struct super_operations udf_sb_ops = {
        .alloc_inode            = udf_alloc_inode,
        .destroy_inode          = udf_destroy_inode,
-       .read_inode             = udf_read_inode,
        .write_inode            = udf_write_inode,
-       .put_inode              = udf_put_inode,
        .delete_inode           = udf_delete_inode,
        .clear_inode            = udf_clear_inode,
        .put_super              = udf_put_super,
@@ -194,7 +193,6 @@ struct udf_options
 static int __init init_udf_fs(void)
 {
        int err;
-       printk(KERN_NOTICE "udf: registering filesystem\n");
        err = init_inodecache();
        if (err)
                goto out1;
@@ -210,7 +208,6 @@ out1:
 
 static void __exit exit_udf_fs(void)
 {
-       printk(KERN_NOTICE "udf: unregistering filesystem\n");
        unregister_filesystem(&udf_fstype);
        destroy_inodecache();
 }
@@ -278,7 +275,7 @@ enum {
        Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
        Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
        Opt_rootdir, Opt_utf8, Opt_iocharset,
-       Opt_err
+       Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
 };
 
 static match_table_t tokens = {
@@ -291,6 +288,10 @@ static match_table_t tokens = {
        {Opt_adinicb, "adinicb"},
        {Opt_shortad, "shortad"},
        {Opt_longad, "longad"},
+       {Opt_uforget, "uid=forget"},
+       {Opt_uignore, "uid=ignore"},
+       {Opt_gforget, "gid=forget"},
+       {Opt_gignore, "gid=ignore"},
        {Opt_gid, "gid=%u"},
        {Opt_uid, "uid=%u"},
        {Opt_umask, "umask=%o"},
@@ -423,6 +424,18 @@ udf_parse_options(char *options, struct udf_options *uopt)
                                uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
                                break;
 #endif
+                       case Opt_uignore:
+                               uopt->flags |= (1 << UDF_FLAG_UID_IGNORE);
+                               break;
+                       case Opt_uforget:
+                               uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
+                               break;
+                       case Opt_gignore:
+                           uopt->flags |= (1 << UDF_FLAG_GID_IGNORE);
+                               break;
+                       case Opt_gforget:
+                           uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
+                               break;
                        default:
                                printk(KERN_ERR "udf: bad mount option \"%s\" "
                                                "or missing value\n", p);
@@ -552,7 +565,7 @@ udf_vrs(struct super_block *sb, int silent)
 
                if (vsd->stdIdent[0] == 0)
                {
-                       udf_release_data(bh);
+                       brelse(bh);
                        break;
                }
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
@@ -585,7 +598,7 @@ udf_vrs(struct super_block *sb, int silent)
                }
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
                {
-                       udf_release_data(bh);
+                       brelse(bh);
                        break;
                }
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
@@ -596,7 +609,7 @@ udf_vrs(struct super_block *sb, int silent)
                {
                        nsr03 = sector;
                }
-               udf_release_data(bh);
+               brelse(bh);
        }
 
        if (nsr03)
@@ -653,8 +666,7 @@ udf_find_anchor(struct super_block *sb)
                 *     lastblock
                 *  however, if the disc isn't closed, it could be 512 */
 
-               for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
-               {
+               for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) {
                        if (last[i] < 0 || !(bh = sb_bread(sb, last[i])))
                        {
                                ident = location = 0;
@@ -663,9 +675,9 @@ udf_find_anchor(struct super_block *sb)
                        {
                                ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
                                location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
-                               udf_release_data(bh);
+                               brelse(bh);
                        }
-       
+
                        if (ident == TAG_IDENT_AVDP)
                        {
                                if (location == last[i] - UDF_SB_SESSION(sb))
@@ -698,7 +710,7 @@ udf_find_anchor(struct super_block *sb)
                                {
                                        ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
                                        location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
-                                       udf_release_data(bh);
+                                       brelse(bh);
                                }
        
                                if (ident == TAG_IDENT_AVDP &&
@@ -717,7 +729,7 @@ udf_find_anchor(struct super_block *sb)
                                        {
                                                ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
                                                location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
-                                               udf_release_data(bh);
+                                               brelse(bh);
                                        }
        
                                        if (ident == TAG_IDENT_AVDP &&
@@ -739,15 +751,14 @@ udf_find_anchor(struct super_block *sb)
                {
                        ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
                        location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
-                       udf_release_data(bh);
+                       brelse(bh);
 
                        if (ident == TAG_IDENT_AVDP && location == 256)
                                UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
                }
        }
 
-       for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
-       {
+       for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {
                if (UDF_SB_ANCHOR(sb)[i])
                {
                        if (!(bh = udf_read_tagged(sb,
@@ -757,7 +768,7 @@ udf_find_anchor(struct super_block *sb)
                        }
                        else
                        {
-                               udf_release_data(bh);
+                               brelse(bh);
                                if ((ident != TAG_IDENT_AVDP) && (i ||
                                        (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
                                {
@@ -771,7 +782,7 @@ udf_find_anchor(struct super_block *sb)
 }
 
 static int 
-udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
+udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr *root)
 {
        struct buffer_head *bh = NULL;
        long lastblock;
@@ -786,7 +797,7 @@ udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
                        return 1;
                else if (ident != TAG_IDENT_FSD)
                {
-                       udf_release_data(bh);
+                       brelse(bh);
                        return 1;
                }
                        
@@ -794,7 +805,7 @@ udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
 
        if (!bh) /* Search backwards through the partitions */
        {
-               lb_addr newfileset;
+               kernel_lb_addr newfileset;
 
                return 1;
                
@@ -825,7 +836,7 @@ udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
                                                newfileset.logicalBlockNum += 1 +
                                                        ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
                                                                >> sb->s_blocksize_bits);
-                                               udf_release_data(bh);
+                                               brelse(bh);
                                                break;
                                        }
                                        case TAG_IDENT_FSD:
@@ -836,7 +847,7 @@ udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
                                        default:
                                        {
                                                newfileset.logicalBlockNum ++;
-                                               udf_release_data(bh);
+                                               brelse(bh);
                                                bh = NULL;
                                                break;
                                        }
@@ -856,7 +867,7 @@ udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
 
                UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
                udf_load_fileset(sb, bh, root);
-               udf_release_data(bh);
+               brelse(bh);
                return 0;
        }
        return 1;
@@ -876,7 +887,7 @@ udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
        if ( udf_stamp_to_time(&recording, &recording_usec,
                lets_to_cpu(pvoldesc->recordingDateAndTime)) )
        {
-               timestamp ts;
+               kernel_timestamp ts;
                ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
                udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
                        recording, recording_usec,
@@ -903,7 +914,7 @@ udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
 }
 
 static void 
-udf_load_fileset(struct super_block *sb, struct buffer_head *bh, lb_addr *root)
+udf_load_fileset(struct super_block *sb, struct buffer_head *bh, kernel_lb_addr *root)
 {
        struct fileSetDesc *fset;
 
@@ -950,7 +961,7 @@ udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
                                phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);
                                if (phd->unallocSpaceTable.extLength)
                                {
-                                       lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i };
+                                       kernel_lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i };
 
                                        UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
                                                udf_iget(sb, loc);
@@ -976,7 +987,7 @@ udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
                                        udf_debug("partitionIntegrityTable (part %d)\n", i);
                                if (phd->freedSpaceTable.extLength)
                                {
-                                       lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i };
+                                       kernel_lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i };
 
                                        UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
                                                udf_iget(sb, loc);
@@ -1015,7 +1026,7 @@ udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
 }
 
 static int 
-udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset)
+udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_addr *fileset)
 {
        struct logicalVolDesc *lvd;
        int i, j, offset;
@@ -1043,12 +1054,12 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fi
                        struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);
                        if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
                        {
-                               if (le16_to_cpu(((uint16_t *)upm2->partIdent.identSuffix)[0]) == 0x0150)
+                               if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0150)
                                {
                                        UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
                                        UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
                                }
-                               else if (le16_to_cpu(((uint16_t *)upm2->partIdent.identSuffix)[0]) == 0x0200)
+                               else if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0200)
                                {
                                        UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
                                        UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
@@ -1074,7 +1085,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fi
                                                if (ident != 0 ||
                                                        strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
                                                {
-                                                       udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
+                                                       brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
                                                        UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
                                                }
                                        }
@@ -1112,7 +1123,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fi
  *
  */
 static void
-udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
+udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
 {
        struct buffer_head *bh = NULL;
        uint16_t ident;
@@ -1128,12 +1139,12 @@ udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
                        udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
                
                if (UDF_SB_LVIDBH(sb) != bh)
-                       udf_release_data(bh);
+                       brelse(bh);
                loc.extLength -= sb->s_blocksize;
                loc.extLocation ++;
        }
        if (UDF_SB_LVIDBH(sb) != bh)
-               udf_release_data(bh);
+               brelse(bh);
 }
 
 /*
@@ -1152,7 +1163,7 @@ udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
  *     Written, tested, and released.
  */
 static  int
-udf_process_sequence(struct super_block *sb, long block, long lastblock, lb_addr *fileset)
+udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_lb_addr *fileset)
 {
        struct buffer_head *bh = NULL;
        struct udf_vds_record vds[VDS_POS_LENGTH];
@@ -1236,7 +1247,7 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, lb_addr
                                        done = 1;
                                break;
                }
-               udf_release_data(bh);
+               brelse(bh);
        }
        for (i=0; i<VDS_POS_LENGTH; i++)
        {
@@ -1258,10 +1269,10 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, lb_addr
                                        gd = (struct generic_desc *)bh2->b_data;
                                        if (ident == TAG_IDENT_PD)
                                                udf_load_partdesc(sb, bh2);
-                                       udf_release_data(bh2);
+                                       brelse(bh2);
                                }
                        }
-                       udf_release_data(bh);
+                       brelse(bh);
                }
        }
 
@@ -1295,7 +1306,7 @@ udf_check_valid(struct super_block *sb, int novrs, int silent)
 }
 
 static int
-udf_load_partition(struct super_block *sb, lb_addr *fileset)
+udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
 {
        struct anchorVolDescPtr *anchor;
        uint16_t ident;
@@ -1306,8 +1317,7 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
        if (!sb)
                return 1;
 
-       for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
-       {
+       for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {
                if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
                        UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
                {
@@ -1318,14 +1328,14 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
                        main_e = le32_to_cpu( anchor->mainVolDescSeqExt.extLength );
                        main_e = main_e >> sb->s_blocksize_bits;
                        main_e += main_s;
-       
+
                        /* Locate the reserve sequence */
                        reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
                        reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
                        reserve_e = reserve_e >> sb->s_blocksize_bits;
                        reserve_e += reserve_s;
 
-                       udf_release_data(bh);
+                       brelse(bh);
 
                        /* Process the main & reserve sequences */
                        /* responsible for finding the PartitionDesc(s) */
@@ -1337,12 +1347,10 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
                }
        }
 
-       if (i == sizeof(UDF_SB_ANCHOR(sb))/sizeof(int))
-       {
+       if (i == ARRAY_SIZE(UDF_SB_ANCHOR(sb))) {
                udf_debug("No Anchor block found\n");
                return 1;
-       }
-       else
+       } else
                udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
 
        for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
@@ -1352,7 +1360,7 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
                        case UDF_VIRTUAL_MAP15:
                        case UDF_VIRTUAL_MAP20:
                        {
-                               lb_addr ino;
+                               kernel_lb_addr ino;
 
                                if (!UDF_SB_LASTBLOCK(sb))
                                {
@@ -1397,12 +1405,14 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
 
                                        pos = udf_block_map(UDF_SB_VAT(sb), 0);
                                        bh = sb_bread(sb, pos);
+                                       if (!bh)
+                                               return 1;
                                        UDF_SB_TYPEVIRT(sb,i).s_start_offset =
                                                le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
                                                        udf_ext0_offset(UDF_SB_VAT(sb));
                                        UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
                                                UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
-                                       udf_release_data(bh);
+                                       brelse(bh);
                                }
                                UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
                                UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
@@ -1417,7 +1427,7 @@ static void udf_open_lvid(struct super_block *sb)
        if (UDF_SB_LVIDBH(sb))
        {
                int i;
-               timestamp cpu_time;
+               kernel_timestamp cpu_time;
 
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1445,7 +1455,7 @@ static void udf_close_lvid(struct super_block *sb)
                UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN)
        {
                int i;
-               timestamp cpu_time;
+               kernel_timestamp cpu_time;
 
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1457,7 +1467,7 @@ static void udf_close_lvid(struct super_block *sb)
                        UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
                if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
                        UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
-               UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_CLOSE;
+               UDF_SB_LVID(sb)->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
 
                UDF_SB_LVID(sb)->descTag.descCRC =
                        cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
@@ -1494,7 +1504,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        int i;
        struct inode *inode=NULL;
        struct udf_options uopt;
-       lb_addr rootdir, fileset;
+       kernel_lb_addr rootdir, fileset;
        struct udf_sb_info *sbi;
 
        uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
@@ -1508,6 +1518,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        sb->s_fs_info = sbi;
        memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
 
+       mutex_init(&sbi->s_alloc_mutex);
+
        if (!udf_parse_options((char *)options, &uopt))
                goto error_out;
 
@@ -1569,6 +1581,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        sb->dq_op = NULL;
        sb->s_dirt = 0;
        sb->s_magic = UDF_SUPER_MAGIC;
+       sb->s_time_gran = 1000;
 
        if (udf_load_partition(sb, &fileset))
        {
@@ -1587,7 +1600,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                if (minUDFReadRev > UDF_MAX_READ_VERSION)
                {
                        printk("UDF-fs: minUDFReadRev=%x (max is %x)\n",
-                               UDF_SB_LVIDIU(sb)->minUDFReadRev, UDF_MAX_READ_VERSION);
+                               le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev),
+                               UDF_MAX_READ_VERSION);
                        goto error_out;
                }
                else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
@@ -1609,6 +1623,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
 
+       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) {
+               printk("UDF-fs: Partition marked readonly; forcing readonly mount\n");
+               sb->s_flags |= MS_RDONLY;
+       }
+
        if ( udf_find_fileset(sb, &fileset, &rootdir) )
        {
                printk("UDF-fs: No fileset found\n");
@@ -1617,7 +1636,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
 
        if (!silent)
        {
-               timestamp ts;
+               kernel_timestamp ts;
                udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb));
                udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
                        UDFFS_VERSION, UDFFS_DATE,
@@ -1665,7 +1684,7 @@ error_out:
                if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
                {
                        for (i=0; i<4; i++)
-                               udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+                               brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
                }
        }
 #ifdef CONFIG_UDF_NLS
@@ -1674,7 +1693,7 @@ error_out:
 #endif
        if (!(sb->s_flags & MS_RDONLY))
                udf_close_lvid(sb);
-       udf_release_data(UDF_SB_LVIDBH(sb));
+       brelse(UDF_SB_LVIDBH(sb));
        UDF_SB_FREE(sb);
        kfree(sbi);
        sb->s_fs_info = NULL;
@@ -1692,7 +1711,7 @@ void udf_error(struct super_block *sb, const char *function,
                sb->s_dirt = 1;
        }
        va_start(args, fmt);
-       vsprintf(error_buf, fmt, args);
+       vsnprintf(error_buf, sizeof(error_buf), fmt, args);
        va_end(args);
        printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
                sb->s_id, function, error_buf);
@@ -1704,7 +1723,7 @@ void udf_warning(struct super_block *sb, const char *function,
        va_list args;
 
        va_start (args, fmt);
-       vsprintf(error_buf, fmt, args);
+       vsnprintf(error_buf, sizeof(error_buf), fmt, args);
        va_end(args);
        printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
                sb->s_id, function, error_buf);
@@ -1743,7 +1762,7 @@ udf_put_super(struct super_block *sb)
                if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
                {
                        for (i=0; i<4; i++)
-                               udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+                               brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
                }
        }
 #ifdef CONFIG_UDF_NLS
@@ -1752,7 +1771,7 @@ udf_put_super(struct super_block *sb)
 #endif
        if (!(sb->s_flags & MS_RDONLY))
                udf_close_lvid(sb);
-       udf_release_data(UDF_SB_LVIDBH(sb));
+       brelse(UDF_SB_LVIDBH(sb));
        UDF_SB_FREE(sb);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
@@ -1772,8 +1791,10 @@ udf_put_super(struct super_block *sb)
  *     Written, tested, and released.
  */
 static int
-udf_statfs(struct super_block *sb, struct kstatfs *buf)
+udf_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
+       struct super_block *sb = dentry->d_sb;
+
        buf->f_type = UDF_SUPER_MAGIC;
        buf->f_bsize = sb->s_blocksize;
        buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
@@ -1800,7 +1821,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
        unsigned int accum = 0;
        int index;
        int block = 0, newblock;
-       lb_addr loc;
+       kernel_lb_addr loc;
        uint32_t bytes;
        uint8_t value;
        uint8_t *ptr;
@@ -1820,13 +1841,13 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
        }
        else if (ident != TAG_IDENT_SBD)
        {
-               udf_release_data(bh);
+               brelse(bh);
                printk(KERN_ERR "udf: udf_count_free failed\n");
                goto out;
        }
 
        bm = (struct spaceBitmapDesc *)bh->b_data;
-       bytes = bm->numOfBytes;
+       bytes = le32_to_cpu(bm->numOfBytes);
        index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
        ptr = (uint8_t *)bh->b_data;
 
@@ -1842,7 +1863,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
                }
                if ( bytes )
                {
-                       udf_release_data(bh);
+                       brelse(bh);
                        newblock = udf_get_lb_pblock(sb, loc, ++block);
                        bh = udf_tread(sb, newblock);
                        if (!bh)
@@ -1854,7 +1875,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
                        ptr = (uint8_t *)bh->b_data;
                }
        }
-       udf_release_data(bh);
+       brelse(bh);
 
 out:
        unlock_kernel();
@@ -1866,21 +1887,20 @@ static unsigned int
 udf_count_free_table(struct super_block *sb, struct inode * table)
 {
        unsigned int accum = 0;
-       uint32_t extoffset, elen;
-       lb_addr bloc, eloc;
+       uint32_t elen;
+       kernel_lb_addr eloc;
        int8_t etype;
-       struct buffer_head *bh = NULL;
+       struct extent_position epos;
 
        lock_kernel();
 
-       bloc = UDF_I_LOCATION(table);
-       extoffset = sizeof(struct unallocSpaceEntry);
+       epos.block = UDF_I_LOCATION(table);
+       epos.offset = sizeof(struct unallocSpaceEntry);
+       epos.bh = NULL;
 
-       while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
-       {
+       while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
                accum += (elen >> table->i_sb->s_blocksize_bits);
-       }
-       udf_release_data(bh);
+       brelse(epos.bh);
 
        unlock_kernel();