aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/conv.c28
-rw-r--r--fs/9p/mux.c15
-rw-r--r--fs/9p/vfs_inode.c6
-rw-r--r--fs/buffer.c4
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/direct-io.c9
-rw-r--r--fs/ext2/acl.c2
-rw-r--r--fs/ext2/ialloc.c2
-rw-r--r--fs/ext2/super.c5
-rw-r--r--fs/ext3/acl.c2
-rw-r--r--fs/fat/file.c50
-rw-r--r--fs/fat/misc.c14
-rw-r--r--fs/fcntl.c7
-rw-r--r--fs/jffs/intrep.c2
-rw-r--r--fs/libfs.c1
-rw-r--r--fs/proc/proc_misc.c2
-rw-r--r--fs/quota_v2.c2
-rw-r--r--fs/reiserfs/super.c2
-rw-r--r--fs/udf/balloc.c7
-rw-r--r--fs/udf/namei.c4
-rw-r--r--fs/ufs/inode.c2
-rw-r--r--fs/ufs/super.c10
-rw-r--r--fs/ufs/truncate.c72
23 files changed, 116 insertions, 134 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 32a9f99154e2..bf1f10067960 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -116,13 +116,19 @@ static void buf_put_int64(struct cbuf *buf, u64 val)
116 } 116 }
117} 117}
118 118
119static void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) 119static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
120{ 120{
121 char *ret;
122
123 ret = NULL;
121 if (buf_check_size(buf, slen + 2)) { 124 if (buf_check_size(buf, slen + 2)) {
122 buf_put_int16(buf, slen); 125 buf_put_int16(buf, slen);
126 ret = buf->p;
123 memcpy(buf->p, s, slen); 127 memcpy(buf->p, s, slen);
124 buf->p += slen; 128 buf->p += slen;
125 } 129 }
130
131 return ret;
126} 132}
127 133
128static inline void buf_put_string(struct cbuf *buf, const char *s) 134static inline void buf_put_string(struct cbuf *buf, const char *s)
@@ -430,15 +436,19 @@ static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p)
430static void 436static void
431v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) 437v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str)
432{ 438{
433 if (data) { 439 int len;
434 str->len = strlen(data); 440 char *s;
435 str->str = bufp->p; 441
436 } else { 442 if (data)
437 str->len = 0; 443 len = strlen(data);
438 str->str = NULL; 444 else
439 } 445 len = 0;
440 446
441 buf_put_stringn(bufp, data, str->len); 447 s = buf_put_stringn(bufp, data, len);
448 if (str) {
449 str->len = len;
450 str->str = s;
451 }
442} 452}
443 453
444static int 454static int
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index 945cb368d451..ea1134eb47c8 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -471,10 +471,13 @@ static void v9fs_write_work(void *a)
471 } 471 }
472 472
473 spin_lock(&m->lock); 473 spin_lock(&m->lock);
474 req = 474again:
475 list_entry(m->unsent_req_list.next, struct v9fs_req, 475 req = list_entry(m->unsent_req_list.next, struct v9fs_req,
476 req_list); 476 req_list);
477 list_move_tail(&req->req_list, &m->req_list); 477 list_move_tail(&req->req_list, &m->req_list);
478 if (req->err == ERREQFLUSH)
479 goto again;
480
478 m->wbuf = req->tcall->sdata; 481 m->wbuf = req->tcall->sdata;
479 m->wsize = req->tcall->size; 482 m->wsize = req->tcall->size;
480 m->wpos = 0; 483 m->wpos = 0;
@@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
525 struct v9fs_str *ename; 528 struct v9fs_str *ename;
526 529
527 tag = req->tag; 530 tag = req->tag;
528 if (req->rcall->id == RERROR && !req->err) { 531 if (!req->err && req->rcall->id == RERROR) {
529 ecode = req->rcall->params.rerror.errno; 532 ecode = req->rcall->params.rerror.errno;
530 ename = &req->rcall->params.rerror.error; 533 ename = &req->rcall->params.rerror.error;
531 534
@@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
551 req->err = -EIO; 554 req->err = -EIO;
552 } 555 }
553 556
554 if (req->cb && req->err != ERREQFLUSH) { 557 if (req->err == ERREQFLUSH)
558 return;
559
560 if (req->cb) {
555 dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n", 561 dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n",
556 req->tcall, req->rcall); 562 req->tcall, req->rcall);
557 563
@@ -812,6 +818,7 @@ v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err)
812 struct v9fs_mux_rpc *r; 818 struct v9fs_mux_rpc *r;
813 819
814 if (err == ERREQFLUSH) { 820 if (err == ERREQFLUSH) {
821 kfree(rc);
815 dprintk(DEBUG_MUX, "err req flush\n"); 822 dprintk(DEBUG_MUX, "err req flush\n");
816 return; 823 return;
817 } 824 }
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 91f552454c76..63e5b0398e8b 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -886,8 +886,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
886 } 886 }
887 887
888 /* copy extension buffer into buffer */ 888 /* copy extension buffer into buffer */
889 if (fcall->params.rstat.stat.extension.len < buflen) 889 if (fcall->params.rstat.stat.extension.len+1 < buflen)
890 buflen = fcall->params.rstat.stat.extension.len; 890 buflen = fcall->params.rstat.stat.extension.len + 1;
891 891
892 memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); 892 memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1);
893 buffer[buflen-1] = 0; 893 buffer[buflen-1] = 0;
@@ -951,7 +951,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
951 if (!link) 951 if (!link)
952 link = ERR_PTR(-ENOMEM); 952 link = ERR_PTR(-ENOMEM);
953 else { 953 else {
954 len = v9fs_readlink(dentry, link, strlen(link)); 954 len = v9fs_readlink(dentry, link, PATH_MAX);
955 955
956 if (len < 0) { 956 if (len < 0) {
957 __putname(link); 957 __putname(link);
diff --git a/fs/buffer.c b/fs/buffer.c
index 5e4a90ee103f..62cfd17dc5fe 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2867,22 +2867,22 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
2867 else if (test_set_buffer_locked(bh)) 2867 else if (test_set_buffer_locked(bh))
2868 continue; 2868 continue;
2869 2869
2870 get_bh(bh);
2871 if (rw == WRITE || rw == SWRITE) { 2870 if (rw == WRITE || rw == SWRITE) {
2872 if (test_clear_buffer_dirty(bh)) { 2871 if (test_clear_buffer_dirty(bh)) {
2873 bh->b_end_io = end_buffer_write_sync; 2872 bh->b_end_io = end_buffer_write_sync;
2873 get_bh(bh);
2874 submit_bh(WRITE, bh); 2874 submit_bh(WRITE, bh);
2875 continue; 2875 continue;
2876 } 2876 }
2877 } else { 2877 } else {
2878 if (!buffer_uptodate(bh)) { 2878 if (!buffer_uptodate(bh)) {
2879 bh->b_end_io = end_buffer_read_sync; 2879 bh->b_end_io = end_buffer_read_sync;
2880 get_bh(bh);
2880 submit_bh(rw, bh); 2881 submit_bh(rw, bh);
2881 continue; 2882 continue;
2882 } 2883 }
2883 } 2884 }
2884 unlock_buffer(bh); 2885 unlock_buffer(bh);
2885 put_bh(bh);
2886 } 2886 }
2887} 2887}
2888 2888
diff --git a/fs/dcache.c b/fs/dcache.c
index 86bdb93789c6..a173bba32666 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -743,7 +743,9 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
743 dentry->d_op = NULL; 743 dentry->d_op = NULL;
744 dentry->d_fsdata = NULL; 744 dentry->d_fsdata = NULL;
745 dentry->d_mounted = 0; 745 dentry->d_mounted = 0;
746#ifdef CONFIG_PROFILING
746 dentry->d_cookie = NULL; 747 dentry->d_cookie = NULL;
748#endif
747 INIT_HLIST_NODE(&dentry->d_hash); 749 INIT_HLIST_NODE(&dentry->d_hash);
748 INIT_LIST_HEAD(&dentry->d_lru); 750 INIT_LIST_HEAD(&dentry->d_lru);
749 INIT_LIST_HEAD(&dentry->d_subdirs); 751 INIT_LIST_HEAD(&dentry->d_subdirs);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 30dbbd1df511..848044af7e16 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -857,6 +857,7 @@ do_holes:
857 /* Handle holes */ 857 /* Handle holes */
858 if (!buffer_mapped(map_bh)) { 858 if (!buffer_mapped(map_bh)) {
859 char *kaddr; 859 char *kaddr;
860 loff_t i_size_aligned;
860 861
861 /* AKPM: eargh, -ENOTBLK is a hack */ 862 /* AKPM: eargh, -ENOTBLK is a hack */
862 if (dio->rw == WRITE) { 863 if (dio->rw == WRITE) {
@@ -864,8 +865,14 @@ do_holes:
864 return -ENOTBLK; 865 return -ENOTBLK;
865 } 866 }
866 867
868 /*
869 * Be sure to account for a partial block as the
870 * last block in the file
871 */
872 i_size_aligned = ALIGN(i_size_read(dio->inode),
873 1 << blkbits);
867 if (dio->block_in_file >= 874 if (dio->block_in_file >=
868 i_size_read(dio->inode)>>blkbits) { 875 i_size_aligned >> blkbits) {
869 /* We hit eof */ 876 /* We hit eof */
870 page_cache_release(page); 877 page_cache_release(page);
871 goto out; 878 goto out;
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 35acc43b897f..da52b4a5db64 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -220,7 +220,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
220 struct ext2_inode_info *ei = EXT2_I(inode); 220 struct ext2_inode_info *ei = EXT2_I(inode);
221 int name_index; 221 int name_index;
222 void *value = NULL; 222 void *value = NULL;
223 size_t size; 223 size_t size = 0;
224 int error; 224 int error;
225 225
226 if (S_ISLNK(inode->i_mode)) 226 if (S_ISLNK(inode->i_mode))
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 74714af4ae69..e52765219e16 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -605,7 +605,7 @@ got:
605 insert_inode_hash(inode); 605 insert_inode_hash(inode);
606 606
607 if (DQUOT_ALLOC_INODE(inode)) { 607 if (DQUOT_ALLOC_INODE(inode)) {
608 err = -ENOSPC; 608 err = -EDQUOT;
609 goto fail_drop; 609 goto fail_drop;
610 } 610 }
611 611
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 8d6819846fc9..cb6f9bd658de 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -221,6 +221,11 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
221 seq_puts(seq, ",grpquota"); 221 seq_puts(seq, ",grpquota");
222#endif 222#endif
223 223
224#if defined(CONFIG_EXT2_FS_XIP)
225 if (sbi->s_mount_opt & EXT2_MOUNT_XIP)
226 seq_puts(seq, ",xip");
227#endif
228
224 return 0; 229 return 0;
225} 230}
226 231
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 47a9da2dfb4f..0d21d558b87a 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -226,7 +226,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
226 struct ext3_inode_info *ei = EXT3_I(inode); 226 struct ext3_inode_info *ei = EXT3_I(inode);
227 int name_index; 227 int name_index;
228 void *value = NULL; 228 void *value = NULL;
229 size_t size; 229 size_t size = 0;
230 int error; 230 int error;
231 231
232 if (S_ISLNK(inode->i_mode)) 232 if (S_ISLNK(inode->i_mode))
diff --git a/fs/fat/file.c b/fs/fat/file.c
index e99c5a73b39e..88aa1ae13f9f 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip)
210 if (MSDOS_I(inode)->i_start == 0) 210 if (MSDOS_I(inode)->i_start == 0)
211 return 0; 211 return 0;
212 212
213 /* 213 fat_cache_inval_inode(inode);
214 * Write a new EOF, and get the remaining cluster chain for freeing. 214
215 */
216 wait = IS_DIRSYNC(inode); 215 wait = IS_DIRSYNC(inode);
216 i_start = free_start = MSDOS_I(inode)->i_start;
217 i_logstart = MSDOS_I(inode)->i_logstart;
218
219 /* First, we write the new file size. */
220 if (!skip) {
221 MSDOS_I(inode)->i_start = 0;
222 MSDOS_I(inode)->i_logstart = 0;
223 }
224 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
225 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
226 if (wait) {
227 err = fat_sync_inode(inode);
228 if (err) {
229 MSDOS_I(inode)->i_start = i_start;
230 MSDOS_I(inode)->i_logstart = i_logstart;
231 return err;
232 }
233 } else
234 mark_inode_dirty(inode);
235
236 /* Write a new EOF, and get the remaining cluster chain for freeing. */
217 if (skip) { 237 if (skip) {
218 struct fat_entry fatent; 238 struct fat_entry fatent;
219 int ret, fclus, dclus; 239 int ret, fclus, dclus;
@@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip)
244 return ret; 264 return ret;
245 265
246 free_start = ret; 266 free_start = ret;
247 i_start = i_logstart = 0;
248 fat_cache_inval_inode(inode);
249 } else {
250 fat_cache_inval_inode(inode);
251
252 i_start = free_start = MSDOS_I(inode)->i_start;
253 i_logstart = MSDOS_I(inode)->i_logstart;
254 MSDOS_I(inode)->i_start = 0;
255 MSDOS_I(inode)->i_logstart = 0;
256 } 267 }
257 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
258 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
259 if (wait) {
260 err = fat_sync_inode(inode);
261 if (err)
262 goto error;
263 } else
264 mark_inode_dirty(inode);
265 inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); 268 inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
266 269
267 /* Freeing the remained cluster chain */ 270 /* Freeing the remained cluster chain */
268 return fat_free_clusters(inode, free_start); 271 return fat_free_clusters(inode, free_start);
269
270error:
271 if (i_start) {
272 MSDOS_I(inode)->i_start = i_start;
273 MSDOS_I(inode)->i_logstart = i_logstart;
274 }
275 return err;
276} 272}
277 273
278void fat_truncate(struct inode *inode) 274void fat_truncate(struct inode *inode)
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 32fb0a3f1da4..944652e9dde1 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -196,19 +196,9 @@ EXPORT_SYMBOL_GPL(fat_date_unix2dos);
196 196
197int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) 197int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
198{ 198{
199 int i, e, err = 0; 199 int i, err = 0;
200 200
201 for (i = 0; i < nr_bhs; i++) { 201 ll_rw_block(SWRITE, nr_bhs, bhs);
202 lock_buffer(bhs[i]);
203 if (test_clear_buffer_dirty(bhs[i])) {
204 get_bh(bhs[i]);
205 bhs[i]->b_end_io = end_buffer_write_sync;
206 e = submit_bh(WRITE, bhs[i]);
207 if (!err && e)
208 err = e;
209 } else
210 unlock_buffer(bhs[i]);
211 }
212 for (i = 0; i < nr_bhs; i++) { 202 for (i = 0; i < nr_bhs; i++) {
213 wait_on_buffer(bhs[i]); 203 wait_on_buffer(bhs[i]);
214 if (buffer_eopnotsupp(bhs[i])) { 204 if (buffer_eopnotsupp(bhs[i])) {
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 5f96786d1c73..dc4a7007f4e7 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -208,8 +208,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
208 struct inode * inode = filp->f_dentry->d_inode; 208 struct inode * inode = filp->f_dentry->d_inode;
209 int error = 0; 209 int error = 0;
210 210
211 /* O_APPEND cannot be cleared if the file is marked as append-only */ 211 /*
212 if (!(arg & O_APPEND) && IS_APPEND(inode)) 212 * O_APPEND cannot be cleared if the file is marked as append-only
213 * and the file is open for write.
214 */
215 if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
213 return -EPERM; 216 return -EPERM;
214 217
215 /* O_NOATIME can only be set by the owner or superuser */ 218 /* O_NOATIME can only be set by the owner or superuser */
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index b2e95421d932..ce7b54b0b2b7 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -1965,7 +1965,7 @@ retry:
1965 iovec_cnt++; 1965 iovec_cnt++;
1966 1966
1967 if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) { 1967 if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) {
1968 static char allff[3]={255,255,255}; 1968 static unsigned char allff[3]={255,255,255};
1969 /* Add some extra padding if necessary */ 1969 /* Add some extra padding if necessary */
1970 node_iovec[iovec_cnt].iov_base = allff; 1970 node_iovec[iovec_cnt].iov_base = allff;
1971 node_iovec[iovec_cnt].iov_len = 1971 node_iovec[iovec_cnt].iov_len =
diff --git a/fs/libfs.c b/fs/libfs.c
index 63c020e6589e..71fd08fa4103 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -388,6 +388,7 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
388 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 388 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
389 inode->i_op = &simple_dir_inode_operations; 389 inode->i_op = &simple_dir_inode_operations;
390 inode->i_fop = &simple_dir_operations; 390 inode->i_fop = &simple_dir_operations;
391 inode->i_nlink = 2;
391 root = d_alloc_root(inode); 392 root = d_alloc_root(inode);
392 if (!root) { 393 if (!root) {
393 iput(inode); 394 iput(inode);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 8f8014285a34..1d24fead51a6 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -548,7 +548,7 @@ static int show_stat(struct seq_file *p, void *v)
548 } 548 }
549 seq_printf(p, "intr %llu", (unsigned long long)sum); 549 seq_printf(p, "intr %llu", (unsigned long long)sum);
550 550
551#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) 551#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
552 for (i = 0; i < NR_IRQS; i++) 552 for (i = 0; i < NR_IRQS; i++)
553 seq_printf(p, " %u", kstat_irqs(i)); 553 seq_printf(p, " %u", kstat_irqs(i));
554#endif 554#endif
diff --git a/fs/quota_v2.c b/fs/quota_v2.c
index a4ef91bb4f3b..b4199ec3ece4 100644
--- a/fs/quota_v2.c
+++ b/fs/quota_v2.c
@@ -35,7 +35,7 @@ static int v2_check_quota_file(struct super_block *sb, int type)
35 35
36 size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); 36 size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
37 if (size != sizeof(struct v2_disk_dqheader)) { 37 if (size != sizeof(struct v2_disk_dqheader)) {
38 printk("quota_v2: failed read expected=%d got=%d\n", 38 printk("quota_v2: failed read expected=%zd got=%zd\n",
39 sizeof(struct v2_disk_dqheader), size); 39 sizeof(struct v2_disk_dqheader), size);
40 return 0; 40 return 0;
41 } 41 }
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 77891de0e02e..ef5e5414e7a8 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1125,7 +1125,7 @@ static void handle_attrs(struct super_block *s)
1125 REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); 1125 REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
1126 } 1126 }
1127 } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) { 1127 } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) {
1128 REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS; 1128 REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ATTRS);
1129 } 1129 }
1130} 1130}
1131 1131
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 4fae57d9d115..201049ac8a96 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -579,10 +579,9 @@ static void udf_table_free_blocks(struct super_block * sb,
579 { 579 {
580 loffset = nextoffset; 580 loffset = nextoffset;
581 aed->lengthAllocDescs = cpu_to_le32(adsize); 581 aed->lengthAllocDescs = cpu_to_le32(adsize);
582 if (obh) 582 sptr = UDF_I_DATA(inode) + nextoffset -
583 sptr = UDF_I_DATA(inode) + nextoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode) - adsize; 583 udf_file_entry_alloc_offset(inode) +
584 else 584 UDF_I_LENEATTR(inode) - adsize;
585 sptr = obh->b_data + nextoffset - adsize;
586 dptr = nbh->b_data + sizeof(struct allocExtDesc); 585 dptr = nbh->b_data + sizeof(struct allocExtDesc);
587 memcpy(dptr, sptr, adsize); 586 memcpy(dptr, sptr, adsize);
588 nextoffset = sizeof(struct allocExtDesc) + adsize; 587 nextoffset = sizeof(struct allocExtDesc) + adsize;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index ca732e79c48b..ab9a7629d23e 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -296,7 +296,7 @@ static struct dentry *
296udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 296udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
297{ 297{
298 struct inode *inode = NULL; 298 struct inode *inode = NULL;
299 struct fileIdentDesc cfi, *fi; 299 struct fileIdentDesc cfi;
300 struct udf_fileident_bh fibh; 300 struct udf_fileident_bh fibh;
301 301
302 if (dentry->d_name.len > UDF_NAME_LEN-2) 302 if (dentry->d_name.len > UDF_NAME_LEN-2)
@@ -318,7 +318,7 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
318 else 318 else
319#endif /* UDF_RECOVERY */ 319#endif /* UDF_RECOVERY */
320 320
321 if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi))) 321 if (udf_find_entry(dir, dentry, &fibh, &cfi))
322 { 322 {
323 if (fibh.sbh != fibh.ebh) 323 if (fibh.sbh != fibh.ebh)
324 udf_release_data(fibh.ebh); 324 udf_release_data(fibh.ebh);
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index e0c04e36a051..3c3f62ce2ad9 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -376,7 +376,7 @@ out:
376 * This function gets the block which contains the fragment. 376 * This function gets the block which contains the fragment.
377 */ 377 */
378 378
379static int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) 379int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
380{ 380{
381 struct super_block * sb = inode->i_sb; 381 struct super_block * sb = inode->i_sb;
382 struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; 382 struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index d4aacee593ff..e9055ef7f5ac 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -388,7 +388,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
388/* 388/*
389 * Read on-disk structures associated with cylinder groups 389 * Read on-disk structures associated with cylinder groups
390 */ 390 */
391static int ufs_read_cylinder_structures (struct super_block *sb) { 391static int ufs_read_cylinder_structures (struct super_block *sb)
392{
392 struct ufs_sb_info * sbi = UFS_SB(sb); 393 struct ufs_sb_info * sbi = UFS_SB(sb);
393 struct ufs_sb_private_info * uspi; 394 struct ufs_sb_private_info * uspi;
394 struct ufs_super_block *usb; 395 struct ufs_super_block *usb;
@@ -415,6 +416,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
415 base = space = kmalloc(size, GFP_KERNEL); 416 base = space = kmalloc(size, GFP_KERNEL);
416 if (!base) 417 if (!base)
417 goto failed; 418 goto failed;
419 sbi->s_csp = (struct ufs_csum *)space;
418 for (i = 0; i < blks; i += uspi->s_fpb) { 420 for (i = 0; i < blks; i += uspi->s_fpb) {
419 size = uspi->s_bsize; 421 size = uspi->s_bsize;
420 if (i + uspi->s_fpb > blks) 422 if (i + uspi->s_fpb > blks)
@@ -430,7 +432,6 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
430 goto failed; 432 goto failed;
431 433
432 ubh_ubhcpymem (space, ubh, size); 434 ubh_ubhcpymem (space, ubh, size);
433 sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space;
434 435
435 space += size; 436 space += size;
436 ubh_brelse (ubh); 437 ubh_brelse (ubh);
@@ -486,7 +487,8 @@ failed:
486 * Put on-disk structures associated with cylinder groups and 487 * Put on-disk structures associated with cylinder groups and
487 * write them back to disk 488 * write them back to disk
488 */ 489 */
489static void ufs_put_cylinder_structures (struct super_block *sb) { 490static void ufs_put_cylinder_structures (struct super_block *sb)
491{
490 struct ufs_sb_info * sbi = UFS_SB(sb); 492 struct ufs_sb_info * sbi = UFS_SB(sb);
491 struct ufs_sb_private_info * uspi; 493 struct ufs_sb_private_info * uspi;
492 struct ufs_buffer_head * ubh; 494 struct ufs_buffer_head * ubh;
@@ -499,7 +501,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) {
499 501
500 size = uspi->s_cssize; 502 size = uspi->s_cssize;
501 blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; 503 blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
502 base = space = (char*) sbi->s_csp[0]; 504 base = space = (char*) sbi->s_csp;
503 for (i = 0; i < blks; i += uspi->s_fpb) { 505 for (i = 0; i < blks; i += uspi->s_fpb) {
504 size = uspi->s_bsize; 506 size = uspi->s_bsize;
505 if (i + uspi->s_fpb > blks) 507 if (i + uspi->s_fpb > blks)
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 61d2e35012a4..02e86291ef8a 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -29,6 +29,11 @@
29 * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr> 29 * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr>
30 */ 30 */
31 31
32/*
33 * Modified to avoid infinite loop on 2006 by
34 * Evgeniy Dushistov <dushistov@mail.ru>
35 */
36
32#include <linux/errno.h> 37#include <linux/errno.h>
33#include <linux/fs.h> 38#include <linux/fs.h>
34#include <linux/ufs_fs.h> 39#include <linux/ufs_fs.h>
@@ -65,19 +70,16 @@
65#define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift) 70#define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift)
66#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) 71#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
67 72
68#define DATA_BUFFER_USED(bh) \
69 (atomic_read(&bh->b_count)>1 || buffer_locked(bh))
70 73
71static int ufs_trunc_direct (struct inode * inode) 74static int ufs_trunc_direct (struct inode * inode)
72{ 75{
73 struct ufs_inode_info *ufsi = UFS_I(inode); 76 struct ufs_inode_info *ufsi = UFS_I(inode);
74 struct super_block * sb; 77 struct super_block * sb;
75 struct ufs_sb_private_info * uspi; 78 struct ufs_sb_private_info * uspi;
76 struct buffer_head * bh;
77 __fs32 * p; 79 __fs32 * p;
78 unsigned frag1, frag2, frag3, frag4, block1, block2; 80 unsigned frag1, frag2, frag3, frag4, block1, block2;
79 unsigned frag_to_free, free_count; 81 unsigned frag_to_free, free_count;
80 unsigned i, j, tmp; 82 unsigned i, tmp;
81 int retry; 83 int retry;
82 84
83 UFSD(("ENTER\n")) 85 UFSD(("ENTER\n"))
@@ -117,15 +119,7 @@ static int ufs_trunc_direct (struct inode * inode)
117 ufs_panic (sb, "ufs_trunc_direct", "internal error"); 119 ufs_panic (sb, "ufs_trunc_direct", "internal error");
118 frag1 = ufs_fragnum (frag1); 120 frag1 = ufs_fragnum (frag1);
119 frag2 = ufs_fragnum (frag2); 121 frag2 = ufs_fragnum (frag2);
120 for (j = frag1; j < frag2; j++) { 122
121 bh = sb_find_get_block (sb, tmp + j);
122 if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
123 retry = 1;
124 brelse (bh);
125 goto next1;
126 }
127 bforget (bh);
128 }
129 inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift; 123 inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift;
130 mark_inode_dirty(inode); 124 mark_inode_dirty(inode);
131 ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); 125 ufs_free_fragments (inode, tmp + frag1, frag2 - frag1);
@@ -140,15 +134,7 @@ next1:
140 tmp = fs32_to_cpu(sb, *p); 134 tmp = fs32_to_cpu(sb, *p);
141 if (!tmp) 135 if (!tmp)
142 continue; 136 continue;
143 for (j = 0; j < uspi->s_fpb; j++) { 137
144 bh = sb_find_get_block(sb, tmp + j);
145 if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
146 retry = 1;
147 brelse (bh);
148 goto next2;
149 }
150 bforget (bh);
151 }
152 *p = 0; 138 *p = 0;
153 inode->i_blocks -= uspi->s_nspb; 139 inode->i_blocks -= uspi->s_nspb;
154 mark_inode_dirty(inode); 140 mark_inode_dirty(inode);
@@ -162,7 +148,6 @@ next1:
162 frag_to_free = tmp; 148 frag_to_free = tmp;
163 free_count = uspi->s_fpb; 149 free_count = uspi->s_fpb;
164 } 150 }
165next2:;
166 } 151 }
167 152
168 if (free_count > 0) 153 if (free_count > 0)
@@ -179,15 +164,7 @@ next2:;
179 if (!tmp ) 164 if (!tmp )
180 ufs_panic(sb, "ufs_truncate_direct", "internal error"); 165 ufs_panic(sb, "ufs_truncate_direct", "internal error");
181 frag4 = ufs_fragnum (frag4); 166 frag4 = ufs_fragnum (frag4);
182 for (j = 0; j < frag4; j++) { 167
183 bh = sb_find_get_block (sb, tmp + j);
184 if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
185 retry = 1;
186 brelse (bh);
187 goto next1;
188 }
189 bforget (bh);
190 }
191 *p = 0; 168 *p = 0;
192 inode->i_blocks -= frag4 << uspi->s_nspfshift; 169 inode->i_blocks -= frag4 << uspi->s_nspfshift;
193 mark_inode_dirty(inode); 170 mark_inode_dirty(inode);
@@ -204,9 +181,8 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
204 struct super_block * sb; 181 struct super_block * sb;
205 struct ufs_sb_private_info * uspi; 182 struct ufs_sb_private_info * uspi;
206 struct ufs_buffer_head * ind_ubh; 183 struct ufs_buffer_head * ind_ubh;
207 struct buffer_head * bh;
208 __fs32 * ind; 184 __fs32 * ind;
209 unsigned indirect_block, i, j, tmp; 185 unsigned indirect_block, i, tmp;
210 unsigned frag_to_free, free_count; 186 unsigned frag_to_free, free_count;
211 int retry; 187 int retry;
212 188
@@ -238,15 +214,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
238 tmp = fs32_to_cpu(sb, *ind); 214 tmp = fs32_to_cpu(sb, *ind);
239 if (!tmp) 215 if (!tmp)
240 continue; 216 continue;
241 for (j = 0; j < uspi->s_fpb; j++) { 217
242 bh = sb_find_get_block(sb, tmp + j);
243 if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *ind)) {
244 retry = 1;
245 brelse (bh);
246 goto next;
247 }
248 bforget (bh);
249 }
250 *ind = 0; 218 *ind = 0;
251 ubh_mark_buffer_dirty(ind_ubh); 219 ubh_mark_buffer_dirty(ind_ubh);
252 if (free_count == 0) { 220 if (free_count == 0) {
@@ -261,7 +229,6 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
261 } 229 }
262 inode->i_blocks -= uspi->s_nspb; 230 inode->i_blocks -= uspi->s_nspb;
263 mark_inode_dirty(inode); 231 mark_inode_dirty(inode);
264next:;
265 } 232 }
266 233
267 if (free_count > 0) { 234 if (free_count > 0) {
@@ -430,9 +397,7 @@ void ufs_truncate (struct inode * inode)
430 struct ufs_inode_info *ufsi = UFS_I(inode); 397 struct ufs_inode_info *ufsi = UFS_I(inode);
431 struct super_block * sb; 398 struct super_block * sb;
432 struct ufs_sb_private_info * uspi; 399 struct ufs_sb_private_info * uspi;
433 struct buffer_head * bh; 400 int retry;
434 unsigned offset;
435 int err, retry;
436 401
437 UFSD(("ENTER\n")) 402 UFSD(("ENTER\n"))
438 sb = inode->i_sb; 403 sb = inode->i_sb;
@@ -442,6 +407,9 @@ void ufs_truncate (struct inode * inode)
442 return; 407 return;
443 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) 408 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
444 return; 409 return;
410
411 block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block);
412
445 lock_kernel(); 413 lock_kernel();
446 while (1) { 414 while (1) {
447 retry = ufs_trunc_direct(inode); 415 retry = ufs_trunc_direct(inode);
@@ -457,15 +425,7 @@ void ufs_truncate (struct inode * inode)
457 blk_run_address_space(inode->i_mapping); 425 blk_run_address_space(inode->i_mapping);
458 yield(); 426 yield();
459 } 427 }
460 offset = inode->i_size & uspi->s_fshift; 428
461 if (offset) {
462 bh = ufs_bread (inode, inode->i_size >> uspi->s_fshift, 0, &err);
463 if (bh) {
464 memset (bh->b_data + offset, 0, uspi->s_fsize - offset);
465 mark_buffer_dirty (bh);
466 brelse (bh);
467 }
468 }
469 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; 429 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
470 ufsi->i_lastfrag = DIRECT_FRAGMENT; 430 ufsi->i_lastfrag = DIRECT_FRAGMENT;
471 unlock_kernel(); 431 unlock_kernel();