Skip to content

Commit

Permalink
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jack/linux-udf-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6:
  UDF: Close small mem leak in udf_find_entry()
  udf: Fix directory corruption after extent merging
  udf: Protect udf_file_aio_write from possible races
  udf: Remove unnecessary bkl usages
  udf: Use of s_alloc_mutex to serialize udf_relocate_blocks() execution
  udf: Replace bkl with the UDF_I(inode)->i_data_sem for protect udf_inode_info struct
  udf: Remove BKL from free space counting functions
  udf: Call udf_add_free_space() for more blocks at once in udf_free_blocks()
  udf: Remove BKL from udf_put_super() and udf_remount_fs()
  udf: Protect default inode credentials by rwlock
  udf: Protect all modifications of LVID with s_alloc_mutex
  udf: Move handling of uniqueID into a helper function and protect it by a s_alloc_mutex
  udf: Remove BKL from udf_update_inode
  udf: Convert UDF_SB(sb)->s_flags to use bitops
  fs/udf: Add printf format/argument verification
  fs/udf: Use vzalloc

(Evil merge: this also removes the BKL dependency from the Kconfig file)
  • Loading branch information
torvalds committed Jan 11, 2011
2 parents e9688f6 + a4264b3 commit 7c955fc
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 180 deletions.
1 change: 0 additions & 1 deletion fs/udf/Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
config UDF_FS
tristate "UDF file system support"
depends on BKL # needs serious work to remove
select CRC_ITU_T
help
This is the new file system used on some CD-ROMs and DVDs. Say Y if
Expand Down
3 changes: 1 addition & 2 deletions fs/udf/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
udf_debug("bit %ld already set\n", bit + i);
udf_debug("byte=%2x\n",
((char *)bh->b_data)[(bit + i) >> 3]);
} else {
udf_add_free_space(sb, sbi->s_partition, 1);
}
}
udf_add_free_space(sb, sbi->s_partition, count);
mark_buffer_dirty(bh);
if (overflow) {
block += count;
Expand Down
5 changes: 0 additions & 5 deletions fs/udf/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>

#include "udf_i.h"
Expand Down Expand Up @@ -190,18 +189,14 @@ static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct inode *dir = filp->f_path.dentry->d_inode;
int result;

lock_kernel();

if (filp->f_pos == 0) {
if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) {
unlock_kernel();
return 0;
}
filp->f_pos++;
}

result = do_udf_readdir(dir, filp, filldir, dirent);
unlock_kernel();
return result;
}

Expand Down
11 changes: 5 additions & 6 deletions fs/udf/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <linux/string.h> /* memset */
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/aio.h>
Expand Down Expand Up @@ -114,6 +113,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
size_t count = iocb->ki_left;
struct udf_inode_info *iinfo = UDF_I(inode);

down_write(&iinfo->i_data_sem);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
if (file->f_flags & O_APPEND)
pos = inode->i_size;
Expand All @@ -126,6 +126,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
udf_expand_file_adinicb(inode, pos + count, &err);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
udf_debug("udf_expand_adinicb: err=%d\n", err);
up_write(&iinfo->i_data_sem);
return err;
}
} else {
Expand All @@ -135,6 +136,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
iinfo->i_lenAlloc = inode->i_size;
}
}
up_write(&iinfo->i_data_sem);

retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
if (retval > 0)
Expand All @@ -149,8 +151,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
long old_block, new_block;
int result = -EINVAL;

lock_kernel();

if (file_permission(filp, MAY_READ) != 0) {
udf_debug("no permission to access inode %lu\n", inode->i_ino);
result = -EPERM;
Expand Down Expand Up @@ -196,18 +196,17 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}

out:
unlock_kernel();
return result;
}

static int udf_release_file(struct inode *inode, struct file *filp)
{
if (filp->f_mode & FMODE_WRITE) {
mutex_lock(&inode->i_mutex);
lock_kernel();
down_write(&UDF_I(inode)->i_data_sem);
udf_discard_prealloc(inode);
udf_truncate_tail_extent(inode);
unlock_kernel();
up_write(&UDF_I(inode)->i_data_sem);
mutex_unlock(&inode->i_mutex);
}
return 0;
Expand Down
21 changes: 6 additions & 15 deletions fs/udf/ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,19 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
return NULL;
}

mutex_lock(&sbi->s_alloc_mutex);
if (sbi->s_lvid_bh) {
struct logicalVolIntegrityDesc *lvid =
(struct logicalVolIntegrityDesc *)
sbi->s_lvid_bh->b_data;
struct logicalVolIntegrityDescImpUse *lvidiu =
udf_sb_lvidiu(sbi);
struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)
(lvid->logicalVolContentsUse);
struct logicalVolIntegrityDescImpUse *lvidiu;

iinfo->i_unique = lvid_get_unique_id(sb);
mutex_lock(&sbi->s_alloc_mutex);
lvidiu = udf_sb_lvidiu(sbi);
if (S_ISDIR(mode))
le32_add_cpu(&lvidiu->numDirs, 1);
else
le32_add_cpu(&lvidiu->numFiles, 1);
iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID);
if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID);
udf_updated_lvid(sb);
mutex_unlock(&sbi->s_alloc_mutex);
}
mutex_unlock(&sbi->s_alloc_mutex);

