summary refs log tree commit diff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 14:35:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 14:35:07 -0700
commit041d6d0be82bed7e0b87181dba5d10b8ab14afd9 (patch)
treeb7af53fa7ca104d30b9759c1f951439af7df3734 /fs
parentaf8cb8aa38296ecc43aca7fae9e574db7b8ae0c4 (diff)
parentcbc8cc33529b0e0e55ae0ff077b8cb0b71d54c7a (diff)
downloadlinux-041d6d0be82bed7e0b87181dba5d10b8ab14afd9.tar.gz
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:
  udf: Fix possible corruption when close races with write
  udf: Perform preallocation only for regular files
  udf: Remove wrong assignment in udf_symlink
  udf: Remove dead code
Diffstat (limited to 'fs')
-rw-r--r--fs/udf/directory.c86
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/udf/inode.c19
-rw-r--r--fs/udf/lowlevel.c4
-rw-r--r--fs/udf/namei.c1
5 files changed, 12 insertions, 100 deletions
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 1d2c570704c8..2ffdb6733af1 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -18,59 +18,6 @@
 #include <linux/string.h>
 #include <linux/buffer_head.h>
 
-#if 0
-static uint8_t *udf_filead_read(struct inode *dir, uint8_t *tmpad,
-				uint8_t ad_size, struct kernel_lb_addr fe_loc,
-				int *pos, int *offset, struct buffer_head **bh,
-				int *error)
-{
-	int loffset = *offset;
-	int block;
-	uint8_t *ad;
-	int remainder;
-
-	*error = 0;
-
-	ad = (uint8_t *)(*bh)->b_data + *offset;
-	*offset += ad_size;
-
-	if (!ad) {
-		brelse(*bh);
-		*error = 1;
-		return NULL;
-	}
-
-	if (*offset == dir->i_sb->s_blocksize) {
-		brelse(*bh);
-		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
-		if (!block)
-			return NULL;
-		*bh = udf_tread(dir->i_sb, block);
-		if (!*bh)
-			return NULL;
-	} else if (*offset > dir->i_sb->s_blocksize) {
-		ad = tmpad;
-
-		remainder = dir->i_sb->s_blocksize - loffset;
-		memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
-
-		brelse(*bh);
-		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
-		if (!block)
-			return NULL;
-		(*bh) = udf_tread(dir->i_sb, block);
-		if (!*bh)
-			return NULL;
-
-		memcpy((uint8_t *)ad + remainder, (*bh)->b_data,
-			ad_size - remainder);
-		*offset = ad_size - remainder;
-	}
-
-	return ad;
-}
-#endif
-
 struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
 					 struct udf_fileident_bh *fibh,
 					 struct fileIdentDesc *cfi,
@@ -248,39 +195,6 @@ struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset)
 	return fi;
 }
 
-#if 0
-static struct extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
-{
-	struct extent_ad *ext;
-	struct fileEntry *fe;
-	uint8_t *ptr;
-
-	if ((!buffer) || (!offset)) {
-		printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
-		return NULL;
-	}
-
-	fe = (struct fileEntry *)buffer;
-
-	if (fe->descTag.tagIdent != cpu_to_le16(TAG_IDENT_FE)) {
-		udf_debug("0x%x != TAG_IDENT_FE\n",
-			  le16_to_cpu(fe->descTag.tagIdent));
-		return NULL;
-	}
-
-	ptr = (uint8_t *)(fe->extendedAttr) +
-		le32_to_cpu(fe->lengthExtendedAttr);
-
-	if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)))
-		ptr += *offset;
-
-	ext = (struct extent_ad *)ptr;
-
-	*offset = *offset + sizeof(struct extent_ad);
-	return ext;
-}
-#endif
-
 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
 			      int inc)
 {
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 7464305382b5..b80cbd78833c 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -193,9 +193,11 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 static int udf_release_file(struct inode *inode, struct file *filp)
 {
 	if (filp->f_mode & FMODE_WRITE) {
+		mutex_lock(&inode->i_mutex);
 		lock_kernel();
 		udf_discard_prealloc(inode);
 		unlock_kernel();
+		mutex_unlock(&inode->i_mutex);
 	}
 	return 0;
 }
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index e7533f785636..6d24c2c63f93 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -90,19 +90,16 @@ no_delete:
 }
 
 /*
- * If we are going to release inode from memory, we discard preallocation and
- * truncate last inode extent to proper length. We could use drop_inode() but
- * it's called under inode_lock and thus we cannot mark inode dirty there.  We
- * use clear_inode() but we have to make sure to write inode as it's not written
- * automatically.
+ * If we are going to release inode from memory, we truncate last inode extent
+ * to proper length. We could use drop_inode() but it's called under inode_lock
+ * and thus we cannot mark inode dirty there.  We use clear_inode() but we have
+ * to make sure to write inode as it's not written automatically.
  */
 void udf_clear_inode(struct inode *inode)
 {
 	struct udf_inode_info *iinfo;
 	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
 		lock_kernel();
-		/* Discard preallocation for directories, symlinks, etc. */
-		udf_discard_prealloc(inode);
 		udf_truncate_tail_extent(inode);
 		unlock_kernel();
 		write_inode_now(inode, 0);
@@ -664,8 +661,12 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
 	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
 
 #ifdef UDF_PREALLOCATE
-	/* preallocate blocks */
-	udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
+	/* We preallocate blocks only for regular files. It also makes sense
+	 * for directories but there's a problem when to drop the
+	 * preallocation. We might use some delayed work for that but I feel
+	 * it's overengineering for a filesystem like UDF. */
+	if (S_ISREG(inode->i_mode))
+		udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
 #endif
 
 	/* merge any continuous blocks in laarr */
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c
index 1b88fd5df05d..43e24a3b8e10 100644
--- a/fs/udf/lowlevel.c
+++ b/fs/udf/lowlevel.c
@@ -36,14 +36,10 @@ unsigned int udf_get_last_session(struct super_block *sb)
 	ms_info.addr_format = CDROM_LBA;
 	i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
 
-#define WE_OBEY_THE_WRITTEN_STANDARDS 1
-
 	if (i == 0) {
 		udf_debug("XA disk: %s, vol_desc_start=%d\n",
 			  (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
-#if WE_OBEY_THE_WRITTEN_STANDARDS
 		if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
-#endif
 			vol_desc_start = ms_info.addr.lba;
 	} else {
 		udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 6a29fa34c478..21dad8c608f9 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -943,7 +943,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
 		pc->componentType = 1;
 		pc->lengthComponentIdent = 0;
 		pc->componentFileVersionNum = 0;
-		pc += sizeof(struct pathComponent);
 		elen += sizeof(struct pathComponent);
 	}