diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-22 13:40:47 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-22 13:40:47 -0700 |
commit | 62429f434091586d54b37b8dd46076e7c08b27b9 (patch) | |
tree | d8fd38000961eb30e37b90026efebb5ae946c1ad | |
parent | 26defe34e48e18b058b773f60467729c64917490 (diff) | |
parent | f845fced913b1437659bb5baf187698547697afe (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6: (41 commits)
udf: use crc_itu_t from lib instead of udf_crc
udf: Fix compilation warnings when UDF debug is on
udf: Fix bug in VAT mapping code
udf: Add read-only support for 2.50 UDF media
udf: Fix handling of multisession media
udf: Mount filesystem read-only if it has pseudooverwrite partition
udf: Handle VAT packed inside inode properly
udf: Allow loading of VAT inode
udf: Fix detection of VAT version
udf: Silence warning about accesses beyond end of device
udf: Improve anchor block detection
udf: Cleanup anchor block detection.
udf: Move processing of virtual partitions
udf: Move filling of partition descriptor info into a separate function
udf: Improve error recovery on mount
udf: Cleanup volume descriptor sequence processing
udf: fix anchor point detection
udf: Remove declarations of arrays of size UDF_NAME_LEN (256 bytes)
udf: Remove checking of existence of filename in udf_add_entry()
udf: Mark udf_process_sequence() as noinline
...
-rw-r--r-- | fs/Kconfig | 1 | ||||
-rw-r--r-- | fs/udf/Makefile | 2 | ||||
-rw-r--r-- | fs/udf/balloc.c | 13 | ||||
-rw-r--r-- | fs/udf/crc.c | 172 | ||||
-rw-r--r-- | fs/udf/dir.c | 83 | ||||
-rw-r--r-- | fs/udf/ecma_167.h | 13 | ||||
-rw-r--r-- | fs/udf/file.c | 47 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 13 | ||||
-rw-r--r-- | fs/udf/inode.c | 208 | ||||
-rw-r--r-- | fs/udf/lowlevel.c | 1 | ||||
-rw-r--r-- | fs/udf/misc.c | 26 | ||||
-rw-r--r-- | fs/udf/namei.c | 218 | ||||
-rw-r--r-- | fs/udf/partition.c | 67 | ||||
-rw-r--r-- | fs/udf/super.c | 1262 | ||||
-rw-r--r-- | fs/udf/symlink.c | 1 | ||||
-rw-r--r-- | fs/udf/truncate.c | 81 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 30 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 109 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 67 | ||||
-rw-r--r-- | fs/udf/udfend.h | 22 | ||||
-rw-r--r-- | fs/udf/udftime.c | 35 | ||||
-rw-r--r-- | fs/udf/unicode.c | 62 | ||||
-rw-r--r-- | include/linux/Kbuild | 2 | ||||
-rw-r--r-- | include/linux/udf_fs.h | 51 | ||||
-rw-r--r-- | include/linux/udf_fs_i.h | 31 | ||||
-rw-r--r-- | include/linux/udf_fs_sb.h | 117 |
26 files changed, 1173 insertions, 1561 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 028ae38ecc5..8b18a875867 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -689,6 +689,7 @@ config ZISOFS config UDF_FS tristate "UDF file system support" + select CRC_ITU_T help This is the new file system used on some CD-ROMs and DVDs. Say Y if you intend to mount DVD discs or CDRW's written in packet mode, or diff --git a/fs/udf/Makefile b/fs/udf/Makefile index be845e7540e..0d4503f7446 100644 --- a/fs/udf/Makefile +++ b/fs/udf/Makefile @@ -6,4 +6,4 @@ obj-$(CONFIG_UDF_FS) += udf.o udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \ partition.o super.o truncate.o symlink.o fsync.o \ - crc.o directory.o misc.o udftime.o unicode.o + directory.o misc.o udftime.o unicode.o diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index f855dcbbdfb..1b809bd494b 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -149,8 +149,7 @@ static bool udf_add_free_space(struct udf_sb_info *sbi, return false; lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; - lvid->freeSpaceTable[partition] = cpu_to_le32(le32_to_cpu( - lvid->freeSpaceTable[partition]) + cnt); + le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); return true; } @@ -589,10 +588,8 @@ static void udf_table_free_blocks(struct super_block *sb, sptr = oepos.bh->b_data + epos.offset; aed = (struct allocExtDesc *) oepos.bh->b_data; - aed->lengthAllocDescs = - cpu_to_le32(le32_to_cpu( - aed->lengthAllocDescs) + - adsize); + le32_add_cpu(&aed->lengthAllocDescs, + adsize); } else { sptr = iinfo->i_ext.i_data + epos.offset; @@ -645,9 +642,7 @@ static void udf_table_free_blocks(struct super_block *sb, mark_inode_dirty(table); } else { aed = (struct allocExtDesc *)epos.bh->b_data; - aed->lengthAllocDescs = - cpu_to_le32(le32_to_cpu( - aed->lengthAllocDescs) + adsize); + le32_add_cpu(&aed->lengthAllocDescs, adsize); udf_update_tag(epos.bh->b_data, epos.offset); mark_buffer_dirty(epos.bh); } diff --git a/fs/udf/crc.c b/fs/udf/crc.c deleted file mode 100644 index b1661296e78..00000000000 --- a/fs/udf/crc.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * crc.c - * - * PURPOSE - * Routines to generate, calculate, and test a 16-bit CRC. - * - * DESCRIPTION - * The CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories - * and Ned W. Rhodes of Software Systems Group. It has been published in - * "Design and Validation of Computer Protocols", Prentice Hall, - * Englewood Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4. - * - * Copyright is held by AT&T. - * - * AT&T gives permission for the free use of the CRC source code. - * - * COPYRIGHT - * This file is distributed under the terms of the GNU General Public - * License (GPL). Copies of the GPL can be obtained from: - * ftp://prep.ai.mit.edu/pub/gnu/GPL - * Each contributing author retains all rights to their own work. - */ - -#include "udfdecl.h" - -static uint16_t crc_table[256] = { - 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U, - 0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU, - 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U, - 0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU, - 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U, - 0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU, - 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U, - 0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU, - 0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U, - 0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU, - 0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U, - 0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU, - 0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U, - 0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U, - 0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U, - 0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U, - 0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU, - 0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U, - 0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU, - 0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U, - 0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU, - 0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U, - 0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU, - 0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U, - 0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU, - 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U, - 0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU, - 0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U, - 0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U, - 0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U, - 0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U, - 0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U -}; - -/* - * udf_crc - * - * PURPOSE - * Calculate a 16-bit CRC checksum using ITU-T V.41 polynomial. - * - * DESCRIPTION - * The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory. - * The polynomial used is: x^16 + x^12 + x^15 + 1 - * - * PRE-CONDITIONS - * data Pointer to the data block. - * size Size of the data block. - * - * POST-CONDITIONS - * <return> CRC of the data block. - * - * HISTORY - * July 21, 1997 - Andrew E. Mileski - * Adapted from OSTA-UDF(tm) 1.50 standard. - */ -uint16_t udf_crc(uint8_t *data, uint32_t size, uint16_t crc) -{ - while (size--) - crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8); - - return crc; -} - -/****************************************************************************/ -#if defined(TEST) - -/* - * PURPOSE - * Test udf_crc() - * - * HISTORY - * July 21, 1997 - Andrew E. Mileski - * Adapted from OSTA-UDF(tm) 1.50 standard. - */ - -unsigned char bytes[] = { 0x70U, 0x6AU, 0x77U }; - -int main(void) -{ - unsigned short x; - - x = udf_crc(bytes, sizeof bytes); - printf("udf_crc: calculated = %4.4x, correct = %4.4x\n", x, 0x3299U); - - return 0; -} - -#endif /* defined(TEST) */ - -/****************************************************************************/ -#if defined(GENERATE) - -/* - * PURPOSE - * Generate a table for fast 16-bit CRC calculations (any polynomial). - * - * DESCRIPTION - * The ITU-T V.41 polynomial is 010041. - * - * HISTORY - * July 21, 1997 - Andrew E. Mileski - * Adapted from OSTA-UDF(tm) 1.50 standard. - */ - -#include <stdio.h> - -int main(int argc, char **argv) -{ - unsigned long crc, poly; - int n, i; - - /* Get the polynomial */ - sscanf(argv[1], "%lo", &poly); - if (poly & 0xffff0000U) { - fprintf(stderr, "polynomial is too large\en"); - exit(1); - } - - printf("/* CRC 0%o */\n", poly); - - /* Create a table */ - printf("static unsigned short crc_table[256] = {\n"); - for (n = 0; n < 256; n++) { - if (n % 8 == 0) - printf("\t"); - crc = n << 8; - for (i = 0; i < 8; i++) { - if (crc & 0x8000U) - crc = (crc << 1) ^ poly; - else - crc <<= 1; - crc &= 0xFFFFU; - } - if (n == 255) - printf("0x%04xU ", crc); - else - printf("0x%04xU, ", crc); - if (n % 8 == 7) - printf("\n"); - } - printf("};\n"); - - return 0; -} - -#endif /* defined(GENERATE) */ diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 8d8643ada19..62dc270c69d 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -39,13 +39,13 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, void *dirent) { - struct udf_fileident_bh fibh; + struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; struct fileIdentDesc *fi = NULL; struct fileIdentDesc cfi; int block, iblock; loff_t nf_pos = (filp->f_pos - 1) << 2; int flen; - char fname[UDF_NAME_LEN]; + char *fname = NULL; char *nameptr; uint16_t liu; uint8_t lfi; @@ -54,23 +54,32 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, kernel_lb_addr eloc; uint32_t elen; sector_t offset; - int i, num; + int i, num, ret = 0; unsigned int dt_type; struct extent_position epos = { NULL, 0, {0, 0} }; struct udf_inode_info *iinfo; if (nf_pos >= size) - return 0; + goto out; + + fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); + if (!fname) { + ret = -ENOMEM; + goto out; + } if (nf_pos == 0) nf_pos = udf_ext0_offset(dir); fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); iinfo = UDF_I(dir); - if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { - fibh.sbh = fibh.ebh = NULL; - } else if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, - &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { + if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { + if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, + &epos, &eloc, &elen, &offset) + != (EXT_RECORDED_ALLOCATED >> 30)) { + ret = -ENOENT; + goto out; + } block = udf_get_lb_pblock(dir->i_sb, eloc, offset); if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) @@ -83,8 +92,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, } if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { - brelse(epos.bh); - return -EIO; + ret = -EIO; + goto out; } if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { @@ -105,9 +114,6 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, brelse(bha[i]); } } - } else { - brelse(epos.bh); - return -ENOENT; } while (nf_pos < size) { @@ -115,13 +121,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); - if (!fi) { - if (fibh.sbh != fibh.ebh) - brelse(fibh.ebh); - brelse(fibh.sbh); - brelse(epos.bh); - return 0; - } + if (!fi) + goto out; liu = le16_to_cpu(cfi.lengthOfImpUse); lfi = cfi.lengthFileIdent; @@ -167,53 +168,23 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, dt_type = DT_UNKNOWN; } - if (flen) { - if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) { - if (fibh.sbh != fibh.ebh) - brelse(fibh.ebh); - brelse(fibh.sbh); - brelse(epos.bh); - return 0; - } - } + if (flen && filldir(dirent, fname, flen, filp->f_pos, + iblock, dt_type) < 0) + goto out; } /* end while */ filp->f_pos = (nf_pos >> 2) + 1; +out: if (fibh.sbh != fibh.ebh) brelse(fibh.ebh); brelse(fibh.sbh); brelse(epos.bh); + kfree(fname); - return 0; + return ret; } -/* - * udf_readdir - * - * PURPOSE - * Read a directory entry. - * - * DESCRIPTION - * Optional - sys_getdents() will return -ENOTDIR if this routine is not - * available. - * - * Refer to sys_getdents() in fs/readdir.c - * sys_getdents() -> . - * - * PRE-CONDITIONS - * filp Pointer to directory file. - * buf Pointer to directory entry buffer. - * filldir Pointer to filldir function. - * - * POST-CONDITIONS - * <return> >=0 on success. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ - static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct inode *dir = filp->f_path.dentry->d_inode; diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h index 56387711589..a0974df82b3 100644 --- a/fs/udf/ecma_167.h +++ b/fs/udf/ecma_167.h @@ -70,19 +70,6 @@ typedef struct { uint8_t microseconds; } __attribute__ ((packed)) timestamp; -typedef struct { - uint16_t typeAndTimezone; - int16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t minute; - uint8_t second; - uint8_t centiseconds; - uint8_t hundredsOfMicroseconds; - uint8_t microseconds; -} __attribute__ ((packed)) kernel_timestamp; - /* Type and Time Zone (ECMA 167r3 1/7.3.1) */ #define TIMESTAMP_TYPE_MASK 0xF000 #define TIMESTAMP_TYPE_CUT 0x0000 diff --git a/fs/udf/file.c b/fs/udf/file.c index 97c71ae7c68..0ed6e146a0d 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -27,7 +27,6 @@ #include "udfdecl.h" #include <linux/fs.h> -#include <linux/udf_fs.h> #include <asm/uaccess.h> #include <linux/kernel.h> #include <linux/string.h> /* memset */ @@ -144,40 +143,6 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, return retval; } -/* - * udf_ioctl - * - * PURPOSE - * Issue an ioctl. - * - * DESCRIPTION - * Optional - sys_ioctl() will return -ENOTTY if this routine is not - * available, and the ioctl cannot be handled without filesystem help. - * - * sys_ioctl() handles these ioctls that apply only to regular files: - * FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD - * These ioctls are also handled by sys_ioctl(): - * FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC - * All other ioctls are passed to the filesystem. - * - * Refer to sys_ioctl() in fs/ioctl.c - * sys_ioctl() -> . - * - * PRE-CONDITIONS - * inode Pointer to inode that ioctl was issued on. - * filp Pointer to file that ioctl was issued on. - * cmd The ioctl command. - * arg The ioctl argument [can be interpreted as a - * user-space pointer if desired]. - * - * POST-CONDITIONS - * <return> Success (>=0) or an error code (<=0) that - * sys_ioctl() will return. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -225,18 +190,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return result; } -/* - * udf_release_file - * - * PURPOSE - * Called when all references to the file are closed - * - * DESCRIPTION - * Discard prealloced blocks - * - * HISTORY - * - */ static int udf_release_file(struct inode *inode, struct file *filp) { if (filp->f_mode & FMODE_WRITE) { diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 84360315aca..eb9cfa23dc3 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -21,7 +21,6 @@ #include "udfdecl.h" #include <linux/fs.h> #include <linux/quotaops.h> -#include <linux/udf_fs.h> #include <linux/sched.h> #include <linux/slab.h> @@ -47,11 +46,9 @@ void udf_free_inode(struct inode *inode) struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sbi); if (S_ISDIR(inode->i_mode)) - lvidiu->numDirs = - cpu_to_le32(le32_to_cpu(lvidiu->numDirs) - 1); + le32_add_cpu(&lvidiu->numDirs, -1); else - lvidiu->numFiles = - cpu_to_le32(le32_to_cpu(lvidiu->numFiles) - 1); + le32_add_cpu(&lvidiu->numFiles, -1); mark_buffer_dirty(sbi->s_lvid_bh); } @@ -105,11 +102,9 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) lvhd = (struct logicalVolHeaderDesc *) (lvid->logicalVolContentsUse); if (S_ISDIR(mode)) - lvidiu->numDirs = - cpu_to_le32(le32_to_cpu(lvidiu->numDirs) + 1); + le32_add_cpu(&lvidiu->numDirs, 1); else - lvidiu->numFiles = - cpu_to_le32(le32_to_cpu(lvidiu->numFiles) + 1); + le32_add_cpu(&lvidiu->numFiles, 1); iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID); if (!(++uniqueID & 0x00000000FFFFFFFFUL)) uniqueID += 16; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 24cfa55d0fd..6e74b117aaf 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -37,6 +37,7 @@ #include <linux/buffer_head.h> #include <linux/writeback.h> #include <linux/slab.h> +#include <linux/crc-itu-t.h> #include "udf_i.h" #include "udf_sb.h" @@ -66,22 +67,7 @@ static void udf_update_extents(struct inode *, struct extent_position *); static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); -/* - * udf_delete_inode - * - * PURPOSE - * Clean-up before the specified inode is destroyed. - * - * DESCRIPTION - * This routine is called when the kernel destroys an inode structure - * ie. when iput() finds i_count == 0. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - * - * Called at the last iput() if i_nlink is zero. - */ + void udf_delete_inode(struct inode *inode) { truncate_inode_pages(&inode->i_data, 0); @@ -323,9 +309,6 @@ static int udf_get_block(struct inode *inode, sector_t block, lock_kernel(); - if (block < 0) - goto abort_negative; - iinfo = UDF_I(inode); if (block == iinfo->i_next_alloc_block + 1) { iinfo->i_next_alloc_block++; @@ -347,10 +330,6 @@ static int udf_get_block(struct inode *inode, sector_t block, abort: unlock_kernel(); return err; - -abort_negative: - udf_warning(inode->i_sb, "udf_get_block", "block < 0"); - goto abort; } static struct buffer_head *udf_getblk(struct inode *inode, long block, @@ -1116,42 +1095,36 @@ static void __udf_read_inode(struct inode *inode) fe = (struct fileEntry *)bh->b_data; if (fe->icbTag.strategyType == cpu_to_le16(4096)) { - struct buffer_head *ibh = NULL, *nbh = NULL; - struct indirectEntry *ie; + struct buffer_head *ibh; ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1, &ident); - if (ident == TAG_IDENT_IE) { - if (ibh) { - kernel_lb_addr loc; - ie = (struct indirectEntry *)ibh->b_data; - - loc = lelb_to_cpu(ie->indirectICB.extLocation); - - if (ie->indirectICB.extLength && - (nbh = udf_read_ptagged(inode->i_sb, loc, 0, - &ident))) { - if (ident == TAG_IDENT_FE || - ident == TAG_IDENT_EFE) { - memcpy(&iinfo->i_location, - &loc, - sizeof(kernel_lb_addr)); - brelse(bh); - brelse(ibh); - brelse(nbh); - __udf_read_inode(inode); - return; - } else { - brelse(nbh); - brelse(ibh); - } - } else { + if (ident == TAG_IDENT_IE && ibh) { + struct buffer_head *nbh = NULL; + kernel_lb_addr loc; + struct indirectEntry *ie; + + ie = (struct indirectEntry *)ibh->b_data; + loc = lelb_to_cpu(ie->indirectICB.extLocation); + + if (ie->indirectICB.extLength && + (nbh = udf_read_ptagged(inode->i_sb, loc, 0, + &ident))) { + if (ident == TAG_IDENT_FE || + ident == TAG_IDENT_EFE) { + memcpy(&iinfo->i_location, + &loc, + sizeof(kernel_lb_addr)); + brelse(bh); brelse(ibh); + brelse(nbh); + __udf_read_inode(inode); + return; } + brelse(nbh); } - } else { - brelse(ibh); } + brelse(ibh); } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { printk(KERN_ERR "udf: unsupported strategy type: %d\n", le16_to_cpu(fe->icbTag.strategyType)); @@ -1168,8 +1141,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) { struct fileEntry *fe; struct extendedFileEntry *efe; - time_t convtime; - long convtime_usec; int offset; struct udf_sb_info *sbi = UDF_SB(inode->i_sb); struct udf_inode_info *iinfo = UDF_I(inode); @@ -1257,29 +1228,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << (inode->i_sb->s_blocksize_bits - 9); - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(fe->accessTime))) { - inode->i_atime.tv_sec = convtime; - inode->i_atime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime)) inode->i_atime = sbi->s_record_time; - } - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(fe->modificationTime))) { - inode->i_mtime.tv_sec = convtime; - inode->i_mtime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&inode->i_mtime, + fe->modificationTime)) inode->i_mtime = sbi->s_record_time; - } - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(fe->attrTime))) { - inode->i_ctime.tv_sec = convtime; - inode->i_ctime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime)) inode->i_ctime = sbi->s_record_time; - } iinfo->i_unique = le64_to_cpu(fe->uniqueID); iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); @@ -1289,37 +1246,18 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << (inode->i_sb->s_blocksize_bits - 9); - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(efe->accessTime))) { - inode->i_atime.tv_sec = convtime; - inode->i_atime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime)) inode->i_atime = sbi->s_record_time; - } - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(efe->modificationTime))) { - inode->i_mtime.tv_sec = convtime; - inode->i_mtime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&inode->i_mtime, + efe->modificationTime)) inode->i_mtime = sbi->s_record_time; - } - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(efe->createTime))) { - iinfo->i_crtime.tv_sec = convtime; - iinfo->i_crtime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime)) iinfo->i_crtime = sbi->s_record_time; - } - if (udf_stamp_to_time(&convtime, &convtime_usec, - lets_to_cpu(efe->attrTime))) { - inode->i_ctime.tv_sec = convtime; - inode->i_ctime.tv_nsec = convtime_usec * 1000; - } else { + if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime)) inode->i_ctime = sbi->s_record_time; - } iinfo->i_unique = le64_to_cpu(efe->uniqueID); iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); @@ -1338,6 +1276,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) case ICBTAG_FILE_TYPE_REALTIME: case ICBTAG_FILE_TYPE_REGULAR: case ICBTAG_FILE_TYPE_UNDEF: + case ICBTAG_FILE_TYPE_VAT20: if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) inode->i_data.a_ops = &udf_adinicb_aops; else @@ -1363,6 +1302,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) inode->i_op = &page_symlink_inode_operations; inode->i_mode = S_IFLNK | S_IRWXUGO; break; + case ICBTAG_FILE_TYPE_MAIN: + udf_debug("METADATA FILE-----\n"); + break; + case ICBTAG_FILE_TYPE_MIRROR: + udf_debug("METADATA MIRROR FILE-----\n"); + break; + case ICBTAG_FILE_TYPE_BITMAP: + udf_debug("METADATA BITMAP FILE-----\n"); + break; default: printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown " "file type=%d\n", inode->i_ino, @@ -1416,21 +1364,6 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) return mode; } -/* - * udf_write_inode - * - * PURPOSE - * Write out the specified inode. - * - * DESCRIPTION - * This routine is called whenever an inode is synced. - * Currently this routine is just a placeholder. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ - int udf_write_inode(struct inode *inode, int sync) { int ret; @@ -1455,7 +1388,6 @@ static int udf_update_inode(struct inode *inode, int do_sync) uint32_t udfperms; uint16_t icbflags; uint16_t crclen; - kernel_timestamp cpu_time; int err = 0; struct udf_sb_info *sbi = UDF_SB(inode->i_sb); unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; @@ -1488,9 +1420,9 @@ static int udf_update_inode(struct inode *inode, int do_sync) iinfo->i_location. logicalBlockNum); use->descTag.descCRCLength = cpu_to_le16(crclen); - use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + - sizeof(tag), crclen, - 0)); + use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + + sizeof(tag), + crclen)); use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); mark_buffer_dirty(bh); @@ -1558,12 +1490,9 @@ static int udf_update_inode(struct inode *inode, int do_sync) (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> (blocksize_bits - 9)); - if (udf_time_to_stamp(&cpu_time, inode->i_atime)) - fe->accessTime = cpu_to_lets(cpu_time); - if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) - fe->modificationTime = cpu_to_lets(cpu_time); - if (udf_time_to_stamp(&cpu_time, inode->i_ctime)) - fe->attrTime = cpu_to_lets(cpu_time); + udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); + udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); + udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime); memset(&(fe->impIdent), 0, sizeof(regid)); strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; @@ -1598,14 +1527,10 @@ static int udf_update_inode(struct inode *inode, int do_sync) iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec)) iinfo->i_crtime = inode->i_ctime; - if (udf_time_to_stamp(&cpu_time, inode->i_atime)) - efe->accessTime = cpu_to_lets(cpu_time); - if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) - efe->modificationTime = cpu_to_lets(cpu_time); - if (udf_time_to_stamp(&cpu_time, iinfo->i_crtime)) - efe->createTime = cpu_to_lets(cpu_time); - if (udf_time_to_stamp(&cpu_time, inode->i_ctime)) - efe->attrTime = cpu_to_lets(cpu_time); + udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime); + udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime); + udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime); + udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime); memset(&(efe->impIdent), 0, sizeof(regid)); strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); @@ -1660,8 +1585,8 @@ static int udf_update_inode(struct inode *inode, int do_sync) crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(tag); fe->descTag.descCRCLength = cpu_to_le16(crclen); - fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), - crclen, 0)); + fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag), + crclen)); fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); /* write the data blocks */ @@ -1778,9 +1703,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, if (epos->bh) { aed = (struct allocExtDesc *)epos->bh->b_data; - aed->lengthAllocDescs = - cpu_to_le32(le32_to_cpu( - aed->lengthAllocDescs) + adsize); + le32_add_cpu(&aed->lengthAllocDescs, adsize); } else { iinfo->i_lenAlloc += adsize; mark_inode_dirty(inode); @@ -1830,9 +1753,7 @@ int8_ |