inode_init_owner(inode, dir, mode);

Expand Down
51 changes: 22 additions & 29 deletions fs/udf/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

#include "udfdecl.h"
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
Expand All @@ -51,6 +50,7 @@ MODULE_LICENSE("GPL");
static mode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *);
static int udf_sync_inode(struct inode *inode);
static int udf_alloc_i_data(struct inode *inode, size_t size);
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
sector_t *, int *);
Expand Down Expand Up @@ -79,9 +79,7 @@ void udf_evict_inode(struct inode *inode)
want_delete = 1;
inode->i_size = 0;
udf_truncate(inode);
lock_kernel();
udf_update_inode(inode, IS_SYNC(inode));
unlock_kernel();
}
invalidate_inode_buffers(inode);
end_writeback(inode);
Expand All @@ -97,9 +95,7 @@ void udf_evict_inode(struct inode *inode)
kfree(iinfo->i_ext.i_data);
iinfo->i_ext.i_data = NULL;
if (want_delete) {
lock_kernel();
udf_free_inode(inode);
unlock_kernel();
}
}

Expand Down Expand Up @@ -302,10 +298,9 @@ static int udf_get_block(struct inode *inode, sector_t block,
err = -EIO;
new = 0;
bh = NULL;

lock_kernel();

iinfo = UDF_I(inode);

down_write(&iinfo->i_data_sem);
if (block == iinfo->i_next_alloc_block + 1) {
iinfo->i_next_alloc_block++;
iinfo->i_next_alloc_goal++;
Expand All @@ -324,7 +319,7 @@ static int udf_get_block(struct inode *inode, sector_t block,
map_bh(bh_result, inode->i_sb, phys);

abort:
unlock_kernel();
up_write(&iinfo->i_data_sem);
return err;
}

Expand Down Expand Up @@ -1022,16 +1017,16 @@ void udf_truncate(struct inode *inode)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;

lock_kernel();
iinfo = UDF_I(inode);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
down_write(&iinfo->i_data_sem);
if (inode->i_sb->s_blocksize <
(udf_file_entry_alloc_offset(inode) +
inode->i_size)) {
udf_expand_file_adinicb(inode, inode->i_size, &err);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
inode->i_size = iinfo->i_lenAlloc;
unlock_kernel();
up_write(&iinfo->i_data_sem);
return;
} else
udf_truncate_extents(inode);
Expand All @@ -1042,18 +1037,20 @@ void udf_truncate(struct inode *inode)
offset - udf_file_entry_alloc_offset(inode));
iinfo->i_lenAlloc = inode->i_size;
}
up_write(&iinfo->i_data_sem);
} else {
block_truncate_page(inode->i_mapping, inode->i_size,
udf_get_block);
down_write(&iinfo->i_data_sem);
udf_truncate_extents(inode);
up_write(&iinfo->i_data_sem);
}

inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
if (IS_SYNC(inode))
udf_sync_inode(inode);
else
mark_inode_dirty(inode);
unlock_kernel();
}

static void __udf_read_inode(struct inode *inode)
Expand Down Expand Up @@ -1202,6 +1199,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
return;
}

read_lock(&sbi->s_cred_lock);
inode->i_uid = le32_to_cpu(fe->uid);
if (inode->i_uid == -1 ||
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) ||
Expand All @@ -1214,13 +1212,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
inode->i_gid = UDF_SB(inode->i_sb)->s_gid;

inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
if (!inode->i_nlink)
inode->i_nlink = 1;

inode->i_size = le64_to_cpu(fe->informationLength);
iinfo->i_lenExtents = inode->i_size;

if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
sbi->s_fmode != UDF_INVALID_MODE)
inode->i_mode = sbi->s_fmode;
Expand All @@ -1230,6 +1221,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
else
inode->i_mode = udf_convert_permissions(fe);
inode->i_mode &= ~sbi->s_umask;
read_unlock(&sbi->s_cred_lock);

inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
if (!inode->i_nlink)
inode->i_nlink = 1;

inode->i_size = le64_to_cpu(fe->informationLength);
iinfo->i_lenExtents = inode->i_size;

if (iinfo->i_efe == 0) {
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
Expand Down Expand Up @@ -1373,16 +1372,10 @@ static mode_t udf_convert_permissions(struct fileEntry *fe)

int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int ret;

lock_kernel();
ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
unlock_kernel();

return ret;
return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}

int udf_sync_inode(struct inode *inode)
static int udf_sync_inode(struct inode *inode)
{
return udf_update_inode(inode, 1);
}
Expand Down Expand Up @@ -2048,15 +2041,15 @@ long udf_block_map(struct inode *inode, sector_t block)
struct extent_position epos = {};
int ret;

lock_kernel();
down_read(&UDF_I(inode)->i_data_sem);

if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30))
ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
else
ret = 0;

unlock_kernel();
up_read(&UDF_I(inode)->i_data_sem);
brelse(epos.bh);

if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
Expand Down
Loading

0 comments on commit 7c955fc

Please sign in to comment.