Commit 0fc9e32a authored by Ben Fennema's avatar Ben Fennema Committed by Linus Torvalds

[PATCH] UDF sync with CVS

This patch updates udf to the CVS version:
  - removes UDF_RW
  - fixes a extraneous read after write which killed CDRW performance
  - fixes setting the session
  - fix a array index bug in udf_prealloc_extents
  - fix symlinks to correspond to the UDF spec
parent f2b38c55
...@@ -1037,15 +1037,12 @@ config SYSV_FS ...@@ -1037,15 +1037,12 @@ config SYSV_FS
If you haven't heard about all of this before, it's safe to say N. If you haven't heard about all of this before, it's safe to say N.
config UDF_FS config UDF_FS
tristate "UDF file system support (read only)" tristate "UDF file system support"
---help--- ---help---
This is the new file system used on some CD-ROMs and DVDs. Say Y if 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 you intend to mount DVD discs or CDRW's written in packet mode, or
if written to by other UDF utilities, such as DirectCD. This UDF if written to by other UDF utilities, such as DirectCD.
file system support is read-only. If you want to write to UDF Please read <file:Documentation/filesystems/udf.txt>.
file systems on some media, you need to say Y to "UDF read-write
support" below in addition. Please read
<file:Documentation/filesystems/udf.txt>.
This file system support is also available as a module ( = code This file system support is also available as a module ( = code
which can be inserted in and removed from the running kernel which can be inserted in and removed from the running kernel
...@@ -1055,14 +1052,6 @@ config UDF_FS ...@@ -1055,14 +1052,6 @@ config UDF_FS
If unsure, say N. If unsure, say N.
config UDF_RW
bool "UDF write support (DANGEROUS)"
depends on UDF_FS && EXPERIMENTAL
help
Say Y if you want to test write support for UDF file systems.
Due to lack of support for writing to CDR/CDRW's, this option
is only supported for hard discs, DVD-RAM, and loopback files.
config UFS_FS config UFS_FS
tristate "UFS file system support (read only)" tristate "UFS file system support (read only)"
---help--- ---help---
......
...@@ -461,8 +461,7 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -461,8 +461,7 @@ static void udf_table_free_blocks(struct super_block * sb,
elen = 0; elen = 0;
obloc = nbloc = UDF_I_LOCATION(table); obloc = nbloc = UDF_I_LOCATION(table);
obh = nbh = udf_tread(sb, udf_get_lb_pblock(sb, nbloc, 0)); obh = nbh = NULL;
atomic_inc(&nbh->b_count);
while (count && (etype = while (count && (etype =
udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
...@@ -506,7 +505,7 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -506,7 +505,7 @@ static void udf_table_free_blocks(struct super_block * sb,
udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
} }
if (memcmp(&nbloc, &obloc, sizeof(lb_addr))) if (nbh != obh)
{ {
i = -1; i = -1;
obloc = nbloc; obloc = nbloc;
...@@ -580,7 +579,10 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -580,7 +579,10 @@ static void udf_table_free_blocks(struct super_block * sb,
{ {
loffset = nextoffset; loffset = nextoffset;
aed->lengthAllocDescs = cpu_to_le32(adsize); aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = (obh)->b_data + nextoffset - adsize; if (obh)
sptr = UDF_I_DATA(inode) + nextoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode) - adsize;
else
sptr = obh->b_data + nextoffset - adsize;
dptr = nbh->b_data + sizeof(struct allocExtDesc); dptr = nbh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize); memcpy(dptr, sptr, adsize);
nextoffset = sizeof(struct allocExtDesc) + adsize; nextoffset = sizeof(struct allocExtDesc) + adsize;
...@@ -591,8 +593,8 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -591,8 +593,8 @@ static void udf_table_free_blocks(struct super_block * sb,
aed->lengthAllocDescs = cpu_to_le32(0); aed->lengthAllocDescs = cpu_to_le32(0);
sptr = (obh)->b_data + nextoffset; sptr = (obh)->b_data + nextoffset;
nextoffset = sizeof(struct allocExtDesc); nextoffset = sizeof(struct allocExtDesc);
if (memcmp(&UDF_I_LOCATION(table), &obloc, sizeof(lb_addr))) if (obh)
{ {
aed = (struct allocExtDesc *)(obh)->b_data; aed = (struct allocExtDesc *)(obh)->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
...@@ -631,15 +633,20 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -631,15 +633,20 @@ static void udf_table_free_blocks(struct super_block * sb,
break; break;
} }
} }
udf_update_tag(obh->b_data, loffset); if (obh)
mark_buffer_dirty(obh); {
udf_update_tag(obh->b_data, loffset);
mark_buffer_dirty(obh);
}
else
mark_inode_dirty(table);
} }
if (elen) /* It's possible that stealing the block emptied the extent */ if (elen) /* It's possible that stealing the block emptied the extent */
{ {
udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1); udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1);
if (!memcmp(&UDF_I_LOCATION(table), &nbloc, sizeof(lb_addr))) if (!nbh)
{ {
UDF_I_LENALLOC(table) += adsize; UDF_I_LENALLOC(table) += adsize;
mark_inode_dirty(table); mark_inode_dirty(table);
...@@ -690,7 +697,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -690,7 +697,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
extoffset = sizeof(struct unallocSpaceEntry); extoffset = sizeof(struct unallocSpaceEntry);
bloc = UDF_I_LOCATION(table); bloc = UDF_I_LOCATION(table);
bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0)); bh = NULL;
eloc.logicalBlockNum = 0xFFFFFFFF; eloc.logicalBlockNum = 0xFFFFFFFF;
while (first_block != eloc.logicalBlockNum && (etype = while (first_block != eloc.logicalBlockNum && (etype =
...@@ -768,8 +775,7 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -768,8 +775,7 @@ static int udf_table_new_block(struct super_block * sb,
extoffset = sizeof(struct unallocSpaceEntry); extoffset = sizeof(struct unallocSpaceEntry);
bloc = UDF_I_LOCATION(table); bloc = UDF_I_LOCATION(table);
goal_bh = bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0)); goal_bh = bh = NULL;
atomic_inc(&goal_bh->b_count);
while (spread && (etype = while (spread && (etype =
udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
......
...@@ -89,13 +89,14 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -89,13 +89,14 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
if ( filp->f_pos == 0 ) if ( filp->f_pos == 0 )
{ {
if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) { if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0)
{
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
filp->f_pos ++; filp->f_pos ++;
} }
result = do_udf_readdir(dir, filp, filldir, dirent); result = do_udf_readdir(dir, filp, filldir, dirent);
UPDATE_ATIME(dir); UPDATE_ATIME(dir);
unlock_kernel(); unlock_kernel();
...@@ -129,7 +130,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -129,7 +130,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
nf_pos = (udf_ext0_offset(dir) >> 2); nf_pos = (udf_ext0_offset(dir) >> 2);
fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
{ {
offset >>= dir->i_sb->s_blocksize_bits; offset >>= dir->i_sb->s_blocksize_bits;
...@@ -143,40 +146,40 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -143,40 +146,40 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
} }
else else
offset = 0; offset = 0;
}
else
{
udf_release_data(bh);
return -ENOENT;
}
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{
udf_release_data(bh);
return -EIO;
}
if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1))) if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{
i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
if (i+offset > (elen >> dir->i_sb->s_blocksize_bits))
i = (elen >> dir->i_sb->s_blocksize_bits)-offset;
for (num=0; i>0; i--)
{ {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i); udf_release_data(bh);
tmp = udf_tgetblk(dir->i_sb, block); return -EIO;
if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
bha[num++] = tmp;
else
brelse(tmp);
} }
if (num)
if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1)))
{ {
ll_rw_block(READA, num, bha); i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
for (i=0; i<num; i++) if (i+offset > (elen >> dir->i_sb->s_blocksize_bits))
brelse(bha[i]); i = (elen >> dir->i_sb->s_blocksize_bits)-offset;
for (num=0; i>0; i--)
{
block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i);
tmp = udf_tgetblk(dir->i_sb, block);
if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
bha[num++] = tmp;
else
brelse(tmp);
}
if (num)
{
ll_rw_block(READA, num, bha);
for (i=0; i<num; i++)
brelse(bha[i]);
}
} }
} }
else
{
udf_release_data(bh);
return -ENOENT;
}
while ( nf_pos < size ) while ( nf_pos < size )
{ {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include "udfdecl.h" #include "udfdecl.h"
#include "udf_i.h"
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -85,6 +86,24 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -85,6 +86,24 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
fibh->soffset = fibh->eoffset; fibh->soffset = fibh->eoffset;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
{
fi = udf_get_fileident(UDF_I_DATA(dir) -
(UDF_I_EFE(dir) ?
sizeof(struct extendedFileEntry) :
sizeof(struct fileEntry)),
dir->i_sb->s_blocksize, &(fibh->eoffset));
if (!fi)
return NULL;
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
return fi;
}
if (fibh->eoffset == dir->i_sb->s_blocksize) if (fibh->eoffset == dir->i_sb->s_blocksize)
{ {
int lextoffset = *extoffset; int lextoffset = *extoffset;
...@@ -276,53 +295,43 @@ udf_get_fileextent(void * buffer, int bufsize, int * offset) ...@@ -276,53 +295,43 @@ udf_get_fileextent(void * buffer, int bufsize, int * offset)
} }
short_ad * short_ad *
udf_get_fileshortad(void * buffer, int maxoffset, int *offset, int inc) udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc)
{ {
short_ad * sa; short_ad *sa;
uint8_t * ptr;
if ( (!buffer) || (!offset) ) if ( (!ptr) || (!offset) )
{ {
printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n"); printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
return NULL; return NULL;
} }
ptr = (uint8_t *)buffer; if ( (*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset) )
if ( (*offset > 0) && (*offset < maxoffset) )
ptr += *offset;
else
return NULL; return NULL;
else if ((sa = (short_ad *)ptr)->extLength == 0)
if ((sa = (short_ad *)ptr)->extLength == 0)
return NULL; return NULL;
else if (inc)
(*offset) += sizeof(short_ad); if (inc)
*offset += sizeof(short_ad);
return sa; return sa;
} }
long_ad * long_ad *
udf_get_filelongad(void * buffer, int maxoffset, int * offset, int inc) udf_get_filelongad(uint8_t *ptr, int maxoffset, int * offset, int inc)
{ {
long_ad * la; long_ad *la;
uint8_t * ptr;
if ( (!buffer) || !(offset) ) if ( (!ptr) || (!offset) )
{ {
printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n"); printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
return NULL; return NULL;
} }
ptr = (uint8_t *)buffer; if ( (*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset) )
if ( (*offset > 0) && (*offset < maxoffset) )
ptr += *offset;
else
return NULL; return NULL;
else if ((la = (long_ad *)ptr)->extLength == 0)
if ((la = (long_ad *)ptr)->extLength == 0)
return NULL; return NULL;
else if (inc)
(*offset) += sizeof(long_ad); if (inc)
*offset += sizeof(long_ad);
return la; return la;
} }
...@@ -47,64 +47,36 @@ ...@@ -47,64 +47,36 @@
static int udf_adinicb_readpage(struct file *file, struct page * page) static int udf_adinicb_readpage(struct file *file, struct page * page)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct buffer_head *bh;
int block;
char *kaddr; char *kaddr;
int err = 0;
if (!PageLocked(page)) if (!PageLocked(page))
PAGE_BUG(page); PAGE_BUG(page);
kaddr = kmap(page); kaddr = kmap(page);
memset(kaddr, 0, PAGE_CACHE_SIZE); memset(kaddr, 0, PAGE_CACHE_SIZE);
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), inode->i_size);
bh = sb_bread(inode->i_sb, block);
if (!bh)
{
SetPageError(page);
err = -EIO;
goto out;
}
memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size);
brelse(bh);
flush_dcache_page(page); flush_dcache_page(page);
SetPageUptodate(page); SetPageUptodate(page);
out:
kunmap(page); kunmap(page);
unlock_page(page); unlock_page(page);
return err; return 0;
} }
static int udf_adinicb_writepage(struct page *page) static int udf_adinicb_writepage(struct page *page)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct buffer_head *bh;
int block;
char *kaddr; char *kaddr;
int err = 0;
if (!PageLocked(page)) if (!PageLocked(page))
PAGE_BUG(page); PAGE_BUG(page);
kaddr = kmap(page); kaddr = kmap(page);
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), kaddr, inode->i_size);
bh = sb_bread(inode->i_sb, block); mark_inode_dirty(inode);
if (!bh)
{
SetPageError(page);
err = -EIO;
goto out;
}
memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size);
mark_buffer_dirty(bh);
brelse(bh);
SetPageUptodate(page); SetPageUptodate(page);
out:
kunmap(page); kunmap(page);
unlock_page(page); unlock_page(page);
return err; return 0;
} }
static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
...@@ -116,31 +88,17 @@ static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsig ...@@ -116,31 +88,17 @@ static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsig
static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct buffer_head *bh;
int block;
char *kaddr = page_address(page); char *kaddr = page_address(page);
int err = 0;
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset,
bh = sb_bread(inode->i_sb, block);
if (!bh)
{
SetPageError(page);
err = -EIO;
goto out;
}
memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset,
kaddr + offset, to - offset); kaddr + offset, to - offset);
mark_buffer_dirty(bh); mark_inode_dirty(inode);
brelse(bh);
SetPageUptodate(page); SetPageUptodate(page);
out:
kunmap(page); kunmap(page);
/* only one page here */ /* only one page here */
if (to > inode->i_size) if (to > inode->i_size)
inode->i_size = to; inode->i_size = to;
return err; return 0;
} }
struct address_space_operations udf_adinicb_aops = { struct address_space_operations udf_adinicb_aops = {
...@@ -232,9 +190,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -232,9 +190,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
int result = -EINVAL; int result = -EINVAL;
struct buffer_head *bh = NULL;
long_ad eaicb;
uint8_t *ea = NULL;
if ( permission(inode, MAY_READ) != 0 ) if ( permission(inode, MAY_READ) != 0 )
{ {
...@@ -249,7 +204,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -249,7 +204,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return -EINVAL; return -EINVAL;
} }
/* first, do ioctls that don't need to udf_read */
switch (cmd) switch (cmd)
{ {
case UDF_GETVOLIDENT: case UDF_GETVOLIDENT:
...@@ -267,50 +221,16 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -267,50 +221,16 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return result; return result;
} }
}
/* ok, we need to read the inode */
bh = udf_tread(inode->i_sb,
udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));
if (!bh)
{
udf_debug("bread failed (inode=%ld)\n", inode->i_ino);
return -EIO;
}
if (UDF_I_EXTENDED_FE(inode) == 0)
{
struct fileEntry *fe;
fe = (struct fileEntry *)bh->b_data;
eaicb = lela_to_cpu(fe->extendedAttrICB);
if (UDF_I_LENEATTR(inode))
ea = fe->extendedAttr;
}
else
{
struct extendedFileEntry *efe;
efe = (struct extendedFileEntry *)bh->b_data;
eaicb = lela_to_cpu(efe->extendedAttrICB);
if (UDF_I_LENEATTR(inode))
ea = efe->extendedAttr;
}
switch (cmd)
{
case UDF_GETEASIZE: case UDF_GETEASIZE:
result = put_user(UDF_I_LENEATTR(inode), (int *)arg); result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
break; break;
case UDF_GETEABLOCK: case UDF_GETEABLOCK:
result = copy_to_user((char *)arg, ea, result = copy_to_user((char *)arg, UDF_I_DATA(inode),
UDF_I_LENEATTR(inode)) ? -EFAULT : 0; UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
break; break;
} }
udf_release_data(bh);
return result; return result;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/udf_fs.h> #include <linux/udf_fs.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h>
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
...@@ -135,13 +136,20 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) ...@@ -135,13 +136,20 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
inode->i_blocks = 0; inode->i_blocks = 0;
UDF_I_LENEATTR(inode) = 0; UDF_I_LENEATTR(inode) = 0;
UDF_I_LENALLOC(inode) = 0; UDF_I_LENALLOC(inode) = 0;
UDF_I_USE(inode) = 0;
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
{ {
UDF_I_EXTENDED_FE(inode) = 1; UDF_I_EFE(inode) = 1;
UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE); UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);
memset(UDF_I_DATA(inode), 0x00, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
} }
else else
UDF_I_EXTENDED_FE(inode) = 0; {
UDF_I_EFE(inode) = 0;
UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);
memset(UDF_I_DATA(inode), 0x00, inode->i_sb->s_blocksize - sizeof(struct fileEntry));
}
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
...@@ -152,7 +160,6 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) ...@@ -152,7 +160,6 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
UDF_I_CRTIME(inode) = CURRENT_TIME; UDF_I_CRTIME(inode) = CURRENT_TIME;
UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) =
UDF_I_UCRTIME(inode) = CURRENT_UTIME; UDF_I_UCRTIME(inode) = CURRENT_UTIME;
UDF_I_NEW_INODE(inode) = 1;
insert_inode_hash(inode); insert_inode_hash(inode);
mark_inode_dirty(inode); mark_inode_dirty(inode);
......
This diff is collapsed.
...@@ -71,15 +71,10 @@ unsigned long ...@@ -71,15 +71,10 @@ unsigned long
udf_get_last_block(struct super_block *sb) udf_get_last_block(struct super_block *sb)
{ {
struct block_device *bdev = sb->s_bdev; struct block_device *bdev = sb->s_bdev;
int ret;
unsigned long lblock = 0; unsigned long lblock = 0;
ret = ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock); if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock))
if (ret) /* Hard Disk */
{
lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits; lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
}
if (lblock) if (lblock)
return lblock - 1; return lblock - 1;
......
...@@ -74,7 +74,7 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type, ...@@ -74,7 +74,7 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
*bh = udf_tread(inode->i_sb, inode->i_ino); *bh = udf_tread(inode->i_sb, inode->i_ino);
if (UDF_I_EXTENDED_FE(inode) == 0) if (UDF_I_EFE(inode) == 0)
{ {
struct fileEntry *fe; struct fileEntry *fe;
...@@ -190,7 +190,7 @@ udf_get_extendedattr(struct inode * inode, uint32_t type, uint8_t subtype, ...@@ -190,7 +190,7 @@ udf_get_extendedattr(struct inode * inode, uint32_t type, uint8_t subtype,
*bh = udf_tread(inode->i_sb, inode->i_ino); *bh = udf_tread(inode->i_sb, inode->i_ino);
if (UDF_I_EXTENDED_FE(inode) == 0) if (UDF_I_EFE(inode) == 0)
{ {
struct fileEntry *fe; struct fileEntry *fe;
...@@ -269,10 +269,10 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1 ...@@ -269,10 +269,10 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
if (block == 0xFFFFFFFF) if (block == 0xFFFFFFFF)
return NULL; return NULL;
bh = udf_tread(sb, block); bh = udf_tread(sb, block + UDF_SB_SESSION(sb));
if (!bh) if (!bh)
{ {
udf_debug("block=%d, location=%d: read failed\n", block, location); udf_debug("block=%d, location=%d: read failed\n", block + UDF_SB_SESSION(sb), location);
return NULL; return NULL;
} }
...@@ -283,7 +283,7 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1 ...@@ -283,7 +283,7 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
if ( location != le32_to_cpu(tag_p->tagLocation) ) if ( location != le32_to_cpu(tag_p->tagLocation) )
{ {
udf_debug("location mismatch block %u, tag %u != %u\n", udf_debug("location mismatch block %u, tag %u != %u\n",
block, le32_to_cpu(tag_p->tagLocation), location); block + UDF_SB_SESSION(sb), le32_to_cpu(tag_p->tagLocation), location);
goto error_out; goto error_out;
} }
...@@ -315,7 +315,7 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1 ...@@ -315,7 +315,7 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
return bh; return bh;
} }
udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", udf_debug("Crc failure block %d: crc = %d, crclen = %d\n",
block, le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength)); block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength));
error_out: error_out:
brelse(bh); brelse(bh);
......
This diff is collapsed.
...@@ -83,7 +83,7 @@ struct appIdentSuffix ...@@ -83,7 +83,7 @@ struct appIdentSuffix
{ {
uint8_t impUse[8]; uint8_t impUse[8];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Logical Volume Integrity Descriptor (UDF 2.01 2.2.6) */ /* Logical Volume Integrity Descriptor (UDF 2.01 2.2.6) */
/* Implementation Use (UDF 2.01 2.2.6.4) */ /* Implementation Use (UDF 2.01 2.2.6.4) */
struct logicalVolIntegrityDescImpUse struct logicalVolIntegrityDescImpUse
......
...@@ -135,7 +135,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) ...@@ -135,7 +135,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
SLAB_CTOR_CONSTRUCTOR) SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode); inode_init_once(&ei->vfs_inode);
} }
static int init_inodecache(void) static int init_inodecache(void)
{ {
udf_inode_cachep = kmem_cache_create("udf_inode_cache", udf_inode_cachep = kmem_cache_create("udf_inode_cache",
...@@ -161,6 +161,7 @@ static struct super_operations udf_sb_ops = { ...@@ -161,6 +161,7 @@ static struct super_operations udf_sb_ops = {
.write_inode = udf_write_inode, .write_inode = udf_write_inode,
.put_inode = udf_put_inode, .put_inode = udf_put_inode,
.delete_inode = udf_delete_inode, .delete_inode = udf_delete_inode,
.clear_inode = udf_clear_inode,
.put_super = udf_put_super, .put_super = udf_put_super,
.write_super = udf_write_super, .write_super = udf_write_super,
.statfs = udf_statfs, .statfs = udf_statfs,
...@@ -285,7 +286,8 @@ udf_parse_options(char *options, struct udf_options *uopt) ...@@ -285,7 +286,8 @@ udf_parse_options(char *options, struct udf_options *uopt)
if (!options) if (!options)
return 1; return 1;
while ((opt = strsep(&options, ",")) != NULL) { while ((opt = strsep(&options, ",")) != NULL)
{
if (!*opt) if (!*opt)
continue; continue;
/* Make "opt=val" into two strings */ /* Make "opt=val" into two strings */
...@@ -383,10 +385,6 @@ udf_remount_fs(struct super_block *sb, int *flags, char *options) ...@@ -383,10 +385,6 @@ udf_remount_fs(struct super_block *sb, int *flags, char *options)
UDF_SB(sb)->s_gid = uopt.gid; UDF_SB(sb)->s_gid = uopt.gid;
UDF_SB(sb)->s_umask = uopt.umask; UDF_SB(sb)->s_umask = uopt.umask;
#if UDFFS_RW != 1
*flags |= MS_RDONLY;
#endif
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
return 0; return 0;
if (*flags & MS_RDONLY) if (*flags & MS_RDONLY)
...@@ -591,14 +589,14 @@ udf_find_anchor(struct super_block *sb) ...@@ -591,14 +589,14 @@ udf_find_anchor(struct super_block *sb)
{ {
if (location == last[i] - UDF_SB_SESSION(sb)) if (location == last[i] - UDF_SB_SESSION(sb))
{ {
lastblock = UDF_SB_ANCHOR(sb)[0] = last[i]; lastblock = UDF_SB_ANCHOR(sb)[0] = last[i] - UDF_SB_SESSION(sb);
UDF_SB_ANCHOR(sb)[1] = last[i] - 256; UDF_SB_ANCHOR(sb)[1] = last[i] - 256 - UDF_SB_SESSION(sb);
} }
else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb)) else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
{ {
UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]); lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb);
UDF_SB_ANCHOR(sb)[1] = lastblock - 256; UDF_SB_ANCHOR(sb)[1] = lastblock - 256 - UDF_SB_SESSION(sb);
} }
else else
udf_debug("Anchor found at block %d, location mismatch %d.\n", udf_debug("Anchor found at block %d, location mismatch %d.\n",
...@@ -607,7 +605,7 @@ udf_find_anchor(struct super_block *sb) ...@@ -607,7 +605,7 @@ udf_find_anchor(struct super_block *sb)
else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE) else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE)
{ {
lastblock = last[i]; lastblock = last[i];
UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb); UDF_SB_ANCHOR(sb)[3] = 512;
} }
else else
{ {
...@@ -852,7 +850,7 @@ udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) ...@@ -852,7 +850,7 @@ udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber)) if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber))
{ {
UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */ UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb); UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation);
if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY) if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY; UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;
if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE) if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)
...@@ -1428,10 +1426,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1428,10 +1426,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info)); memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
#if UDFFS_RW != 1
sb->s_flags |= MS_RDONLY;
#endif
if (!udf_parse_options((char *)options, &uopt)) if (!udf_parse_options((char *)options, &uopt))
goto error_out; goto error_out;
...@@ -1478,7 +1472,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1478,7 +1472,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
UDF_SB_LASTBLOCK(sb) = uopt.lastblock; UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0; UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
UDF_SB_ANCHOR(sb)[2] = uopt.anchor; UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
UDF_SB_ANCHOR(sb)[3] = UDF_SB_SESSION(sb) + 256; UDF_SB_ANCHOR(sb)[3] = 256;
if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */ if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
{ {
...@@ -1543,8 +1537,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1543,8 +1537,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
{ {
timestamp ts; timestamp ts;
udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0); udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
udf_info("UDF %s-%s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n", udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
UDFFS_VERSION, UDFFS_RW ? "rw" : "ro", UDFFS_DATE, UDFFS_VERSION, UDFFS_DATE,
UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute, UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
ts.typeAndTimezone); ts.typeAndTimezone);
} }
...@@ -1726,8 +1720,6 @@ udf_put_super(struct super_block *sb) ...@@ -1726,8 +1720,6 @@ udf_put_super(struct super_block *sb)
static int static int
udf_statfs(struct super_block *sb, struct statfs *buf) udf_statfs(struct super_block *sb, struct statfs *buf)
{ {
lock_kernel();
buf->f_type = UDF_SUPER_MAGIC; buf->f_type = UDF_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize; buf->f_bsize = sb->s_blocksize;
buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb)); buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
...@@ -1740,8 +1732,6 @@ udf_statfs(struct super_block *sb, struct statfs *buf) ...@@ -1740,8 +1732,6 @@ udf_statfs(struct super_block *sb, struct statfs *buf)
/* __kernel_fsid_t f_fsid */ /* __kernel_fsid_t f_fsid */
buf->f_namelen = UDF_NAME_LEN; buf->f_namelen = UDF_NAME_LEN;
unlock_kernel();
return 0; return 0;
} }
...@@ -1763,6 +1753,8 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) ...@@ -1763,6 +1753,8 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
uint16_t ident; uint16_t ident;
struct spaceBitmapDesc *bm; struct spaceBitmapDesc *bm;
lock_kernel();
loc.logicalBlockNum = bitmap->s_extPosition; loc.logicalBlockNum = bitmap->s_extPosition;
loc.partitionReferenceNum = UDF_SB_PARTITION(sb); loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
bh = udf_read_ptagged(sb, loc, 0, &ident); bh = udf_read_ptagged(sb, loc, 0, &ident);
...@@ -1770,13 +1762,13 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) ...@@ -1770,13 +1762,13 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
if (!bh) if (!bh)
{ {
printk(KERN_ERR "udf: udf_count_free failed\n"); printk(KERN_ERR "udf: udf_count_free failed\n");
return 0; goto out;
} }
else if (ident != TAG_IDENT_SBD) else if (ident != TAG_IDENT_SBD)
{ {
udf_release_data(bh); udf_release_data(bh);
printk(KERN_ERR "udf: udf_count_free failed\n"); printk(KERN_ERR "udf: udf_count_free failed\n");
return 0; goto out;
} }
bm = (struct spaceBitmapDesc *)bh->b_data; bm = (struct spaceBitmapDesc *)bh->b_data;
...@@ -1802,13 +1794,17 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) ...@@ -1802,13 +1794,17 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
if (!bh) if (!bh)
{ {
udf_debug("read failed\n"); udf_debug("read failed\n");
return accum; goto out;
} }
index = 0; index = 0;
ptr = (uint8_t *)bh->b_data; ptr = (uint8_t *)bh->b_data;
} }
} }
udf_release_data(bh); udf_release_data(bh);
out:
unlock_kernel();
return accum; return accum;
} }
...@@ -1821,6 +1817,8 @@ udf_count_free_table(struct super_block *sb, struct inode * table) ...@@ -1821,6 +1817,8 @@ udf_count_free_table(struct super_block *sb, struct inode * table)
int8_t etype; int8_t etype;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
lock_kernel();
bloc = UDF_I_LOCATION(table); bloc = UDF_I_LOCATION(table);
extoffset = sizeof(struct unallocSpaceEntry); extoffset = sizeof(struct unallocSpaceEntry);
...@@ -1829,6 +1827,9 @@ udf_count_free_table(struct super_block *sb, struct inode * table) ...@@ -1829,6 +1827,9 @@ udf_count_free_table(struct super_block *sb, struct inode * table)
accum += (elen >> table->i_sb->s_blocksize_bits); accum += (elen >> table->i_sb->s_blocksize_bits);
} }
udf_release_data(bh); udf_release_data(bh);
unlock_kernel();
return accum; return accum;
} }
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include "udf_i.h" #include "udf_i.h"
static void udf_pc_to_char(char *from, int fromlen, char *to) static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to)
{ {
struct pathComponent *pc; struct pathComponent *pc;
int elen = 0; int elen = 0;
...@@ -66,9 +66,9 @@ static void udf_pc_to_char(char *from, int fromlen, char *to) ...@@ -66,9 +66,9 @@ static void udf_pc_to_char(char *from, int fromlen, char *to)
/* that would be . - just ignore */ /* that would be . - just ignore */
break; break;
case 5: case 5:
memcpy(p, pc->componentIdent, pc->lengthComponentIdent); p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);
p += pc->lengthComponentIdent;
*p++ = '/'; *p++ = '/';
break;
} }
elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
} }
...@@ -85,17 +85,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) ...@@ -85,17 +85,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
char *symlink; char *symlink;
int err = -EIO; int err = -EIO;
char *p = kmap(page); char *p = kmap(page);
lock_kernel(); lock_kernel();
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
{ symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
bh = udf_tread(inode->i_sb, inode->i_ino);
if (!bh)
goto out;
symlink = bh->b_data + udf_file_entry_alloc_offset(inode);
}
else else
{ {
bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
...@@ -106,7 +99,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) ...@@ -106,7 +99,7 @@ static int udf_symlink_filler(struct file *file, struct page *page)
symlink = bh->b_data; symlink = bh->b_data;
} }
udf_pc_to_char(symlink, inode->i_size, p); udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
udf_release_data(bh); udf_release_data(bh);
unlock_kernel(); unlock_kernel();
......
...@@ -95,7 +95,7 @@ void udf_truncate_extents(struct inode * inode) ...@@ -95,7 +95,7 @@ void udf_truncate_extents(struct inode * inode)
else else
lenalloc = extoffset - adsize; lenalloc = extoffset - adsize;
if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr))) if (!bh)
lenalloc -= udf_file_entry_alloc_offset(inode); lenalloc -= udf_file_entry_alloc_offset(inode);
else else
lenalloc -= sizeof(struct allocExtDesc); lenalloc -= sizeof(struct allocExtDesc);
...@@ -108,15 +108,15 @@ void udf_truncate_extents(struct inode * inode) ...@@ -108,15 +108,15 @@ void udf_truncate_extents(struct inode * inode)
extoffset = 0; extoffset = 0;
if (lelen) if (lelen)
{ {
if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr))) if (!bh)
memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode)); BUG();
else else
memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
} }
else else
{ {
if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr))) if (!bh)
{ {
UDF_I_LENALLOC(inode) = lenalloc; UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);
...@@ -135,9 +135,9 @@ void udf_truncate_extents(struct inode * inode) ...@@ -135,9 +135,9 @@ void udf_truncate_extents(struct inode * inode)
} }
udf_release_data(bh); udf_release_data(bh);
bh = NULL; extoffset = sizeof(struct allocExtDesc);
bloc = eloc; bloc = eloc;
bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0));
if (elen) if (elen)
lelen = (elen + inode->i_sb->s_blocksize - 1) >> lelen = (elen + inode->i_sb->s_blocksize - 1) >>
inode->i_sb->s_blocksize_bits; inode->i_sb->s_blocksize_bits;
...@@ -153,15 +153,15 @@ void udf_truncate_extents(struct inode * inode) ...@@ -153,15 +153,15 @@ void udf_truncate_extents(struct inode * inode)
if (lelen) if (lelen)
{ {
if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr))) if (!bh)
memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode)); BUG();
else else
memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
} }
else else
{ {
if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr))) if (!bh)
{ {
UDF_I_LENALLOC(inode) = lenalloc; UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);
......
...@@ -13,14 +13,17 @@ static inline struct udf_inode_info *UDF_I(struct inode *inode) ...@@ -13,14 +13,17 @@ static inline struct udf_inode_info *UDF_I(struct inode *inode)
#define UDF_I_LENEXTENTS(X) ( UDF_I(X)->i_lenExtents ) #define UDF_I_LENEXTENTS(X) ( UDF_I(X)->i_lenExtents )
#define UDF_I_UNIQUE(X) ( UDF_I(X)->i_unique ) #define UDF_I_UNIQUE(X) ( UDF_I(X)->i_unique )
#define UDF_I_ALLOCTYPE(X) ( UDF_I(X)->i_alloc_type ) #define UDF_I_ALLOCTYPE(X) ( UDF_I(X)->i_alloc_type )
#define UDF_I_EXTENDED_FE(X) ( UDF_I(X)->i_extended_fe ) #define UDF_I_EFE(X) ( UDF_I(X)->i_efe )
#define UDF_I_STRAT4096(X) ( UDF_I(X)->i_strat_4096 ) #define UDF_I_USE(X) ( UDF_I(X)->i_use )
#define UDF_I_NEW_INODE(X) ( UDF_I(X)->i_new_inode ) #define UDF_I_STRAT4096(X) ( UDF_I(X)->i_strat4096 )
#define UDF_I_NEXT_ALLOC_BLOCK(X) ( UDF_I(X)->i_next_alloc_block ) #define UDF_I_NEXT_ALLOC_BLOCK(X) ( UDF_I(X)->i_next_alloc_block )
#define UDF_I_NEXT_ALLOC_GOAL(X) ( UDF_I(X)->i_next_alloc_goal ) #define UDF_I_NEXT_ALLOC_GOAL(X) ( UDF_I(X)->i_next_alloc_goal )
#define UDF_I_UMTIME(X) ( UDF_I(X)->i_umtime ) #define UDF_I_UMTIME(X) ( UDF_I(X)->i_umtime )
#define UDF_I_UCTIME(X) ( UDF_I(X)->i_uctime ) #define UDF_I_UCTIME(X) ( UDF_I(X)->i_uctime )
#define UDF_I_CRTIME(X) ( UDF_I(X)->i_crtime ) #define UDF_I_CRTIME(X) ( UDF_I(X)->i_crtime )
#define UDF_I_UCRTIME(X) ( UDF_I(X)->i_ucrtime ) #define UDF_I_UCRTIME(X) ( UDF_I(X)->i_ucrtime )
#define UDF_I_SAD(X) ( UDF_I(X)->i_ext.i_sad )
#define UDF_I_LAD(X) ( UDF_I(X)->i_ext.i_lad )
#define UDF_I_DATA(X) ( UDF_I(X)->i_ext.i_data )
#endif /* !defined(_LINUX_UDF_I_H) */ #endif /* !defined(_LINUX_UDF_I_H) */
...@@ -16,10 +16,6 @@ ...@@ -16,10 +16,6 @@
#include <linux/version.h> #include <linux/version.h>
#endif #endif
#if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
#define CONFIG_UDF_FS_MODULE
#endif
#include "udfend.h" #include "udfend.h"
#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
...@@ -35,9 +31,11 @@ ...@@ -35,9 +31,11 @@
#define CURRENT_UTIME (xtime.tv_nsec / 1000) #define CURRENT_UTIME (xtime.tv_nsec / 1000)
#define udf_file_entry_alloc_offset(inode)\ #define udf_file_entry_alloc_offset(inode)\
((UDF_I_EXTENDED_FE(inode) ?\ (UDF_I_USE(inode) ?\
sizeof(struct extendedFileEntry) :\ sizeof(struct unallocSpaceEntry) :\
sizeof(struct fileEntry)) + UDF_I_LENEATTR(inode)) ((UDF_I_EFE(inode) ?\
sizeof(struct extendedFileEntry) :\
sizeof(struct fileEntry)) + UDF_I_LENEATTR(inode)))
#define udf_ext0_offset(inode)\ #define udf_ext0_offset(inode)\
(UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ?\ (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ?\
...@@ -114,6 +112,7 @@ extern void udf_truncate(struct inode *); ...@@ -114,6 +112,7 @@ extern void udf_truncate(struct inode *);
extern void udf_read_inode(struct inode *); extern void udf_read_inode(struct inode *);
extern void udf_put_inode(struct inode *); extern void udf_put_inode(struct inode *);
extern void udf_delete_inode(struct inode *); extern void udf_delete_inode(struct inode *);
extern void udf_clear_inode(struct inode *);
extern void udf_write_inode(struct inode *, int); extern void udf_write_inode(struct inode *, int);
extern long udf_block_map(struct inode *, long); extern long udf_block_map(struct inode *, long);
extern int8_t inode_bmap(struct inode *, int, lb_addr *, uint32_t *, lb_addr *, uint32_t *, uint32_t *, struct buffer_head **); extern int8_t inode_bmap(struct inode *, int, lb_addr *, uint32_t *, lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
...@@ -134,6 +133,10 @@ extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint ...@@ -134,6 +133,10 @@ extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint
extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *);
extern struct buffer_head *udf_read_ptagged(struct super_block *, lb_addr, uint32_t, uint16_t *); extern struct buffer_head *udf_read_ptagged(struct super_block *, lb_addr, uint32_t, uint16_t *);
extern void udf_release_data(struct buffer_head *); extern void udf_release_data(struct buffer_head *);
extern uint32_t udf64_low32(uint64_t);
extern uint32_t udf64_high32(uint64_t);
extern void udf_update_tag(char *, int);
extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
/* lowlevel.c */ /* lowlevel.c */
extern unsigned int udf_get_last_session(struct super_block *); extern unsigned int udf_get_last_session(struct super_block *);
...@@ -148,6 +151,9 @@ extern int udf_relocate_blocks(struct super_block *, long, long *); ...@@ -148,6 +151,9 @@ extern int udf_relocate_blocks(struct super_block *, long, long *);
/* unicode.c */ /* unicode.c */
extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, int);
extern int udf_build_ustr(struct ustr *, dstring *, int);
extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
/* ialloc.c */ /* ialloc.c */
extern void udf_free_inode(struct inode *); extern void udf_free_inode(struct inode *);
...@@ -168,40 +174,17 @@ extern int udf_fsync_inode(struct inode *, int); ...@@ -168,40 +174,17 @@ extern int udf_fsync_inode(struct inode *, int);
/* directory.c */ /* directory.c */
extern uint8_t * udf_filead_read(struct inode *, uint8_t *, uint8_t, lb_addr, int *, int *, struct buffer_head **, int *); extern uint8_t * udf_filead_read(struct inode *, uint8_t *, uint8_t, lb_addr, int *, int *, struct buffer_head **, int *);
extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, lb_addr *, uint32_t *, lb_addr *, uint32_t *, uint32_t *, struct buffer_head **); extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, lb_addr *, uint32_t *, lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
/* unicode.c */ extern extent_ad * udf_get_fileextent(void * buffer, int bufsize, int * offset);
extern int udf_ustr_to_dchars(uint8_t *, const struct ustr *, int); extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int);
extern int udf_ustr_to_char(uint8_t *, const struct ustr *, int); extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int);
extern int udf_ustr_to_dstring(dstring *, const struct ustr *, int); extern uint8_t * udf_get_filead(struct fileEntry *, uint8_t *, int, int, int, int *);
extern int udf_dchars_to_ustr(struct ustr *, const uint8_t *, int);
extern int udf_char_to_ustr(struct ustr *, const uint8_t *, int);
extern int udf_dstring_to_ustr(struct ustr *, const dstring *, int);
extern int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
extern int udf_build_ustr(struct ustr *, dstring *, int);
extern int udf_build_ustr_exact(struct ustr *, dstring *, int);
extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
extern int udf_UTF8toCS0(dstring *, struct ustr *, int);
extern int udf_CS0toNLS(struct nls_table *, struct ustr *, struct ustr *);
extern int udf_NLStoCS0(struct nls_table *, dstring *, struct ustr *, int);
/* crc.c */ /* crc.c */
extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t); extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
/* misc.c */
extern uint32_t udf64_low32(uint64_t);
extern uint32_t udf64_high32(uint64_t);
extern void udf_update_tag(char *, int);
extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
/* udftime.c */ /* udftime.c */
extern time_t *udf_stamp_to_time(time_t *, long *, timestamp); extern time_t *udf_stamp_to_time(time_t *, long *, timestamp);
extern timestamp *udf_time_to_stamp(timestamp *, time_t, long); extern timestamp *udf_time_to_stamp(timestamp *, time_t, long);
/* directory.c */
extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
extern extent_ad * udf_get_fileextent(void * buffer, int bufsize, int * offset);
extern long_ad * udf_get_filelongad(void * buffer, int bufsize, int * offset, int);
extern short_ad * udf_get_fileshortad(void * buffer, int bufsize, int * offset, int);
extern uint8_t * udf_get_filead(struct fileEntry *, uint8_t *, int, int, int, int *);
#endif /* __UDF_DECL_H */ #endif /* __UDF_DECL_H */
...@@ -32,46 +32,9 @@ ...@@ -32,46 +32,9 @@
#include "udf_sb.h" #include "udf_sb.h"
int udf_ustr_to_dchars(uint8_t *dest, const struct ustr *src, int strlen) static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
{
if ( (!dest) || (!src) || (!strlen) || (src->u_len > strlen) )
return 0;
memcpy(dest+1, src->u_name, src->u_len);
dest[0] = src->u_cmpID;
return src->u_len + 1;
}
int udf_ustr_to_char(uint8_t *dest, const struct ustr *src, int strlen)
{
if ( (!dest) || (!src) || (!strlen) || (src->u_len >= strlen) )
return 0;
memcpy(dest, src->u_name, src->u_len);
return src->u_len;
}
int udf_ustr_to_dstring(dstring *dest, const struct ustr *src, int dlength)
{
if ( udf_ustr_to_dchars(dest, src, dlength-1) )
{
dest[dlength-1] = src->u_len + 1;
return dlength;
}
else
return 0;
}
int udf_dchars_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
{
if ( (!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN) )
return 0;
memset(dest, 0, sizeof(struct ustr));
memcpy(dest->u_name, src+1, strlen-1);
dest->u_cmpID = src[0];
dest->u_len = strlen-1;
return strlen-1;
}
int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
{ {
if ( (!dest) || (!src) || (!strlen) || (strlen >= UDF_NAME_LEN) ) if ( (!dest) || (!src) || (!strlen) || (strlen >= UDF_NAME_LEN) )
return 0; return 0;
...@@ -82,15 +45,6 @@ int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) ...@@ -82,15 +45,6 @@ int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
return strlen; return strlen;
} }
int udf_dstring_to_ustr(struct ustr *dest, const dstring *src, int dlength)
{
if ( dlength && udf_dchars_to_ustr(dest, src, src[dlength-1]) )
return dlength;
else
return 0;
}
/* /*
* udf_build_ustr * udf_build_ustr
*/ */
...@@ -112,7 +66,7 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) ...@@ -112,7 +66,7 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
/* /*
* udf_build_ustr_exact * udf_build_ustr_exact
*/ */
int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
{ {
if ( (!dest) || (!ptr) || (!exactsize) ) if ( (!dest) || (!ptr) || (!exactsize) )
return -1; return -1;
...@@ -224,7 +178,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) ...@@ -224,7 +178,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
* November 12, 1997 - Andrew E. Mileski * November 12, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
{ {
unsigned c, i, max_val, utf_char; unsigned c, i, max_val, utf_char;
int utf_cnt; int utf_cnt;
...@@ -318,7 +272,7 @@ int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) ...@@ -318,7 +272,7 @@ int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
return u_len + 1; return u_len + 1;
} }
int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i) static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i)
{ {
uint8_t *ocu; uint8_t *ocu;
uint32_t c; uint32_t c;
...@@ -360,7 +314,7 @@ int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i) ...@@ -360,7 +314,7 @@ int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i)
return utf_o->u_len; return utf_o->u_len;
} }
int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length) static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length)
{ {
unsigned len, i, max_val; unsigned len, i, max_val;
uint16_t uni_char; uint16_t uni_char;
...@@ -434,12 +388,42 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int ...@@ -434,12 +388,42 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int
return 0; return 0;
} }
int udf_put_filename(struct super_block *sb, const uint8_t *sname, uint8_t *dname, int flen)
{
struct ustr unifilename;
int namelen;
if ( !(udf_char_to_ustr(&unifilename, sname, flen)) )
{
return 0;
}
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
{
if ( !(namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN)) )
{
return 0;
}
}
else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
{
if ( !(namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename, UDF_NAME_LEN)) )
{
return 0;
}
}
else
return 0;
return namelen;
}
#define ILLEGAL_CHAR_MARK '_' #define ILLEGAL_CHAR_MARK '_'
#define EXT_MARK '.' #define EXT_MARK '.'
#define CRC_MARK '#' #define CRC_MARK '#'
#define EXT_SIZE 5 #define EXT_SIZE 5
int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen, uint8_t *fidName, int fidNameLen) static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen, uint8_t *fidName, int fidNameLen)
{ {
int index, newIndex = 0, needsCRC = 0; int index, newIndex = 0, needsCRC = 0;
int extIndex = 0, newExtIndex = 0, hasExt = 0; int extIndex = 0, newExtIndex = 0, hasExt = 0;
......
...@@ -34,23 +34,11 @@ ...@@ -34,23 +34,11 @@
#ifndef _UDF_FS_H #ifndef _UDF_FS_H
#define _UDF_FS_H 1 #define _UDF_FS_H 1
#include <linux/config.h>
#define UDF_PREALLOCATE #define UDF_PREALLOCATE
#define UDF_DEFAULT_PREALLOC_BLOCKS 8 #define UDF_DEFAULT_PREALLOC_BLOCKS 8
#define UDFFS_DATE "2002/03/11" #define UDFFS_DATE "2002/11/15"
#define UDFFS_VERSION "0.9.6" #define UDFFS_VERSION "0.9.7"
#if !defined(UDFFS_RW)
#if defined(CONFIG_UDF_RW)
#define UDFFS_RW 1
#else /* !defined(CONFIG_UDF_RW) */
#define UDFFS_RW 0
#endif /* defined(CONFIG_UDF_RW) */
#endif /* !defined(UDFFS_RW) */
#define UDFFS_DEBUG #define UDFFS_DEBUG
......
...@@ -23,30 +23,49 @@ ...@@ -23,30 +23,49 @@
#ifndef _ECMA_167_H #ifndef _ECMA_167_H
typedef struct typedef struct
{ {
__u32 logicalBlockNum; __u32 logicalBlockNum;
__u16 partitionReferenceNum; __u16 partitionReferenceNum;
} __attribute__ ((packed)) lb_addr; } __attribute__ ((packed)) lb_addr;
typedef struct
{
__u32 extLength;
__u32 extPosition;
} __attribute__ ((packed)) short_ad;
typedef struct
{
__u32 extLength;
lb_addr extLocation;
__u8 impUse[6];
} __attribute__ ((packed)) long_ad;
#endif #endif
struct udf_inode_info struct udf_inode_info
{ {
long i_umtime; long i_umtime;
long i_uctime; long i_uctime;
long i_crtime; long i_crtime;
long i_ucrtime; long i_ucrtime;
/* Physical address of inode */ /* Physical address of inode */
lb_addr i_location; lb_addr i_location;
__u64 i_unique; __u64 i_unique;
__u32 i_lenEAttr; __u32 i_lenEAttr;
__u32 i_lenAlloc; __u32 i_lenAlloc;
__u64 i_lenExtents; __u64 i_lenExtents;
__u32 i_next_alloc_block; __u32 i_next_alloc_block;
__u32 i_next_alloc_goal; __u32 i_next_alloc_goal;
unsigned i_alloc_type : 3; unsigned i_alloc_type : 3;
unsigned i_extended_fe : 1; unsigned i_efe : 1;
unsigned i_strat_4096 : 1; unsigned i_use : 1;
unsigned i_new_inode : 1; unsigned i_strat4096 : 1;
unsigned reserved : 26; unsigned reserved : 26;
union
{
short_ad *i_sad;
long_ad *i_lad;
__u8 *i_data;
} i_ext;
struct inode vfs_inode; struct inode vfs_inode;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment