summaryrefslogtreecommitdiffstats
path: root/fs/udf/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r--fs/udf/namei.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 712cf09fb..ea921eeb3 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -25,6 +25,8 @@
*
*/
+#include "udfdecl.h"
+
#if defined(__linux__) && defined(__KERNEL__)
#include <linux/version.h>
#include "udf_i.h"
@@ -36,8 +38,6 @@
#include <linux/udf_fs.h>
#endif
-#include "udfdecl.h"
-
static inline int udf_match(int len, const char * const name, struct qstr *qs)
{
if (len != qs->len)
@@ -147,13 +147,13 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
struct FileIdentDesc *cfi)
{
struct FileIdentDesc *fi=NULL;
- int f_pos, block;
- int flen;
+ loff_t f_pos;
+ int block, flen;
char fname[255];
char *nameptr;
Uint8 lfi;
Uint16 liu;
- int size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
lb_addr bloc, eloc;
Uint32 extoffset, elen, offset;
struct buffer_head *bh = NULL;
@@ -333,10 +333,10 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
struct ustr unifilename;
char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
int namelen;
- int f_pos;
+ loff_t f_pos;
int flen;
char *nameptr;
- int size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
int nfidlen;
Uint8 lfi;
Uint16 liu;
@@ -492,7 +492,6 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
extoffset -= sizeof(long_ad);
}
- dir->i_size += nfidlen;
if (sb->s_blocksize - fibh->eoffset >= nfidlen)
{
fibh->soffset = fibh->eoffset;
@@ -550,8 +549,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
else
{
elen = ((elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
- block = eloc.logicalBlockNum + ((elen - 1) >>
- dir->i_sb->s_blocksize_bits);
+ block = eloc.logicalBlockNum +
+ ((elen - 1) >> dir->i_sb->s_blocksize_bits);
elen = (EXTENT_RECORDED_ALLOCATED << 30) | elen;
udf_write_aext(dir, bloc, &lextoffset, eloc, elen, &bh, 0);
}
@@ -568,11 +567,30 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (udf_next_aext(dir, &bloc, &lextoffset, &eloc, &elen, &bh, 1) ==
EXTENT_RECORDED_ALLOCATED)
{
- block = eloc.logicalBlockNum + ((elen - 1) >>
- dir->i_sb->s_blocksize_bits);
+ if (block == (eloc.logicalBlockNum +
+ ((elen - 1) >> dir->i_sb->s_blocksize_bits)))
+ {
+ if (udf_next_aext(dir, &bloc, &lextoffset, &eloc, &elen, &bh, 1) !=
+ EXTENT_RECORDED_ALLOCATED)
+ {
+ udf_release_data(bh);
+ udf_release_data(fibh->sbh);
+ udf_release_data(fibh->ebh);
+ udf_debug("next extent not recorded and allocated\n");
+ return NULL;
+ }
+ }
}
else
- block ++;
+ {
+ udf_release_data(bh);
+ udf_release_data(fibh->sbh);
+ udf_release_data(fibh->ebh);
+ udf_debug("next extent not recorded and allocated\n");
+ return NULL;
+ }
+ block = eloc.logicalBlockNum + ((elen - 1) >>
+ dir->i_sb->s_blocksize_bits);
}
fi = (struct FileIdentDesc *)(fibh->sbh->b_data + sb->s_blocksize + fibh->soffset);
@@ -586,6 +604,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (!udf_write_fi(cfi, fi, fibh, NULL, name))
{
udf_release_data(bh);
+ dir->i_size += nfidlen;
if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(dir) += nfidlen;
dir->i_version = ++event;
@@ -595,7 +614,6 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
else
{
udf_release_data(bh);
- dir->i_size -= nfidlen;
if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh);
@@ -807,8 +825,8 @@ static int empty_dir(struct inode *dir)
{
struct FileIdentDesc *fi, cfi;
struct udf_fileident_bh fibh;
- int f_pos;
- int size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t f_pos;
+ loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
int block;
lb_addr bloc, eloc;
Uint32 extoffset, elen, offset;