udf: Remove declarations of arrays of size UDF_NAME_LEN (256 bytes)
There are several places in UDF where we declared temporary arrays of UDF_NAME_LEN bytes on stack. This is not nice to stack usage so this patch changes those places to use kmalloc() instead. Also clean up bail-out paths in those functions when we are changing them. Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
57
fs/udf/dir.c
57
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,25 +168,21 @@ 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;
|
||||
}
|
||||
|
||||
static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
|
Reference in New Issue
Block a user