diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:35:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:35:07 -0400 |
commit | 041d6d0be82bed7e0b87181dba5d10b8ab14afd9 (patch) | |
tree | b7af53fa7ca104d30b9759c1f951439af7df3734 /fs | |
parent | af8cb8aa38296ecc43aca7fae9e574db7b8ae0c4 (diff) | |
parent | cbc8cc33529b0e0e55ae0ff077b8cb0b71d54c7a (diff) |
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.c | 86 | ||||
-rw-r--r-- | fs/udf/file.c | 2 | ||||
-rw-r--r-- | fs/udf/inode.c | 19 | ||||
-rw-r--r-- | fs/udf/lowlevel.c | 4 | ||||
-rw-r--r-- | fs/udf/namei.c | 1 |
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 @@ | |||
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | 20 | ||
21 | #if 0 | ||
22 | static uint8_t *udf_filead_read(struct inode *dir, uint8_t *tmpad, | ||
23 | uint8_t ad_size, struct kernel_lb_addr fe_loc, | ||
24 | int *pos, int *offset, struct buffer_head **bh, | ||
25 | int *error) | ||
26 | { | ||
27 | int loffset = *offset; | ||
28 | int block; | ||
29 | uint8_t *ad; | ||
30 | int remainder; | ||
31 | |||
32 | *error = 0; | ||
33 | |||
34 | ad = (uint8_t *)(*bh)->b_data + *offset; | ||
35 | *offset += ad_size; | ||
36 | |||
37 | if (!ad) { | ||
38 | brelse(*bh); | ||
39 | *error = 1; | ||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | if (*offset == dir->i_sb->s_blocksize) { | ||
44 | brelse(*bh); | ||
45 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); | ||
46 | if (!block) | ||
47 | return NULL; | ||
48 | *bh = udf_tread(dir->i_sb, block); | ||
49 | if (!*bh) | ||
50 | return NULL; | ||
51 | } else if (*offset > dir->i_sb->s_blocksize) { | ||
52 | ad = tmpad; | ||
53 | |||
54 | remainder = dir->i_sb->s_blocksize - loffset; | ||
55 | memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder); | ||
56 | |||
57 | brelse(*bh); | ||
58 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); | ||
59 | if (!block) | ||
60 | return NULL; | ||
61 | (*bh) = udf_tread(dir->i_sb, block); | ||
62 | if (!*bh) | ||
63 | return NULL; | ||
64 | |||
65 | memcpy((uint8_t *)ad + remainder, (*bh)->b_data, | ||
66 | ad_size - remainder); | ||
67 | *offset = ad_size - remainder; | ||
68 | } | ||
69 | |||
70 | return ad; | ||
71 | } | ||
72 | #endif | ||
73 | |||
74 | struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, | 21 | struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, |
75 | struct udf_fileident_bh *fibh, | 22 | struct udf_fileident_bh *fibh, |
76 | struct fileIdentDesc *cfi, | 23 | struct fileIdentDesc *cfi, |
@@ -248,39 +195,6 @@ struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset) | |||
248 | return fi; | 195 | return fi; |
249 | } | 196 | } |
250 | 197 | ||
251 | #if 0 | ||
252 | static struct extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset) | ||
253 | { | ||
254 | struct extent_ad *ext; | ||
255 | struct fileEntry *fe; | ||
256 | uint8_t *ptr; | ||
257 | |||
258 | if ((!buffer) || (!offset)) { | ||
259 | printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n"); | ||
260 | return NULL; | ||
261 | } | ||
262 | |||
263 | fe = (struct fileEntry *)buffer; | ||
264 | |||
265 | if (fe->descTag.tagIdent != cpu_to_le16(TAG_IDENT_FE)) { | ||
266 | udf_debug("0x%x != TAG_IDENT_FE\n", | ||
267 | le16_to_cpu(fe->descTag.tagIdent)); | ||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | ptr = (uint8_t *)(fe->extendedAttr) + | ||
272 | le32_to_cpu(fe->lengthExtendedAttr); | ||
273 | |||
274 | if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs))) | ||
275 | ptr += *offset; | ||
276 | |||
277 | ext = (struct extent_ad *)ptr; | ||
278 | |||
279 | *offset = *offset + sizeof(struct extent_ad); | ||
280 | return ext; | ||
281 | } | ||
282 | #endif | ||
283 | |||
284 | struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, | 198 | struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, |
285 | int inc) | 199 | int inc) |
286 | { | 200 | { |
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, | |||
193 | static int udf_release_file(struct inode *inode, struct file *filp) | 193 | static int udf_release_file(struct inode *inode, struct file *filp) |
194 | { | 194 | { |
195 | if (filp->f_mode & FMODE_WRITE) { | 195 | if (filp->f_mode & FMODE_WRITE) { |
196 | mutex_lock(&inode->i_mutex); | ||
196 | lock_kernel(); | 197 | lock_kernel(); |
197 | udf_discard_prealloc(inode); | 198 | udf_discard_prealloc(inode); |
198 | unlock_kernel(); | 199 | unlock_kernel(); |
200 | mutex_unlock(&inode->i_mutex); | ||
199 | } | 201 | } |
200 | return 0; | 202 | return 0; |
201 | } | 203 | } |
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: | |||
90 | } | 90 | } |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * If we are going to release inode from memory, we discard preallocation and | 93 | * If we are going to release inode from memory, we truncate last inode extent |
94 | * truncate last inode extent to proper length. We could use drop_inode() but | 94 | * to proper length. We could use drop_inode() but it's called under inode_lock |
95 | * it's called under inode_lock and thus we cannot mark inode dirty there. We | 95 | * and thus we cannot mark inode dirty there. We use clear_inode() but we have |
96 | * use clear_inode() but we have to make sure to write inode as it's not written | 96 | * to make sure to write inode as it's not written automatically. |
97 | * automatically. | ||
98 | */ | 97 | */ |
99 | void udf_clear_inode(struct inode *inode) | 98 | void udf_clear_inode(struct inode *inode) |
100 | { | 99 | { |
101 | struct udf_inode_info *iinfo; | 100 | struct udf_inode_info *iinfo; |
102 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { | 101 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { |
103 | lock_kernel(); | 102 | lock_kernel(); |
104 | /* Discard preallocation for directories, symlinks, etc. */ | ||
105 | udf_discard_prealloc(inode); | ||
106 | udf_truncate_tail_extent(inode); | 103 | udf_truncate_tail_extent(inode); |
107 | unlock_kernel(); | 104 | unlock_kernel(); |
108 | write_inode_now(inode, 0); | 105 | write_inode_now(inode, 0); |
@@ -664,8 +661,12 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, | |||
664 | udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum); | 661 | udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum); |
665 | 662 | ||
666 | #ifdef UDF_PREALLOCATE | 663 | #ifdef UDF_PREALLOCATE |
667 | /* preallocate blocks */ | 664 | /* We preallocate blocks only for regular files. It also makes sense |
668 | udf_prealloc_extents(inode, c, lastblock, laarr, &endnum); | 665 | * for directories but there's a problem when to drop the |
666 | * preallocation. We might use some delayed work for that but I feel | ||
667 | * it's overengineering for a filesystem like UDF. */ | ||
668 | if (S_ISREG(inode->i_mode)) | ||
669 | udf_prealloc_extents(inode, c, lastblock, laarr, &endnum); | ||
669 | #endif | 670 | #endif |
670 | 671 | ||
671 | /* merge any continuous blocks in laarr */ | 672 | /* 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) | |||
36 | ms_info.addr_format = CDROM_LBA; | 36 | ms_info.addr_format = CDROM_LBA; |
37 | i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info); | 37 | i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info); |
38 | 38 | ||
39 | #define WE_OBEY_THE_WRITTEN_STANDARDS 1 | ||
40 | |||
41 | if (i == 0) { | 39 | if (i == 0) { |
42 | udf_debug("XA disk: %s, vol_desc_start=%d\n", | 40 | udf_debug("XA disk: %s, vol_desc_start=%d\n", |
43 | (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba); | 41 | (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba); |
44 | #if WE_OBEY_THE_WRITTEN_STANDARDS | ||
45 | if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ | 42 | if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ |
46 | #endif | ||
47 | vol_desc_start = ms_info.addr.lba; | 43 | vol_desc_start = ms_info.addr.lba; |
48 | } else { | 44 | } else { |
49 | udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); | 45 | 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, | |||
943 | pc->componentType = 1; | 943 | pc->componentType = 1; |
944 | pc->lengthComponentIdent = 0; | 944 | pc->lengthComponentIdent = 0; |
945 | pc->componentFileVersionNum = 0; | 945 | pc->componentFileVersionNum = 0; |
946 | pc += sizeof(struct pathComponent); | ||
947 | elen += sizeof(struct pathComponent); | 946 | elen += sizeof(struct pathComponent); |
948 | } | 947 | } |
949 | 948 | ||