diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/Kconfig | 11 | ||||
-rw-r--r-- | fs/autofs4/autofs_i.h | 1 | ||||
-rw-r--r-- | fs/autofs4/inode.c | 73 | ||||
-rw-r--r-- | fs/bio.c | 9 | ||||
-rw-r--r-- | fs/dcache.c | 7 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 1 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 2 | ||||
-rw-r--r-- | fs/ext2/xip.c | 2 | ||||
-rw-r--r-- | fs/ext3/ialloc.c | 2 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 2 | ||||
-rw-r--r-- | fs/fcntl.c | 5 | ||||
-rw-r--r-- | fs/hfs/bnode.c | 2 | ||||
-rw-r--r-- | fs/hfs/extent.c | 3 | ||||
-rw-r--r-- | fs/hfsplus/bnode.c | 2 | ||||
-rw-r--r-- | fs/hfsplus/extents.c | 4 | ||||
-rw-r--r-- | fs/hostfs/hostfs.h | 1 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 2 | ||||
-rw-r--r-- | fs/hostfs/hostfs_user.c | 16 | ||||
-rw-r--r-- | fs/inotify.c | 5 | ||||
-rw-r--r-- | fs/isofs/compress.c | 6 | ||||
-rw-r--r-- | fs/jffs/intrep.c | 3 | ||||
-rw-r--r-- | fs/jfs/jfs_dmap.c | 46 | ||||
-rw-r--r-- | fs/jfs/jfs_dtree.c | 13 | ||||
-rw-r--r-- | fs/jfs/jfs_logmgr.c | 3 | ||||
-rw-r--r-- | fs/jfs/jfs_metapage.c | 11 | ||||
-rw-r--r-- | fs/locks.c | 81 | ||||
-rw-r--r-- | fs/mbcache.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 4 | ||||
-rw-r--r-- | fs/namespace.c | 2 | ||||
-rw-r--r-- | fs/ntfs/sysctl.h | 2 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 12 | ||||
-rw-r--r-- | fs/reiserfs/journal.c | 4 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 1 | ||||
-rw-r--r-- | fs/sysfs/file.c | 18 | ||||
-rw-r--r-- | fs/sysfs/inode.c | 2 |
35 files changed, 257 insertions, 104 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 5d0c4be43dba..e54be7058359 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -363,12 +363,15 @@ config INOTIFY | |||
363 | bool "Inotify file change notification support" | 363 | bool "Inotify file change notification support" |
364 | default y | 364 | default y |
365 | ---help--- | 365 | ---help--- |
366 | Say Y here to enable inotify support and the /dev/inotify character | 366 | Say Y here to enable inotify support and the associated system |
367 | device. Inotify is a file change notification system and a | 367 | calls. Inotify is a file change notification system and a |
368 | replacement for dnotify. Inotify fixes numerous shortcomings in | 368 | replacement for dnotify. Inotify fixes numerous shortcomings in |
369 | dnotify and introduces several new features. It allows monitoring | 369 | dnotify and introduces several new features. It allows monitoring |
370 | of both files and directories via a single open fd. Multiple file | 370 | of both files and directories via a single open fd. Other features |
371 | events are supported. | 371 | include multiple file events, one-shot support, and unmount |
372 | notification. | ||
373 | |||
374 | For more information, see Documentation/filesystems/inotify.txt | ||
372 | 375 | ||
373 | If unsure, say Y. | 376 | If unsure, say Y. |
374 | 377 | ||
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 9c09641ce907..fca83e28edcf 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -92,6 +92,7 @@ struct autofs_wait_queue { | |||
92 | 92 | ||
93 | struct autofs_sb_info { | 93 | struct autofs_sb_info { |
94 | u32 magic; | 94 | u32 magic; |
95 | struct dentry *root; | ||
95 | struct file *pipe; | 96 | struct file *pipe; |
96 | pid_t oz_pgrp; | 97 | pid_t oz_pgrp; |
97 | int catatonic; | 98 | int catatonic; |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 4bb14cc68040..0a3c05d10167 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | #include <linux/parser.h> | 17 | #include <linux/parser.h> |
18 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
19 | #include <linux/smp_lock.h> | ||
19 | #include "autofs_i.h" | 20 | #include "autofs_i.h" |
20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
21 | 22 | ||
@@ -76,6 +77,66 @@ void autofs4_free_ino(struct autofs_info *ino) | |||
76 | kfree(ino); | 77 | kfree(ino); |
77 | } | 78 | } |
78 | 79 | ||
80 | /* | ||
81 | * Deal with the infamous "Busy inodes after umount ..." message. | ||
82 | * | ||
83 | * Clean up the dentry tree. This happens with autofs if the user | ||
84 | * space program goes away due to a SIGKILL, SIGSEGV etc. | ||
85 | */ | ||
86 | static void autofs4_force_release(struct autofs_sb_info *sbi) | ||
87 | { | ||
88 | struct dentry *this_parent = sbi->root; | ||
89 | struct list_head *next; | ||
90 | |||
91 | spin_lock(&dcache_lock); | ||
92 | repeat: | ||
93 | next = this_parent->d_subdirs.next; | ||
94 | resume: | ||
95 | while (next != &this_parent->d_subdirs) { | ||
96 | struct dentry *dentry = list_entry(next, struct dentry, d_child); | ||
97 | |||
98 | /* Negative dentry - don`t care */ | ||
99 | if (!simple_positive(dentry)) { | ||
100 | next = next->next; | ||
101 | continue; | ||
102 | } | ||
103 | |||
104 | if (!list_empty(&dentry->d_subdirs)) { | ||
105 | this_parent = dentry; | ||
106 | goto repeat; | ||
107 | } | ||
108 | |||
109 | next = next->next; | ||
110 | spin_unlock(&dcache_lock); | ||
111 | |||
112 | DPRINTK("dentry %p %.*s", | ||
113 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | ||
114 | |||
115 | dput(dentry); | ||
116 | spin_lock(&dcache_lock); | ||
117 | } | ||
118 | |||
119 | if (this_parent != sbi->root) { | ||
120 | struct dentry *dentry = this_parent; | ||
121 | |||
122 | next = this_parent->d_child.next; | ||
123 | this_parent = this_parent->d_parent; | ||
124 | spin_unlock(&dcache_lock); | ||
125 | DPRINTK("parent dentry %p %.*s", | ||
126 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | ||
127 | dput(dentry); | ||
128 | spin_lock(&dcache_lock); | ||
129 | goto resume; | ||
130 | } | ||
131 | spin_unlock(&dcache_lock); | ||
132 | |||
133 | dput(sbi->root); | ||
134 | sbi->root = NULL; | ||
135 | shrink_dcache_sb(sbi->sb); | ||
136 | |||
137 | return; | ||
138 | } | ||
139 | |||
79 | static void autofs4_put_super(struct super_block *sb) | 140 | static void autofs4_put_super(struct super_block *sb) |
80 | { | 141 | { |
81 | struct autofs_sb_info *sbi = autofs4_sbi(sb); | 142 | struct autofs_sb_info *sbi = autofs4_sbi(sb); |
@@ -85,6 +146,10 @@ static void autofs4_put_super(struct super_block *sb) | |||
85 | if ( !sbi->catatonic ) | 146 | if ( !sbi->catatonic ) |
86 | autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */ | 147 | autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */ |
87 | 148 | ||
149 | /* Clean up and release dangling references */ | ||
150 | if (sbi) | ||
151 | autofs4_force_release(sbi); | ||
152 | |||
88 | kfree(sbi); | 153 | kfree(sbi); |
89 | 154 | ||
90 | DPRINTK("shutting down"); | 155 | DPRINTK("shutting down"); |
@@ -199,6 +264,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
199 | 264 | ||
200 | s->s_fs_info = sbi; | 265 | s->s_fs_info = sbi; |
201 | sbi->magic = AUTOFS_SBI_MAGIC; | 266 | sbi->magic = AUTOFS_SBI_MAGIC; |
267 | sbi->root = NULL; | ||
202 | sbi->catatonic = 0; | 268 | sbi->catatonic = 0; |
203 | sbi->exp_timeout = 0; | 269 | sbi->exp_timeout = 0; |
204 | sbi->oz_pgrp = process_group(current); | 270 | sbi->oz_pgrp = process_group(current); |
@@ -267,6 +333,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
267 | sbi->pipe = pipe; | 333 | sbi->pipe = pipe; |
268 | 334 | ||
269 | /* | 335 | /* |
336 | * Take a reference to the root dentry so we get a chance to | ||
337 | * clean up the dentry tree on umount. | ||
338 | * See autofs4_force_release. | ||
339 | */ | ||
340 | sbi->root = dget(root); | ||
341 | |||
342 | /* | ||
270 | * Success! Install the root dentry now to indicate completion. | 343 | * Success! Install the root dentry now to indicate completion. |
271 | */ | 344 | */ |
272 | s->s_root = root; | 345 | s->s_root = root; |
@@ -248,19 +248,16 @@ inline void __bio_clone(struct bio *bio, struct bio *bio_src) | |||
248 | { | 248 | { |
249 | request_queue_t *q = bdev_get_queue(bio_src->bi_bdev); | 249 | request_queue_t *q = bdev_get_queue(bio_src->bi_bdev); |
250 | 250 | ||
251 | memcpy(bio->bi_io_vec, bio_src->bi_io_vec, bio_src->bi_max_vecs * sizeof(struct bio_vec)); | 251 | memcpy(bio->bi_io_vec, bio_src->bi_io_vec, |
252 | bio_src->bi_max_vecs * sizeof(struct bio_vec)); | ||
252 | 253 | ||
253 | bio->bi_sector = bio_src->bi_sector; | 254 | bio->bi_sector = bio_src->bi_sector; |
254 | bio->bi_bdev = bio_src->bi_bdev; | 255 | bio->bi_bdev = bio_src->bi_bdev; |
255 | bio->bi_flags |= 1 << BIO_CLONED; | 256 | bio->bi_flags |= 1 << BIO_CLONED; |
256 | bio->bi_rw = bio_src->bi_rw; | 257 | bio->bi_rw = bio_src->bi_rw; |
257 | |||
258 | /* | ||
259 | * notes -- maybe just leave bi_idx alone. assume identical mapping | ||
260 | * for the clone | ||
261 | */ | ||
262 | bio->bi_vcnt = bio_src->bi_vcnt; | 258 | bio->bi_vcnt = bio_src->bi_vcnt; |
263 | bio->bi_size = bio_src->bi_size; | 259 | bio->bi_size = bio_src->bi_size; |
260 | bio->bi_idx = bio_src->bi_idx; | ||
264 | bio_phys_segments(q, bio); | 261 | bio_phys_segments(q, bio); |
265 | bio_hw_segments(q, bio); | 262 | bio_hw_segments(q, bio); |
266 | } | 263 | } |
diff --git a/fs/dcache.c b/fs/dcache.c index 3aa8a7e980d8..a15a2e1f5520 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/fsnotify.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
@@ -101,6 +102,7 @@ static inline void dentry_iput(struct dentry * dentry) | |||
101 | list_del_init(&dentry->d_alias); | 102 | list_del_init(&dentry->d_alias); |
102 | spin_unlock(&dentry->d_lock); | 103 | spin_unlock(&dentry->d_lock); |
103 | spin_unlock(&dcache_lock); | 104 | spin_unlock(&dcache_lock); |
105 | fsnotify_inoderemove(inode); | ||
104 | if (dentry->d_op && dentry->d_op->d_iput) | 106 | if (dentry->d_op && dentry->d_op->d_iput) |
105 | dentry->d_op->d_iput(dentry, inode); | 107 | dentry->d_op->d_iput(dentry, inode); |
106 | else | 108 | else |
@@ -1165,13 +1167,16 @@ out: | |||
1165 | 1167 | ||
1166 | void d_delete(struct dentry * dentry) | 1168 | void d_delete(struct dentry * dentry) |
1167 | { | 1169 | { |
1170 | int isdir = 0; | ||
1168 | /* | 1171 | /* |
1169 | * Are we the only user? | 1172 | * Are we the only user? |
1170 | */ | 1173 | */ |
1171 | spin_lock(&dcache_lock); | 1174 | spin_lock(&dcache_lock); |
1172 | spin_lock(&dentry->d_lock); | 1175 | spin_lock(&dentry->d_lock); |
1176 | isdir = S_ISDIR(dentry->d_inode->i_mode); | ||
1173 | if (atomic_read(&dentry->d_count) == 1) { | 1177 | if (atomic_read(&dentry->d_count) == 1) { |
1174 | dentry_iput(dentry); | 1178 | dentry_iput(dentry); |
1179 | fsnotify_nameremove(dentry, isdir); | ||
1175 | return; | 1180 | return; |
1176 | } | 1181 | } |
1177 | 1182 | ||
@@ -1180,6 +1185,8 @@ void d_delete(struct dentry * dentry) | |||
1180 | 1185 | ||
1181 | spin_unlock(&dentry->d_lock); | 1186 | spin_unlock(&dentry->d_lock); |
1182 | spin_unlock(&dcache_lock); | 1187 | spin_unlock(&dcache_lock); |
1188 | |||
1189 | fsnotify_nameremove(dentry, isdir); | ||
1183 | } | 1190 | } |
1184 | 1191 | ||
1185 | static void __d_rehash(struct dentry * entry, struct hlist_head *list) | 1192 | static void __d_rehash(struct dentry * entry, struct hlist_head *list) |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 77e059149212..161f156d98c8 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -612,6 +612,7 @@ got: | |||
612 | err = ext2_init_acl(inode, dir); | 612 | err = ext2_init_acl(inode, dir); |
613 | if (err) { | 613 | if (err) { |
614 | DQUOT_FREE_INODE(inode); | 614 | DQUOT_FREE_INODE(inode); |
615 | DQUOT_DROP(inode); | ||
615 | goto fail2; | 616 | goto fail2; |
616 | } | 617 | } |
617 | mark_inode_dirty(inode); | 618 | mark_inode_dirty(inode); |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 27982b500e84..0099462d4271 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -823,7 +823,7 @@ cleanup: | |||
823 | void | 823 | void |
824 | ext2_xattr_put_super(struct super_block *sb) | 824 | ext2_xattr_put_super(struct super_block *sb) |
825 | { | 825 | { |
826 | mb_cache_shrink(ext2_xattr_cache, sb->s_bdev); | 826 | mb_cache_shrink(sb->s_bdev); |
827 | } | 827 | } |
828 | 828 | ||
829 | 829 | ||
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c index 0aa5ac159c09..ca7f00312388 100644 --- a/fs/ext2/xip.c +++ b/fs/ext2/xip.c | |||
@@ -36,7 +36,7 @@ __ext2_get_sector(struct inode *inode, sector_t offset, int create, | |||
36 | *result = tmp.b_blocknr; | 36 | *result = tmp.b_blocknr; |
37 | 37 | ||
38 | /* did we get a sparse block (hole in the file)? */ | 38 | /* did we get a sparse block (hole in the file)? */ |
39 | if (!(*result)) { | 39 | if (!tmp.b_blocknr && !rc) { |
40 | BUG_ON(create); | 40 | BUG_ON(create); |
41 | rc = -ENODATA; | 41 | rc = -ENODATA; |
42 | } | 42 | } |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 1e6f3ea28713..6981bd014ede 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -604,12 +604,14 @@ got: | |||
604 | err = ext3_init_acl(handle, inode, dir); | 604 | err = ext3_init_acl(handle, inode, dir); |
605 | if (err) { | 605 | if (err) { |
606 | DQUOT_FREE_INODE(inode); | 606 | DQUOT_FREE_INODE(inode); |
607 | DQUOT_DROP(inode); | ||
607 | goto fail2; | 608 | goto fail2; |
608 | } | 609 | } |
609 | err = ext3_mark_inode_dirty(handle, inode); | 610 | err = ext3_mark_inode_dirty(handle, inode); |
610 | if (err) { | 611 | if (err) { |
611 | ext3_std_error(sb, err); | 612 | ext3_std_error(sb, err); |
612 | DQUOT_FREE_INODE(inode); | 613 | DQUOT_FREE_INODE(inode); |
614 | DQUOT_DROP(inode); | ||
613 | goto fail2; | 615 | goto fail2; |
614 | } | 616 | } |
615 | 617 | ||
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 3f9dfa643b19..269c7b92db9a 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -1106,7 +1106,7 @@ cleanup: | |||
1106 | void | 1106 | void |
1107 | ext3_xattr_put_super(struct super_block *sb) | 1107 | ext3_xattr_put_super(struct super_block *sb) |
1108 | { | 1108 | { |
1109 | mb_cache_shrink(ext3_xattr_cache, sb->s_bdev); | 1109 | mb_cache_shrink(sb->s_bdev); |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* | 1112 | /* |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 286a9f8f3d49..6fbc9d8fcc36 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -288,7 +288,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | |||
288 | break; | 288 | break; |
289 | case F_SETLK: | 289 | case F_SETLK: |
290 | case F_SETLKW: | 290 | case F_SETLKW: |
291 | err = fcntl_setlk(filp, cmd, (struct flock __user *) arg); | 291 | err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); |
292 | break; | 292 | break; |
293 | case F_GETOWN: | 293 | case F_GETOWN: |
294 | /* | 294 | /* |
@@ -376,7 +376,8 @@ asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg | |||
376 | break; | 376 | break; |
377 | case F_SETLK64: | 377 | case F_SETLK64: |
378 | case F_SETLKW64: | 378 | case F_SETLKW64: |
379 | err = fcntl_setlk64(filp, cmd, (struct flock64 __user *) arg); | 379 | err = fcntl_setlk64(fd, filp, cmd, |
380 | (struct flock64 __user *) arg); | ||
380 | break; | 381 | break; |
381 | default: | 382 | default: |
382 | err = do_fcntl(fd, cmd, arg, filp); | 383 | err = do_fcntl(fd, cmd, arg, filp); |
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index 6ad1211f84ed..a096c5a56664 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c | |||
@@ -480,6 +480,8 @@ void hfs_bnode_put(struct hfs_bnode *node) | |||
480 | return; | 480 | return; |
481 | } | 481 | } |
482 | for (i = 0; i < tree->pages_per_bnode; i++) { | 482 | for (i = 0; i < tree->pages_per_bnode; i++) { |
483 | if (!node->page[i]) | ||
484 | continue; | ||
483 | mark_page_accessed(node->page[i]); | 485 | mark_page_accessed(node->page[i]); |
484 | #if REF_PAGES | 486 | #if REF_PAGES |
485 | put_page(node->page[i]); | 487 | put_page(node->page[i]); |
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index cbc8510ad222..5ea6b3d45eaa 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c | |||
@@ -482,7 +482,8 @@ void hfs_file_truncate(struct inode *inode) | |||
482 | page_cache_release(page); | 482 | page_cache_release(page); |
483 | mark_inode_dirty(inode); | 483 | mark_inode_dirty(inode); |
484 | return; | 484 | return; |
485 | } | 485 | } else if (inode->i_size == HFS_I(inode)->phys_size) |
486 | return; | ||
486 | size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1; | 487 | size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1; |
487 | blk_cnt = size / HFS_SB(sb)->alloc_blksz; | 488 | blk_cnt = size / HFS_SB(sb)->alloc_blksz; |
488 | alloc_cnt = HFS_I(inode)->alloc_blocks; | 489 | alloc_cnt = HFS_I(inode)->alloc_blocks; |
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 267872e84d71..8868d3b766fd 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c | |||
@@ -643,6 +643,8 @@ void hfs_bnode_put(struct hfs_bnode *node) | |||
643 | return; | 643 | return; |
644 | } | 644 | } |
645 | for (i = 0; i < tree->pages_per_bnode; i++) { | 645 | for (i = 0; i < tree->pages_per_bnode; i++) { |
646 | if (!node->page[i]) | ||
647 | continue; | ||
646 | mark_page_accessed(node->page[i]); | 648 | mark_page_accessed(node->page[i]); |
647 | #if REF_PAGES | 649 | #if REF_PAGES |
648 | put_page(node->page[i]); | 650 | put_page(node->page[i]); |
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 376498cc64fd..e7235ca79a95 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
@@ -461,7 +461,9 @@ void hfsplus_file_truncate(struct inode *inode) | |||
461 | page_cache_release(page); | 461 | page_cache_release(page); |
462 | mark_inode_dirty(inode); | 462 | mark_inode_dirty(inode); |
463 | return; | 463 | return; |
464 | } | 464 | } else if (inode->i_size == HFSPLUS_I(inode).phys_size) |
465 | return; | ||
466 | |||
465 | blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift; | 467 | blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift; |
466 | alloc_cnt = HFSPLUS_I(inode).alloc_blocks; | 468 | alloc_cnt = HFSPLUS_I(inode).alloc_blocks; |
467 | if (blk_cnt == alloc_cnt) | 469 | if (blk_cnt == alloc_cnt) |
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h index c1516d013bf6..67bca0d4a33b 100644 --- a/fs/hostfs/hostfs.h +++ b/fs/hostfs/hostfs.h | |||
@@ -69,6 +69,7 @@ extern int read_file(int fd, unsigned long long *offset, char *buf, int len); | |||
69 | extern int write_file(int fd, unsigned long long *offset, const char *buf, | 69 | extern int write_file(int fd, unsigned long long *offset, const char *buf, |
70 | int len); | 70 | int len); |
71 | extern int lseek_file(int fd, long long offset, int whence); | 71 | extern int lseek_file(int fd, long long offset, int whence); |
72 | extern int fsync_file(int fd, int datasync); | ||
72 | extern int file_create(char *name, int ur, int uw, int ux, int gr, | 73 | extern int file_create(char *name, int ur, int uw, int ux, int gr, |
73 | int gw, int gx, int or, int ow, int ox); | 74 | int gw, int gx, int or, int ow, int ox); |
74 | extern int set_attr(const char *file, struct hostfs_iattr *attrs); | 75 | extern int set_attr(const char *file, struct hostfs_iattr *attrs); |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 88e68caa3784..b2d18200a003 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -382,7 +382,7 @@ int hostfs_file_open(struct inode *ino, struct file *file) | |||
382 | 382 | ||
383 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 383 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) |
384 | { | 384 | { |
385 | return(0); | 385 | return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync); |
386 | } | 386 | } |
387 | 387 | ||
388 | static struct file_operations hostfs_file_fops = { | 388 | static struct file_operations hostfs_file_fops = { |
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index 4796e8490f7d..b97809deba66 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c | |||
@@ -153,10 +153,24 @@ int lseek_file(int fd, long long offset, int whence) | |||
153 | int ret; | 153 | int ret; |
154 | 154 | ||
155 | ret = lseek64(fd, offset, whence); | 155 | ret = lseek64(fd, offset, whence); |
156 | if(ret < 0) return(-errno); | 156 | if(ret < 0) |
157 | return(-errno); | ||
157 | return(0); | 158 | return(0); |
158 | } | 159 | } |
159 | 160 | ||
161 | int fsync_file(int fd, int datasync) | ||
162 | { | ||
163 | int ret; | ||
164 | if (datasync) | ||
165 | ret = fdatasync(fd); | ||
166 | else | ||
167 | ret = fsync(fd); | ||
168 | |||
169 | if (ret < 0) | ||
170 | return -errno; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
160 | void close_file(void *stream) | 174 | void close_file(void *stream) |
161 | { | 175 | { |
162 | close(*((int *) stream)); | 176 | close(*((int *) stream)); |
diff --git a/fs/inotify.c b/fs/inotify.c index a8a714e48140..27ebcac5e07f 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -90,6 +90,7 @@ struct inotify_device { | |||
90 | unsigned int queue_size; /* size of the queue (bytes) */ | 90 | unsigned int queue_size; /* size of the queue (bytes) */ |
91 | unsigned int event_count; /* number of pending events */ | 91 | unsigned int event_count; /* number of pending events */ |
92 | unsigned int max_events; /* maximum number of events */ | 92 | unsigned int max_events; /* maximum number of events */ |
93 | u32 last_wd; /* the last wd allocated */ | ||
93 | }; | 94 | }; |
94 | 95 | ||
95 | /* | 96 | /* |
@@ -352,7 +353,7 @@ static int inotify_dev_get_wd(struct inotify_device *dev, | |||
352 | do { | 353 | do { |
353 | if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) | 354 | if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) |
354 | return -ENOSPC; | 355 | return -ENOSPC; |
355 | ret = idr_get_new(&dev->idr, watch, &watch->wd); | 356 | ret = idr_get_new_above(&dev->idr, watch, dev->last_wd, &watch->wd); |
356 | } while (ret == -EAGAIN); | 357 | } while (ret == -EAGAIN); |
357 | 358 | ||
358 | return ret; | 359 | return ret; |
@@ -401,6 +402,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev, | |||
401 | return ERR_PTR(ret); | 402 | return ERR_PTR(ret); |
402 | } | 403 | } |
403 | 404 | ||
405 | dev->last_wd = ret; | ||
404 | watch->mask = mask; | 406 | watch->mask = mask; |
405 | atomic_set(&watch->count, 0); | 407 | atomic_set(&watch->count, 0); |
406 | INIT_LIST_HEAD(&watch->d_list); | 408 | INIT_LIST_HEAD(&watch->d_list); |
@@ -899,6 +901,7 @@ asmlinkage long sys_inotify_init(void) | |||
899 | dev->queue_size = 0; | 901 | dev->queue_size = 0; |
900 | dev->max_events = inotify_max_queued_events; | 902 | dev->max_events = inotify_max_queued_events; |
901 | dev->user = user; | 903 | dev->user = user; |
904 | dev->last_wd = 0; | ||
902 | atomic_set(&dev->count, 0); | 905 | atomic_set(&dev->count, 0); |
903 | 906 | ||
904 | get_inotify_dev(dev); | 907 | get_inotify_dev(dev); |
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c index 34a44e451689..4917315db732 100644 --- a/fs/isofs/compress.c +++ b/fs/isofs/compress.c | |||
@@ -129,8 +129,14 @@ static int zisofs_readpage(struct file *file, struct page *page) | |||
129 | cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask))); | 129 | cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask))); |
130 | brelse(bh); | 130 | brelse(bh); |
131 | 131 | ||
132 | if (cstart > cend) | ||
133 | goto eio; | ||
134 | |||
132 | csize = cend-cstart; | 135 | csize = cend-cstart; |
133 | 136 | ||
137 | if (csize > deflateBound(1UL << zisofs_block_shift)) | ||
138 | goto eio; | ||
139 | |||
134 | /* Now page[] contains an array of pages, any of which can be NULL, | 140 | /* Now page[] contains an array of pages, any of which can be NULL, |
135 | and the locks on which we hold. We should now read the data and | 141 | and the locks on which we hold. We should now read the data and |
136 | release the pages. If the pages are NULL the decompressed data | 142 | release the pages. If the pages are NULL the decompressed data |
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index fc589ddd0762..456d7e6e29c2 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c | |||
@@ -3397,6 +3397,9 @@ jffs_garbage_collect_thread(void *ptr) | |||
3397 | siginfo_t info; | 3397 | siginfo_t info; |
3398 | unsigned long signr = 0; | 3398 | unsigned long signr = 0; |
3399 | 3399 | ||
3400 | if (try_to_freeze()) | ||
3401 | continue; | ||
3402 | |||
3400 | spin_lock_irq(¤t->sighand->siglock); | 3403 | spin_lock_irq(¤t->sighand->siglock); |
3401 | signr = dequeue_signal(current, ¤t->blocked, &info); | 3404 | signr = dequeue_signal(current, ¤t->blocked, &info); |
3402 | spin_unlock_irq(¤t->sighand->siglock); | 3405 | spin_unlock_irq(¤t->sighand->siglock); |
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 0732f206ca60..c739626f5bf1 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c | |||
@@ -75,7 +75,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
75 | int nblocks); | 75 | int nblocks); |
76 | static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); | 76 | static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); |
77 | static void dbBackSplit(dmtree_t * tp, int leafno); | 77 | static void dbBackSplit(dmtree_t * tp, int leafno); |
78 | static void dbJoin(dmtree_t * tp, int leafno, int newval); | 78 | static int dbJoin(dmtree_t * tp, int leafno, int newval); |
79 | static void dbAdjTree(dmtree_t * tp, int leafno, int newval); | 79 | static void dbAdjTree(dmtree_t * tp, int leafno, int newval); |
80 | static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, | 80 | static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, |
81 | int level); | 81 | int level); |
@@ -98,8 +98,8 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); | |||
98 | static int dbFindBits(u32 word, int l2nb); | 98 | static int dbFindBits(u32 word, int l2nb); |
99 | static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); | 99 | static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); |
100 | static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); | 100 | static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); |
101 | static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | 101 | static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, |
102 | int nblocks); | 102 | int nblocks); |
103 | static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, | 103 | static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, |
104 | int nblocks); | 104 | int nblocks); |
105 | static int dbMaxBud(u8 * cp); | 105 | static int dbMaxBud(u8 * cp); |
@@ -378,6 +378,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) | |||
378 | 378 | ||
379 | /* free the blocks. */ | 379 | /* free the blocks. */ |
380 | if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) { | 380 | if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) { |
381 | jfs_error(ip->i_sb, "dbFree: error in block map\n"); | ||
381 | release_metapage(mp); | 382 | release_metapage(mp); |
382 | IREAD_UNLOCK(ipbmap); | 383 | IREAD_UNLOCK(ipbmap); |
383 | return (rc); | 384 | return (rc); |
@@ -2020,7 +2021,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2020 | int nblocks) | 2021 | int nblocks) |
2021 | { | 2022 | { |
2022 | s8 oldroot; | 2023 | s8 oldroot; |
2023 | int rc, word; | 2024 | int rc = 0, word; |
2024 | 2025 | ||
2025 | /* save the current value of the root (i.e. maximum free string) | 2026 | /* save the current value of the root (i.e. maximum free string) |
2026 | * of the dmap tree. | 2027 | * of the dmap tree. |
@@ -2028,11 +2029,11 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2028 | oldroot = dp->tree.stree[ROOT]; | 2029 | oldroot = dp->tree.stree[ROOT]; |
2029 | 2030 | ||
2030 | /* free the specified (blocks) bits */ | 2031 | /* free the specified (blocks) bits */ |
2031 | dbFreeBits(bmp, dp, blkno, nblocks); | 2032 | rc = dbFreeBits(bmp, dp, blkno, nblocks); |
2032 | 2033 | ||
2033 | /* if the root has not changed, done. */ | 2034 | /* if error or the root has not changed, done. */ |
2034 | if (dp->tree.stree[ROOT] == oldroot) | 2035 | if (rc || (dp->tree.stree[ROOT] == oldroot)) |
2035 | return (0); | 2036 | return (rc); |
2036 | 2037 | ||
2037 | /* root changed. bubble the change up to the dmap control pages. | 2038 | /* root changed. bubble the change up to the dmap control pages. |
2038 | * if the adjustment of the upper level control pages fails, | 2039 | * if the adjustment of the upper level control pages fails, |
@@ -2221,15 +2222,16 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2221 | * blkno - starting block number of the bits to be freed. | 2222 | * blkno - starting block number of the bits to be freed. |
2222 | * nblocks - number of bits to be freed. | 2223 | * nblocks - number of bits to be freed. |
2223 | * | 2224 | * |
2224 | * RETURN VALUES: none | 2225 | * RETURN VALUES: 0 for success |
2225 | * | 2226 | * |
2226 | * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; | 2227 | * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; |
2227 | */ | 2228 | */ |
2228 | static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | 2229 | static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, |
2229 | int nblocks) | 2230 | int nblocks) |
2230 | { | 2231 | { |
2231 | int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; | 2232 | int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; |
2232 | dmtree_t *tp = (dmtree_t *) & dp->tree; | 2233 | dmtree_t *tp = (dmtree_t *) & dp->tree; |
2234 | int rc = 0; | ||
2233 | int size; | 2235 | int size; |
2234 | 2236 | ||
2235 | /* determine the bit number and word within the dmap of the | 2237 | /* determine the bit number and word within the dmap of the |
@@ -2278,8 +2280,10 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2278 | 2280 | ||
2279 | /* update the leaf for this dmap word. | 2281 | /* update the leaf for this dmap word. |
2280 | */ | 2282 | */ |
2281 | dbJoin(tp, word, | 2283 | rc = dbJoin(tp, word, |
2282 | dbMaxBud((u8 *) & dp->wmap[word])); | 2284 | dbMaxBud((u8 *) & dp->wmap[word])); |
2285 | if (rc) | ||
2286 | return rc; | ||
2283 | 2287 | ||
2284 | word += 1; | 2288 | word += 1; |
2285 | } else { | 2289 | } else { |
@@ -2310,7 +2314,9 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2310 | 2314 | ||
2311 | /* update the leaf. | 2315 | /* update the leaf. |
2312 | */ | 2316 | */ |
2313 | dbJoin(tp, word, size); | 2317 | rc = dbJoin(tp, word, size); |
2318 | if (rc) | ||
2319 | return rc; | ||
2314 | 2320 | ||
2315 | /* get the number of dmap words handled. | 2321 | /* get the number of dmap words handled. |
2316 | */ | 2322 | */ |
@@ -2357,6 +2363,8 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2357 | } | 2363 | } |
2358 | 2364 | ||
2359 | BMAP_UNLOCK(bmp); | 2365 | BMAP_UNLOCK(bmp); |
2366 | |||
2367 | return 0; | ||
2360 | } | 2368 | } |
2361 | 2369 | ||
2362 | 2370 | ||
@@ -2464,7 +2472,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) | |||
2464 | } | 2472 | } |
2465 | dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); | 2473 | dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); |
2466 | } else { | 2474 | } else { |
2467 | dbJoin((dmtree_t *) dcp, leafno, newval); | 2475 | rc = dbJoin((dmtree_t *) dcp, leafno, newval); |
2476 | if (rc) | ||
2477 | return rc; | ||
2468 | } | 2478 | } |
2469 | 2479 | ||
2470 | /* check if the root of the current dmap control page changed due | 2480 | /* check if the root of the current dmap control page changed due |
@@ -2689,7 +2699,7 @@ static void dbBackSplit(dmtree_t * tp, int leafno) | |||
2689 | * | 2699 | * |
2690 | * RETURN VALUES: none | 2700 | * RETURN VALUES: none |
2691 | */ | 2701 | */ |
2692 | static void dbJoin(dmtree_t * tp, int leafno, int newval) | 2702 | static int dbJoin(dmtree_t * tp, int leafno, int newval) |
2693 | { | 2703 | { |
2694 | int budsz, buddy; | 2704 | int budsz, buddy; |
2695 | s8 *leaf; | 2705 | s8 *leaf; |
@@ -2729,7 +2739,9 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval) | |||
2729 | if (newval > leaf[buddy]) | 2739 | if (newval > leaf[buddy]) |
2730 | break; | 2740 | break; |
2731 | 2741 | ||
2732 | assert(newval == leaf[buddy]); | 2742 | /* It shouldn't be less */ |
2743 | if (newval < leaf[buddy]) | ||
2744 | return -EIO; | ||
2733 | 2745 | ||
2734 | /* check which (leafno or buddy) is the left buddy. | 2746 | /* check which (leafno or buddy) is the left buddy. |
2735 | * the left buddy gets to claim the blocks resulting | 2747 | * the left buddy gets to claim the blocks resulting |
@@ -2761,6 +2773,8 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval) | |||
2761 | /* update the leaf value. | 2773 | /* update the leaf value. |
2762 | */ | 2774 | */ |
2763 | dbAdjTree(tp, leafno, newval); | 2775 | dbAdjTree(tp, leafno, newval); |
2776 | |||
2777 | return 0; | ||
2764 | } | 2778 | } |
2765 | 2779 | ||
2766 | 2780 | ||
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 73b5fc7eda80..404f33eae507 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c | |||
@@ -381,9 +381,12 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) | |||
381 | * It's time to move the inline table to an external | 381 | * It's time to move the inline table to an external |
382 | * page and begin to build the xtree | 382 | * page and begin to build the xtree |
383 | */ | 383 | */ |
384 | if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage) || | 384 | if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage)) |
385 | dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) | 385 | goto clean_up; |
386 | goto clean_up; /* No space */ | 386 | if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { |
387 | DQUOT_FREE_BLOCK(ip, sbi->nbperpage); | ||
388 | goto clean_up; | ||
389 | } | ||
387 | 390 | ||
388 | /* | 391 | /* |
389 | * Save the table, we're going to overwrite it with the | 392 | * Save the table, we're going to overwrite it with the |
@@ -397,13 +400,15 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) | |||
397 | xtInitRoot(tid, ip); | 400 | xtInitRoot(tid, ip); |
398 | 401 | ||
399 | /* | 402 | /* |
400 | * Allocate the first block & add it to the xtree | 403 | * Add the first block to the xtree |
401 | */ | 404 | */ |
402 | if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { | 405 | if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { |
403 | /* This really shouldn't fail */ | 406 | /* This really shouldn't fail */ |
404 | jfs_warn("add_index: xtInsert failed!"); | 407 | jfs_warn("add_index: xtInsert failed!"); |
405 | memcpy(&jfs_ip->i_dirtable, temp_table, | 408 | memcpy(&jfs_ip->i_dirtable, temp_table, |
406 | sizeof (temp_table)); | 409 | sizeof (temp_table)); |
410 | dbFree(ip, xaddr, sbi->nbperpage); | ||
411 | DQUOT_FREE_BLOCK(ip, sbi->nbperpage); | ||
407 | goto clean_up; | 412 | goto clean_up; |
408 | } | 413 | } |
409 | ip->i_size = PSIZE; | 414 | ip->i_size = PSIZE; |
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 79d07624bfe1..22815e88e7cc 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -1030,7 +1030,8 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
1030 | * starting until all current transactions are completed | 1030 | * starting until all current transactions are completed |
1031 | * by setting syncbarrier flag. | 1031 | * by setting syncbarrier flag. |
1032 | */ | 1032 | */ |
1033 | if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) { | 1033 | if (!test_bit(log_SYNCBARRIER, &log->flag) && |
1034 | (written > LOGSYNC_BARRIER(logsize)) && log->active) { | ||
1034 | set_bit(log_SYNCBARRIER, &log->flag); | 1035 | set_bit(log_SYNCBARRIER, &log->flag); |
1035 | jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, | 1036 | jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, |
1036 | log->syncpt); | 1037 | log->syncpt); |
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 6c5485d16c39..13d7e3f1feb4 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
@@ -561,7 +561,6 @@ static int metapage_releasepage(struct page *page, int gfp_mask) | |||
561 | dump_mem("page", page, sizeof(struct page)); | 561 | dump_mem("page", page, sizeof(struct page)); |
562 | dump_stack(); | 562 | dump_stack(); |
563 | } | 563 | } |
564 | WARN_ON(mp->lsn); | ||
565 | if (mp->lsn) | 564 | if (mp->lsn) |
566 | remove_from_logsync(mp); | 565 | remove_from_logsync(mp); |
567 | remove_metapage(page, mp); | 566 | remove_metapage(page, mp); |
@@ -641,7 +640,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, | |||
641 | } else { | 640 | } else { |
642 | page = read_cache_page(mapping, page_index, | 641 | page = read_cache_page(mapping, page_index, |
643 | (filler_t *)mapping->a_ops->readpage, NULL); | 642 | (filler_t *)mapping->a_ops->readpage, NULL); |
644 | if (IS_ERR(page)) { | 643 | if (IS_ERR(page) || !PageUptodate(page)) { |
645 | jfs_err("read_cache_page failed!"); | 644 | jfs_err("read_cache_page failed!"); |
646 | return NULL; | 645 | return NULL; |
647 | } | 646 | } |
@@ -783,14 +782,6 @@ void release_metapage(struct metapage * mp) | |||
783 | if (test_bit(META_discard, &mp->flag) && !mp->count) { | 782 | if (test_bit(META_discard, &mp->flag) && !mp->count) { |
784 | clear_page_dirty(page); | 783 | clear_page_dirty(page); |
785 | ClearPageUptodate(page); | 784 | ClearPageUptodate(page); |
786 | #ifdef _NOT_YET | ||
787 | if (page->mapping) { | ||
788 | /* Remove from page cache and page cache reference */ | ||
789 | remove_from_page_cache(page); | ||
790 | page_cache_release(page); | ||
791 | metapage_releasepage(page, 0); | ||
792 | } | ||
793 | #endif | ||
794 | } | 785 | } |
795 | #else | 786 | #else |
796 | /* Try to keep metapages from using up too much memory */ | 787 | /* Try to keep metapages from using up too much memory */ |
diff --git a/fs/locks.c b/fs/locks.c index 29fa5da6c117..11956b6179ff 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1591,7 +1591,8 @@ out: | |||
1591 | /* Apply the lock described by l to an open file descriptor. | 1591 | /* Apply the lock described by l to an open file descriptor. |
1592 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 1592 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
1593 | */ | 1593 | */ |
1594 | int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l) | 1594 | int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, |
1595 | struct flock __user *l) | ||
1595 | { | 1596 | { |
1596 | struct file_lock *file_lock = locks_alloc_lock(); | 1597 | struct file_lock *file_lock = locks_alloc_lock(); |
1597 | struct flock flock; | 1598 | struct flock flock; |
@@ -1620,6 +1621,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l) | |||
1620 | goto out; | 1621 | goto out; |
1621 | } | 1622 | } |
1622 | 1623 | ||
1624 | again: | ||
1623 | error = flock_to_posix_lock(filp, file_lock, &flock); | 1625 | error = flock_to_posix_lock(filp, file_lock, &flock); |
1624 | if (error) | 1626 | if (error) |
1625 | goto out; | 1627 | goto out; |
@@ -1648,25 +1650,33 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l) | |||
1648 | if (error) | 1650 | if (error) |
1649 | goto out; | 1651 | goto out; |
1650 | 1652 | ||
1651 | if (filp->f_op && filp->f_op->lock != NULL) { | 1653 | if (filp->f_op && filp->f_op->lock != NULL) |
1652 | error = filp->f_op->lock(filp, cmd, file_lock); | 1654 | error = filp->f_op->lock(filp, cmd, file_lock); |
1653 | goto out; | 1655 | else { |
1654 | } | 1656 | for (;;) { |
1657 | error = __posix_lock_file(inode, file_lock); | ||
1658 | if ((error != -EAGAIN) || (cmd == F_SETLK)) | ||
1659 | break; | ||
1660 | error = wait_event_interruptible(file_lock->fl_wait, | ||
1661 | !file_lock->fl_next); | ||
1662 | if (!error) | ||
1663 | continue; | ||
1655 | 1664 | ||
1656 | for (;;) { | 1665 | locks_delete_block(file_lock); |
1657 | error = __posix_lock_file(inode, file_lock); | ||
1658 | if ((error != -EAGAIN) || (cmd == F_SETLK)) | ||
1659 | break; | 1666 | break; |
1660 | error = wait_event_interruptible(file_lock->fl_wait, | 1667 | } |
1661 | !file_lock->fl_next); | 1668 | } |
1662 | if (!error) | ||
1663 | continue; | ||
1664 | 1669 | ||
1665 | locks_delete_block(file_lock); | 1670 | /* |
1666 | break; | 1671 | * Attempt to detect a close/fcntl race and recover by |
1672 | * releasing the lock that was just acquired. | ||
1673 | */ | ||
1674 | if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { | ||
1675 | flock.l_type = F_UNLCK; | ||
1676 | goto again; | ||
1667 | } | 1677 | } |
1668 | 1678 | ||
1669 | out: | 1679 | out: |
1670 | locks_free_lock(file_lock); | 1680 | locks_free_lock(file_lock); |
1671 | return error; | 1681 | return error; |
1672 | } | 1682 | } |
@@ -1724,7 +1734,8 @@ out: | |||
1724 | /* Apply the lock described by l to an open file descriptor. | 1734 | /* Apply the lock described by l to an open file descriptor. |
1725 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 1735 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
1726 | */ | 1736 | */ |
1727 | int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) | 1737 | int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, |
1738 | struct flock64 __user *l) | ||
1728 | { | 1739 | { |
1729 | struct file_lock *file_lock = locks_alloc_lock(); | 1740 | struct file_lock *file_lock = locks_alloc_lock(); |
1730 | struct flock64 flock; | 1741 | struct flock64 flock; |
@@ -1753,6 +1764,7 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) | |||
1753 | goto out; | 1764 | goto out; |
1754 | } | 1765 | } |
1755 | 1766 | ||
1767 | again: | ||
1756 | error = flock64_to_posix_lock(filp, file_lock, &flock); | 1768 | error = flock64_to_posix_lock(filp, file_lock, &flock); |
1757 | if (error) | 1769 | if (error) |
1758 | goto out; | 1770 | goto out; |
@@ -1781,22 +1793,30 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) | |||
1781 | if (error) | 1793 | if (error) |
1782 | goto out; | 1794 | goto out; |
1783 | 1795 | ||
1784 | if (filp->f_op && filp->f_op->lock != NULL) { | 1796 | if (filp->f_op && filp->f_op->lock != NULL) |
1785 | error = filp->f_op->lock(filp, cmd, file_lock); | 1797 | error = filp->f_op->lock(filp, cmd, file_lock); |
1786 | goto out; | 1798 | else { |
1787 | } | 1799 | for (;;) { |
1800 | error = __posix_lock_file(inode, file_lock); | ||
1801 | if ((error != -EAGAIN) || (cmd == F_SETLK64)) | ||
1802 | break; | ||
1803 | error = wait_event_interruptible(file_lock->fl_wait, | ||
1804 | !file_lock->fl_next); | ||
1805 | if (!error) | ||
1806 | continue; | ||
1788 | 1807 | ||
1789 | for (;;) { | 1808 | locks_delete_block(file_lock); |
1790 | error = __posix_lock_file(inode, file_lock); | ||
1791 | if ((error != -EAGAIN) || (cmd == F_SETLK64)) | ||
1792 | break; | 1809 | break; |
1793 | error = wait_event_interruptible(file_lock->fl_wait, | 1810 | } |
1794 | !file_lock->fl_next); | 1811 | } |
1795 | if (!error) | ||
1796 | continue; | ||
1797 | 1812 | ||
1798 | locks_delete_block(file_lock); | 1813 | /* |
1799 | break; | 1814 | * Attempt to detect a close/fcntl race and recover by |
1815 | * releasing the lock that was just acquired. | ||
1816 | */ | ||
1817 | if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { | ||
1818 | flock.l_type = F_UNLCK; | ||
1819 | goto again; | ||
1800 | } | 1820 | } |
1801 | 1821 | ||
1802 | out: | 1822 | out: |
@@ -1888,12 +1908,7 @@ void locks_remove_flock(struct file *filp) | |||
1888 | 1908 | ||
1889 | while ((fl = *before) != NULL) { | 1909 | while ((fl = *before) != NULL) { |
1890 | if (fl->fl_file == filp) { | 1910 | if (fl->fl_file == filp) { |
1891 | /* | 1911 | if (IS_FLOCK(fl)) { |
1892 | * We might have a POSIX lock that was created at the same time | ||
1893 | * the filp was closed for the last time. Just remove that too, | ||
1894 | * regardless of ownership, since nobody can own it. | ||
1895 | */ | ||
1896 | if (IS_FLOCK(fl) || IS_POSIX(fl)) { | ||
1897 | locks_delete_lock(before); | 1912 | locks_delete_lock(before); |
1898 | continue; | 1913 | continue; |
1899 | } | 1914 | } |
diff --git a/fs/mbcache.c b/fs/mbcache.c index c7170b9221a3..b002a088857d 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
@@ -316,11 +316,10 @@ fail: | |||
316 | * currently in use cannot be freed, and thus remain in the cache. All others | 316 | * currently in use cannot be freed, and thus remain in the cache. All others |
317 | * are freed. | 317 | * are freed. |
318 | * | 318 | * |
319 | * @cache: which cache to shrink | ||
320 | * @bdev: which device's cache entries to shrink | 319 | * @bdev: which device's cache entries to shrink |
321 | */ | 320 | */ |
322 | void | 321 | void |
323 | mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev) | 322 | mb_cache_shrink(struct block_device *bdev) |
324 | { | 323 | { |
325 | LIST_HEAD(free_list); | 324 | LIST_HEAD(free_list); |
326 | struct list_head *l, *ltmp; | 325 | struct list_head *l, *ltmp; |
diff --git a/fs/namei.c b/fs/namei.c index e252b12d39be..264e232addda 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1801,7 +1801,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1801 | } | 1801 | } |
1802 | up(&dentry->d_inode->i_sem); | 1802 | up(&dentry->d_inode->i_sem); |
1803 | if (!error) { | 1803 | if (!error) { |
1804 | fsnotify_rmdir(dentry, dentry->d_inode, dir); | ||
1805 | d_delete(dentry); | 1804 | d_delete(dentry); |
1806 | } | 1805 | } |
1807 | dput(dentry); | 1806 | dput(dentry); |
@@ -1874,7 +1873,6 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1874 | 1873 | ||
1875 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ | 1874 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
1876 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | 1875 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { |
1877 | fsnotify_unlink(dentry, dir); | ||
1878 | d_delete(dentry); | 1876 | d_delete(dentry); |
1879 | } | 1877 | } |
1880 | 1878 | ||
@@ -2218,7 +2216,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2218 | error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); | 2216 | error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); |
2219 | if (!error) { | 2217 | if (!error) { |
2220 | const char *new_name = old_dentry->d_name.name; | 2218 | const char *new_name = old_dentry->d_name.name; |
2221 | fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir); | 2219 | fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, new_dentry->d_inode); |
2222 | } | 2220 | } |
2223 | fsnotify_oldname_free(old_name); | 2221 | fsnotify_oldname_free(old_name); |
2224 | 2222 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 587eb0d707ee..79bd8a46e1e7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -160,7 +160,7 @@ clone_mnt(struct vfsmount *old, struct dentry *root) | |||
160 | mnt->mnt_root = dget(root); | 160 | mnt->mnt_root = dget(root); |
161 | mnt->mnt_mountpoint = mnt->mnt_root; | 161 | mnt->mnt_mountpoint = mnt->mnt_root; |
162 | mnt->mnt_parent = mnt; | 162 | mnt->mnt_parent = mnt; |
163 | mnt->mnt_namespace = old->mnt_namespace; | 163 | mnt->mnt_namespace = current->namespace; |
164 | 164 | ||
165 | /* stick the duplicate mount on the same expiry list | 165 | /* stick the duplicate mount on the same expiry list |
166 | * as the original if that was on one */ | 166 | * as the original if that was on one */ |
diff --git a/fs/ntfs/sysctl.h b/fs/ntfs/sysctl.h index df749cc0aac8..c8064cae8f17 100644 --- a/fs/ntfs/sysctl.h +++ b/fs/ntfs/sysctl.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #include <linux/config.h> | 27 | #include <linux/config.h> |
28 | 28 | ||
29 | #if (DEBUG && CONFIG_SYSCTL) | 29 | #if defined(DEBUG) && defined(CONFIG_SYSCTL) |
30 | 30 | ||
31 | extern int ntfs_sysctl(int add); | 31 | extern int ntfs_sysctl(int add); |
32 | 32 | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 1aaf2c7d44e6..d9f614a57731 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1980,7 +1980,17 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1980 | out_inserted_sd: | 1980 | out_inserted_sd: |
1981 | inode->i_nlink = 0; | 1981 | inode->i_nlink = 0; |
1982 | th->t_trans_id = 0; /* so the caller can't use this handle later */ | 1982 | th->t_trans_id = 0; /* so the caller can't use this handle later */ |
1983 | iput(inode); | 1983 | |
1984 | /* If we were inheriting an ACL, we need to release the lock so that | ||
1985 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking | ||
1986 | * code really needs to be reworked, but this will take care of it | ||
1987 | * for now. -jeffm */ | ||
1988 | if (REISERFS_I(dir)->i_acl_default) { | ||
1989 | reiserfs_write_unlock_xattrs(dir->i_sb); | ||
1990 | iput(inode); | ||
1991 | reiserfs_write_lock_xattrs(dir->i_sb); | ||
1992 | } else | ||
1993 | iput(inode); | ||
1984 | return err; | 1994 | return err; |
1985 | } | 1995 | } |
1986 | 1996 | ||
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index c66c27ec4100..ca7989b04be3 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -556,14 +556,14 @@ static inline void insert_journal_hash(struct reiserfs_journal_cnode **table, | |||
556 | } | 556 | } |
557 | 557 | ||
558 | /* lock the current transaction */ | 558 | /* lock the current transaction */ |
559 | inline static void lock_journal(struct super_block *p_s_sb) | 559 | static inline void lock_journal(struct super_block *p_s_sb) |
560 | { | 560 | { |
561 | PROC_INFO_INC(p_s_sb, journal.lock_journal); | 561 | PROC_INFO_INC(p_s_sb, journal.lock_journal); |
562 | down(&SB_JOURNAL(p_s_sb)->j_lock); | 562 | down(&SB_JOURNAL(p_s_sb)->j_lock); |
563 | } | 563 | } |
564 | 564 | ||
565 | /* unlock the current transaction */ | 565 | /* unlock the current transaction */ |
566 | inline static void unlock_journal(struct super_block *p_s_sb) | 566 | static inline void unlock_journal(struct super_block *p_s_sb) |
567 | { | 567 | { |
568 | up(&SB_JOURNAL(p_s_sb)->j_lock); | 568 | up(&SB_JOURNAL(p_s_sb)->j_lock); |
569 | } | 569 | } |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e386d3db3051..87ac9dc8b381 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/xattr.h> | 39 | #include <linux/xattr.h> |
40 | #include <linux/reiserfs_xattr.h> | 40 | #include <linux/reiserfs_xattr.h> |
41 | #include <linux/reiserfs_acl.h> | 41 | #include <linux/reiserfs_acl.h> |
42 | #include <linux/mbcache.h> | ||
43 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
44 | #include <asm/checksum.h> | 43 | #include <asm/checksum.h> |
45 | #include <linux/smp_lock.h> | 44 | #include <linux/smp_lock.h> |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 335288b9be0f..4013d7905e84 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -437,8 +437,8 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
437 | { | 437 | { |
438 | struct dentry *dir = kobj->dentry; | 438 | struct dentry *dir = kobj->dentry; |
439 | struct dentry *victim; | 439 | struct dentry *victim; |
440 | struct sysfs_dirent *sd; | 440 | struct inode * inode; |
441 | umode_t umode = (mode & S_IALLUGO) | S_IFREG; | 441 | struct iattr newattrs; |
442 | int res = -ENOENT; | 442 | int res = -ENOENT; |
443 | 443 | ||
444 | down(&dir->d_inode->i_sem); | 444 | down(&dir->d_inode->i_sem); |
@@ -446,13 +446,15 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
446 | if (!IS_ERR(victim)) { | 446 | if (!IS_ERR(victim)) { |
447 | if (victim->d_inode && | 447 | if (victim->d_inode && |
448 | (victim->d_parent->d_inode == dir->d_inode)) { | 448 | (victim->d_parent->d_inode == dir->d_inode)) { |
449 | sd = victim->d_fsdata; | 449 | inode = victim->d_inode; |
450 | attr->mode = mode; | 450 | down(&inode->i_sem); |
451 | sd->s_mode = umode; | 451 | newattrs.ia_mode = (mode & S_IALLUGO) | |
452 | victim->d_inode->i_mode = umode; | 452 | (inode->i_mode & ~S_IALLUGO); |
453 | dput(victim); | 453 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
454 | res = 0; | 454 | res = notify_change(victim, &newattrs); |
455 | up(&inode->i_sem); | ||
455 | } | 456 | } |
457 | dput(victim); | ||
456 | } | 458 | } |
457 | up(&dir->d_inode->i_sem); | 459 | up(&dir->d_inode->i_sem); |
458 | 460 | ||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 8de13bafaa76..d727dc960634 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -85,7 +85,7 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
85 | 85 | ||
86 | if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) | 86 | if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) |
87 | mode &= ~S_ISGID; | 87 | mode &= ~S_ISGID; |
88 | sd_iattr->ia_mode = mode; | 88 | sd_iattr->ia_mode = sd->s_mode = mode; |
89 | } | 89 | } |
90 | 90 | ||
91 | return error; | 91 | return error; |