aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 23:05:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 23:05:37 -0400
commit4b4f1d017815f96737ca4a62f90e5a1f0b9f02d6 (patch)
treec95ae92ec01cabf6c2a40d31a31da6a4d9256816
parent875287caa067492779670f5fb3b98ec8dcfe2cb0 (diff)
parentaa7dfb8954ccf49e026ba13d12991a4eb7defb96 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (87 commits) nilfs2: get rid of bd_mount_sem use from nilfs nilfs2: correct exclusion control in nilfs_remount function nilfs2: simplify remaining sget() use nilfs2: get rid of sget use for checking if current mount is present nilfs2: get rid of sget use for acquiring nilfs object nilfs2: remove meaningless EBUSY case from nilfs_get_sb function remove the call to ->write_super in __sync_filesystem nilfs2: call nilfs2_write_super from nilfs2_sync_fs jffs2: call jffs2_write_super from jffs2_sync_fs ufs: add ->sync_fs sysv: add ->sync_fs hfsplus: add ->sync_fs hfs: add ->sync_fs fat: add ->sync_fs ext2: add ->sync_fs exofs: add ->sync_fs bfs: add ->sync_fs affs: add ->sync_fs sanitize ->fsync() for affs repair bfs_write_inode(), switch bfs to simple_fsync() ...
-rw-r--r--arch/alpha/kernel/osf_sys.c3
-rw-r--r--drivers/ieee1394/dv1394.c5
-rw-r--r--drivers/ieee1394/ieee1394_core.h6
-rw-r--r--drivers/usb/core/inode.c5
-rw-r--r--fs/adfs/adfs.h4
-rw-r--r--fs/adfs/dir.c10
-rw-r--r--fs/adfs/dir_f.c17
-rw-r--r--fs/adfs/dir_fplus.c17
-rw-r--r--fs/adfs/file.c2
-rw-r--r--fs/adfs/inode.c4
-rw-r--r--fs/adfs/map.c2
-rw-r--r--fs/adfs/super.c4
-rw-r--r--fs/affs/affs.h1
-rw-r--r--fs/affs/dir.c2
-rw-r--r--fs/affs/file.c14
-rw-r--r--fs/affs/super.c54
-rw-r--r--fs/afs/mntpt.c2
-rw-r--r--fs/afs/super.c4
-rw-r--r--fs/autofs/dirhash.c5
-rw-r--r--fs/autofs4/autofs_i.h6
-rw-r--r--fs/autofs4/dev-ioctl.c195
-rw-r--r--fs/autofs4/expire.c15
-rw-r--r--fs/autofs4/root.c7
-rw-r--r--fs/befs/linuxvfs.c5
-rw-r--r--fs/bfs/dir.c8
-rw-r--r--fs/bfs/inode.c52
-rw-r--r--fs/block_dev.c19
-rw-r--r--fs/btrfs/inode.c7
-rw-r--r--fs/btrfs/super.c11
-rw-r--r--fs/cachefiles/interface.c4
-rw-r--r--fs/char_dev.c14
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifsfs.c6
-rw-r--r--fs/compat.c2
-rw-r--r--fs/dcache.c7
-rw-r--r--fs/ecryptfs/super.c5
-rw-r--r--fs/exofs/super.c25
-rw-r--r--fs/ext2/Makefile2
-rw-r--r--fs/ext2/dir.c2
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/file.c4
-rw-r--r--fs/ext2/fsync.c50
-rw-r--r--fs/ext2/inode.c11
-rw-r--r--fs/ext2/super.c60
-rw-r--r--fs/ext3/balloc.c3
-rw-r--r--fs/ext3/ialloc.c3
-rw-r--r--fs/ext3/inode.c1
-rw-r--r--fs/ext3/resize.c2
-rw-r--r--fs/ext3/super.c34
-rw-r--r--fs/ext3/xattr.c1
-rw-r--r--fs/ext4/super.c16
-rw-r--r--fs/fat/dir.c16
-rw-r--r--fs/fat/fat.h6
-rw-r--r--fs/fat/fatent.c13
-rw-r--r--fs/fat/file.c14
-rw-r--r--fs/fat/inode.c31
-rw-r--r--fs/fat/namei_msdos.c4
-rw-r--r--fs/fat/namei_vfat.c4
-rw-r--r--fs/file_table.c40
-rw-r--r--fs/freevxfs/vxfs_super.c4
-rw-r--r--fs/fs-writeback.c92
-rw-r--r--fs/gfs2/log.c2
-rw-r--r--fs/gfs2/super.c15
-rw-r--r--fs/hfs/super.c23
-rw-r--r--fs/hfsplus/super.c25
-rw-r--r--fs/hpfs/super.c12
-rw-r--r--fs/inode.c2
-rw-r--r--fs/internal.h17
-rw-r--r--fs/isofs/inode.c5
-rw-r--r--fs/jffs2/fs.c18
-rw-r--r--fs/jffs2/os-linux.h1
-rw-r--r--fs/jffs2/super.c26
-rw-r--r--fs/jfs/super.c27
-rw-r--r--fs/libfs.c25
-rw-r--r--fs/minix/dir.c2
-rw-r--r--fs/minix/file.c20
-rw-r--r--fs/minix/inode.c37
-rw-r--r--fs/minix/minix.h2
-rw-r--r--fs/namei.c129
-rw-r--r--fs/namespace.c327
-rw-r--r--fs/ncpfs/inode.c4
-rw-r--r--fs/nfs/namespace.c2
-rw-r--r--fs/nfs/super.c2
-rw-r--r--fs/nfsd/export.c78
-rw-r--r--fs/nfsd/vfs.c54
-rw-r--r--fs/nilfs2/cpfile.c6
-rw-r--r--fs/nilfs2/sb.h1
-rw-r--r--fs/nilfs2/super.c256
-rw-r--r--fs/nilfs2/the_nilfs.c113
-rw-r--r--fs/nilfs2/the_nilfs.h23
-rw-r--r--fs/ntfs/super.c54
-rw-r--r--fs/ocfs2/super.c22
-rw-r--r--fs/omfs/file.c17
-rw-r--r--fs/open.c4
-rw-r--r--fs/proc/internal.h25
-rw-r--r--fs/proc/proc_devtree.c1
-rw-r--r--fs/qnx4/Makefile2
-rw-r--r--fs/qnx4/bitmap.c7
-rw-r--r--fs/qnx4/dir.c9
-rw-r--r--fs/qnx4/file.c5
-rw-r--r--fs/qnx4/fsync.c169
-rw-r--r--fs/qnx4/inode.c58
-rw-r--r--fs/qnx4/namei.c13
-rw-r--r--fs/qnx4/qnx4.h57
-rw-r--r--fs/qnx4/truncate.c6
-rw-r--r--fs/quota/quota.c25
-rw-r--r--fs/reiserfs/dir.c10
-rw-r--r--fs/reiserfs/super.c33
-rw-r--r--fs/reiserfs/xattr.c3
-rw-r--r--fs/smbfs/inode.c4
-rw-r--r--fs/squashfs/super.c4
-rw-r--r--fs/super.c192
-rw-r--r--fs/sync.c117
-rw-r--r--fs/sysv/dir.c2
-rw-r--r--fs/sysv/file.c17
-rw-r--r--fs/sysv/inode.c75
-rw-r--r--fs/sysv/sysv.h1
-rw-r--r--fs/ubifs/super.c17
-rw-r--r--fs/udf/Makefile2
-rw-r--r--fs/udf/dir.c2
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/udf/fsync.c52
-rw-r--r--fs/udf/super.c11
-rw-r--r--fs/udf/udfdecl.h3
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/ufs/file.c23
-rw-r--r--fs/ufs/super.c65
-rw-r--r--fs/ufs/ufs.h1
-rw-r--r--fs/xattr.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c12
-rw-r--r--fs/xfs/xfs_trans.c2
-rw-r--r--include/linux/Kbuild2
-rw-r--r--include/linux/cdev.h2
-rw-r--r--include/linux/cramfs_fs.h3
-rw-r--r--include/linux/dcache.h7
-rw-r--r--include/linux/fs.h21
-rw-r--r--include/linux/magic.h2
-rw-r--r--include/linux/mount.h25
-rw-r--r--include/linux/namei.h5
-rw-r--r--include/linux/nfsd/export.h6
-rw-r--r--include/linux/proc_fs.h24
-rw-r--r--include/linux/qnx4_fs.h61
-rw-r--r--include/linux/quotaops.h20
-rw-r--r--include/linux/reiserfs_fs_sb.h2
-rw-r--r--include/linux/writeback.h1
-rw-r--r--kernel/audit_tree.c6
-rw-r--r--kernel/cgroup.c3
147 files changed, 1707 insertions, 1834 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 42ee05981e71..9a3334ae282e 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -371,8 +371,6 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
371 int retval = -EINVAL; 371 int retval = -EINVAL;
372 char *name; 372 char *name;
373 373
374 lock_kernel();
375
376 name = getname(path); 374 name = getname(path);
377 retval = PTR_ERR(name); 375 retval = PTR_ERR(name);
378 if (IS_ERR(name)) 376 if (IS_ERR(name))
@@ -392,7 +390,6 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
392 } 390 }
393 putname(name); 391 putname(name);
394 out: 392 out:
395 unlock_kernel();
396 return retval; 393 return retval;
397} 394}
398 395
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 823a6297a1af..2cd00b5b45b4 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1789,12 +1789,13 @@ static int dv1394_open(struct inode *inode, struct file *file)
1789 } else { 1789 } else {
1790 /* look up the card by ID */ 1790 /* look up the card by ID */
1791 unsigned long flags; 1791 unsigned long flags;
1792 int idx = ieee1394_file_to_instance(file);
1792 1793
1793 spin_lock_irqsave(&dv1394_cards_lock, flags); 1794 spin_lock_irqsave(&dv1394_cards_lock, flags);
1794 if (!list_empty(&dv1394_cards)) { 1795 if (!list_empty(&dv1394_cards)) {
1795 struct video_card *p; 1796 struct video_card *p;
1796 list_for_each_entry(p, &dv1394_cards, list) { 1797 list_for_each_entry(p, &dv1394_cards, list) {
1797 if ((p->id) == ieee1394_file_to_instance(file)) { 1798 if ((p->id) == idx) {
1798 video = p; 1799 video = p;
1799 break; 1800 break;
1800 } 1801 }
@@ -1803,7 +1804,7 @@ static int dv1394_open(struct inode *inode, struct file *file)
1803 spin_unlock_irqrestore(&dv1394_cards_lock, flags); 1804 spin_unlock_irqrestore(&dv1394_cards_lock, flags);
1804 1805
1805 if (!video) { 1806 if (!video) {
1806 debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file)); 1807 debug_printk("dv1394: OHCI card %d not found", idx);
1807 return -ENODEV; 1808 return -ENODEV;
1808 } 1809 }
1809 1810
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 21d50f73a210..28b9f58bafd2 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -5,6 +5,7 @@
5#include <linux/fs.h> 5#include <linux/fs.h>
6#include <linux/list.h> 6#include <linux/list.h>
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/cdev.h>
8#include <asm/atomic.h> 9#include <asm/atomic.h>
9 10
10#include "hosts.h" 11#include "hosts.h"
@@ -155,7 +156,10 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
155 */ 156 */
156static inline unsigned char ieee1394_file_to_instance(struct file *file) 157static inline unsigned char ieee1394_file_to_instance(struct file *file)
157{ 158{
158 return file->f_path.dentry->d_inode->i_cindex; 159 int idx = cdev_index(file->f_path.dentry->d_inode);
160 if (idx < 0)
161 idx = 0;
162 return idx;
159} 163}
160 164
161extern int hpsb_disable_irm; 165extern int hpsb_disable_irm;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index dff5760a37f6..ffe75e83787c 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -39,6 +39,7 @@
39#include <linux/parser.h> 39#include <linux/parser.h>
40#include <linux/notifier.h> 40#include <linux/notifier.h>
41#include <linux/seq_file.h> 41#include <linux/seq_file.h>
42#include <linux/smp_lock.h>
42#include <asm/byteorder.h> 43#include <asm/byteorder.h>
43#include "usb.h" 44#include "usb.h"
44#include "hcd.h" 45#include "hcd.h"
@@ -265,9 +266,13 @@ static int remount(struct super_block *sb, int *flags, char *data)
265 return -EINVAL; 266 return -EINVAL;
266 } 267 }
267 268
269 lock_kernel();
270
268 if (usbfs_mount && usbfs_mount->mnt_sb) 271 if (usbfs_mount && usbfs_mount->mnt_sb)
269 update_sb(usbfs_mount->mnt_sb); 272 update_sb(usbfs_mount->mnt_sb);
270 273
274 unlock_kernel();
275
271 return 0; 276 return 0;
272} 277}
273 278
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index e0a85dbeeb88..a6665f37f456 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -53,6 +53,7 @@ struct adfs_dir_ops {
53 int (*update)(struct adfs_dir *dir, struct object_info *obj); 53 int (*update)(struct adfs_dir *dir, struct object_info *obj);
54 int (*create)(struct adfs_dir *dir, struct object_info *obj); 54 int (*create)(struct adfs_dir *dir, struct object_info *obj);
55 int (*remove)(struct adfs_dir *dir, struct object_info *obj); 55 int (*remove)(struct adfs_dir *dir, struct object_info *obj);
56 int (*sync)(struct adfs_dir *dir);
56 void (*free)(struct adfs_dir *dir); 57 void (*free)(struct adfs_dir *dir);
57}; 58};
58 59
@@ -90,7 +91,8 @@ extern const struct dentry_operations adfs_dentry_operations;
90extern struct adfs_dir_ops adfs_f_dir_ops; 91extern struct adfs_dir_ops adfs_f_dir_ops;
91extern struct adfs_dir_ops adfs_fplus_dir_ops; 92extern struct adfs_dir_ops adfs_fplus_dir_ops;
92 93
93extern int adfs_dir_update(struct super_block *sb, struct object_info *obj); 94extern int adfs_dir_update(struct super_block *sb, struct object_info *obj,
95 int wait);
94 96
95/* file.c */ 97/* file.c */
96extern const struct inode_operations adfs_file_inode_operations; 98extern const struct inode_operations adfs_file_inode_operations;
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index e867ccf37246..4d4073447d1a 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -83,7 +83,7 @@ out:
83} 83}
84 84
85int 85int
86adfs_dir_update(struct super_block *sb, struct object_info *obj) 86adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
87{ 87{
88 int ret = -EINVAL; 88 int ret = -EINVAL;
89#ifdef CONFIG_ADFS_FS_RW 89#ifdef CONFIG_ADFS_FS_RW
@@ -106,6 +106,12 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj)
106 ret = ops->update(&dir, obj); 106 ret = ops->update(&dir, obj);
107 write_unlock(&adfs_dir_lock); 107 write_unlock(&adfs_dir_lock);
108 108
109 if (wait) {
110 int err = ops->sync(&dir);
111 if (!ret)
112 ret = err;
113 }
114
109 ops->free(&dir); 115 ops->free(&dir);
110out: 116out:
111#endif 117#endif
@@ -199,7 +205,7 @@ const struct file_operations adfs_dir_operations = {
199 .read = generic_read_dir, 205 .read = generic_read_dir,
200 .llseek = generic_file_llseek, 206 .llseek = generic_file_llseek,
201 .readdir = adfs_readdir, 207 .readdir = adfs_readdir,
202 .fsync = file_fsync, 208 .fsync = simple_fsync,
203}; 209};
204 210
205static int 211static int
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
index ea7df2146921..31df6adf0de6 100644
--- a/fs/adfs/dir_f.c
+++ b/fs/adfs/dir_f.c
@@ -437,6 +437,22 @@ bad_dir:
437#endif 437#endif
438} 438}
439 439
440static int
441adfs_f_sync(struct adfs_dir *dir)
442{
443 int err = 0;
444 int i;
445
446 for (i = dir->nr_buffers - 1; i >= 0; i--) {
447 struct buffer_head *bh = dir->bh[i];
448 sync_dirty_buffer(bh);
449 if (buffer_req(bh) && !buffer_uptodate(bh))
450 err = -EIO;
451 }
452
453 return err;
454}
455
440static void 456static void
441adfs_f_free(struct adfs_dir *dir) 457adfs_f_free(struct adfs_dir *dir)
442{ 458{
@@ -456,5 +472,6 @@ struct adfs_dir_ops adfs_f_dir_ops = {
456 .setpos = adfs_f_setpos, 472 .setpos = adfs_f_setpos,
457 .getnext = adfs_f_getnext, 473 .getnext = adfs_f_getnext,
458 .update = adfs_f_update, 474 .update = adfs_f_update,
475 .sync = adfs_f_sync,
459 .free = adfs_f_free 476 .free = adfs_f_free
460}; 477};
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c
index 1ec644e32df9..139e0f345f18 100644
--- a/fs/adfs/dir_fplus.c
+++ b/fs/adfs/dir_fplus.c
@@ -161,6 +161,22 @@ out:
161 return ret; 161 return ret;
162} 162}
163 163
164static int
165adfs_fplus_sync(struct adfs_dir *dir)
166{
167 int err = 0;
168 int i;
169
170 for (i = dir->nr_buffers - 1; i >= 0; i--) {
171 struct buffer_head *bh = dir->bh[i];
172 sync_dirty_buffer(bh);
173 if (buffer_req(bh) && !buffer_uptodate(bh))
174 err = -EIO;
175 }
176
177 return err;
178}
179
164static void 180static void
165adfs_fplus_free(struct adfs_dir *dir) 181adfs_fplus_free(struct adfs_dir *dir)
166{ 182{
@@ -175,5 +191,6 @@ struct adfs_dir_ops adfs_fplus_dir_ops = {
175 .read = adfs_fplus_read, 191 .read = adfs_fplus_read,
176 .setpos = adfs_fplus_setpos, 192 .setpos = adfs_fplus_setpos,
177 .getnext = adfs_fplus_getnext, 193 .getnext = adfs_fplus_getnext,
194 .sync = adfs_fplus_sync,
178 .free = adfs_fplus_free 195 .free = adfs_fplus_free
179}; 196};
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index 36e381c6a99a..8224d54a2afb 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -30,7 +30,7 @@ const struct file_operations adfs_file_operations = {
30 .read = do_sync_read, 30 .read = do_sync_read,
31 .aio_read = generic_file_aio_read, 31 .aio_read = generic_file_aio_read,
32 .mmap = generic_file_mmap, 32 .mmap = generic_file_mmap,
33 .fsync = file_fsync, 33 .fsync = simple_fsync,
34 .write = do_sync_write, 34 .write = do_sync_write,
35 .aio_write = generic_file_aio_write, 35 .aio_write = generic_file_aio_write,
36 .splice_read = generic_file_splice_read, 36 .splice_read = generic_file_splice_read,
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index e647200262a2..05b3a677201d 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -376,7 +376,7 @@ out:
376 * The adfs-specific inode data has already been updated by 376 * The adfs-specific inode data has already been updated by
377 * adfs_notify_change() 377 * adfs_notify_change()
378 */ 378 */
379int adfs_write_inode(struct inode *inode, int unused) 379int adfs_write_inode(struct inode *inode, int wait)
380{ 380{
381 struct super_block *sb = inode->i_sb; 381 struct super_block *sb = inode->i_sb;
382 struct object_info obj; 382 struct object_info obj;
@@ -391,7 +391,7 @@ int adfs_write_inode(struct inode *inode, int unused)
391 obj.attr = ADFS_I(inode)->attr; 391 obj.attr = ADFS_I(inode)->attr;
392 obj.size = inode->i_size; 392 obj.size = inode->i_size;
393 393
394 ret = adfs_dir_update(sb, &obj); 394 ret = adfs_dir_update(sb, &obj, wait);
395 unlock_kernel(); 395 unlock_kernel();
396 return ret; 396 return ret;
397} 397}
diff --git a/fs/adfs/map.c b/fs/adfs/map.c
index 92ab4fbc2031..568081b93f73 100644
--- a/fs/adfs/map.c
+++ b/fs/adfs/map.c
@@ -62,7 +62,7 @@ static DEFINE_RWLOCK(adfs_map_lock);
62#define GET_FRAG_ID(_map,_start,_idmask) \ 62#define GET_FRAG_ID(_map,_start,_idmask) \
63 ({ \ 63 ({ \
64 unsigned char *_m = _map + (_start >> 3); \ 64 unsigned char *_m = _map + (_start >> 3); \
65 u32 _frag = get_unaligned((u32 *)_m); \ 65 u32 _frag = get_unaligned_le32(_m); \
66 _frag >>= (_start & 7); \ 66 _frag >>= (_start & 7); \
67 _frag & _idmask; \ 67 _frag & _idmask; \
68 }) 68 })
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index dd9becca4241..0ec5aaf47aa7 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -132,11 +132,15 @@ static void adfs_put_super(struct super_block *sb)
132 int i; 132 int i;
133 struct adfs_sb_info *asb = ADFS_SB(sb); 133 struct adfs_sb_info *asb = ADFS_SB(sb);
134 134
135 lock_kernel();
136
135 for (i = 0; i < asb->s_map_size; i++) 137 for (i = 0; i < asb->s_map_size; i++)
136 brelse(asb->s_map[i].dm_bh); 138 brelse(asb->s_map[i].dm_bh);
137 kfree(asb->s_map); 139 kfree(asb->s_map);
138 kfree(asb); 140 kfree(asb);
139 sb->s_fs_info = NULL; 141 sb->s_fs_info = NULL;
142
143 unlock_kernel();
140} 144}
141 145
142static int adfs_show_options(struct seq_file *seq, struct vfsmount *mnt) 146static int adfs_show_options(struct seq_file *seq, struct vfsmount *mnt)
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index 1a2d5e3c7f4e..e511dc621a2e 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -182,6 +182,7 @@ extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dent
182 182
183void affs_free_prealloc(struct inode *inode); 183void affs_free_prealloc(struct inode *inode);
184extern void affs_truncate(struct inode *); 184extern void affs_truncate(struct inode *);
185int affs_file_fsync(struct file *, struct dentry *, int);
185 186
186/* dir.c */ 187/* dir.c */
187 188
diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index 7b36904dbeac..8ca8f3a55599 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -21,7 +21,7 @@ const struct file_operations affs_dir_operations = {
21 .read = generic_read_dir, 21 .read = generic_read_dir,
22 .llseek = generic_file_llseek, 22 .llseek = generic_file_llseek,
23 .readdir = affs_readdir, 23 .readdir = affs_readdir,
24 .fsync = file_fsync, 24 .fsync = affs_file_fsync,
25}; 25};
26 26
27/* 27/*
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 9246cb4aa018..184e55c1c9ba 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -34,7 +34,7 @@ const struct file_operations affs_file_operations = {
34 .mmap = generic_file_mmap, 34 .mmap = generic_file_mmap,
35 .open = affs_file_open, 35 .open = affs_file_open,
36 .release = affs_file_release, 36 .release = affs_file_release,
37 .fsync = file_fsync, 37 .fsync = affs_file_fsync,
38 .splice_read = generic_file_splice_read, 38 .splice_read = generic_file_splice_read,
39}; 39};
40 40
@@ -915,3 +915,15 @@ affs_truncate(struct inode *inode)
915 } 915 }
916 affs_free_prealloc(inode); 916 affs_free_prealloc(inode);
917} 917}
918
919int affs_file_fsync(struct file *filp, struct dentry *dentry, int datasync)
920{
921 struct inode * inode = dentry->d_inode;
922 int ret, err;
923
924 ret = write_inode_now(inode, 0);
925 err = sync_blockdev(inode->i_sb->s_bdev);
926 if (!ret)
927 ret = err;
928 return ret;
929}
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 63f5183f263b..104fdcb3a7fc 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -16,6 +16,7 @@
16#include <linux/parser.h> 16#include <linux/parser.h>
17#include <linux/magic.h> 17#include <linux/magic.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/smp_lock.h>
19#include "affs.h" 20#include "affs.h"
20 21
21extern struct timezone sys_tz; 22extern struct timezone sys_tz;
@@ -24,49 +25,67 @@ static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
24static int affs_remount (struct super_block *sb, int *flags, char *data); 25static int affs_remount (struct super_block *sb, int *flags, char *data);
25 26
26static void 27static void
28affs_commit_super(struct super_block *sb, int clean)
29{
30 struct affs_sb_info *sbi = AFFS_SB(sb);
31 struct buffer_head *bh = sbi->s_root_bh;
32 struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh);
33
34 tail->bm_flag = cpu_to_be32(clean);
35 secs_to_datestamp(get_seconds(), &tail->disk_change);
36 affs_fix_checksum(sb, bh);
37 mark_buffer_dirty(bh);
38}
39
40static void
27affs_put_super(struct super_block *sb) 41affs_put_super(struct super_block *sb)
28{ 42{
29 struct affs_sb_info *sbi = AFFS_SB(sb); 43 struct affs_sb_info *sbi = AFFS_SB(sb);
30 pr_debug("AFFS: put_super()\n"); 44 pr_debug("AFFS: put_super()\n");
31 45
32 if (!(sb->s_flags & MS_RDONLY)) { 46 lock_kernel();
33 AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1); 47
34 secs_to_datestamp(get_seconds(), 48 if (!(sb->s_flags & MS_RDONLY))
35 &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change); 49 affs_commit_super(sb, 1);
36 affs_fix_checksum(sb, sbi->s_root_bh);
37 mark_buffer_dirty(sbi->s_root_bh);
38 }
39 50
40 kfree(sbi->s_prefix); 51 kfree(sbi->s_prefix);
41 affs_free_bitmap(sb); 52 affs_free_bitmap(sb);
42 affs_brelse(sbi->s_root_bh); 53 affs_brelse(sbi->s_root_bh);
43 kfree(sbi); 54 kfree(sbi);
44 sb->s_fs_info = NULL; 55 sb->s_fs_info = NULL;
45 return; 56
57 unlock_kernel();
46} 58}
47 59
48static void 60static void
49affs_write_super(struct super_block *sb) 61affs_write_super(struct super_block *sb)
50{ 62{
51 int clean = 2; 63 int clean = 2;
52 struct affs_sb_info *sbi = AFFS_SB(sb);
53 64
65 lock_super(sb);
54 if (!(sb->s_flags & MS_RDONLY)) { 66 if (!(sb->s_flags & MS_RDONLY)) {
55 // if (sbi->s_bitmap[i].bm_bh) { 67 // if (sbi->s_bitmap[i].bm_bh) {
56 // if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) { 68 // if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) {
57 // clean = 0; 69 // clean = 0;
58 AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(clean); 70 affs_commit_super(sb, clean);
59 secs_to_datestamp(get_seconds(),
60 &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
61 affs_fix_checksum(sb, sbi->s_root_bh);
62 mark_buffer_dirty(sbi->s_root_bh);
63 sb->s_dirt = !clean; /* redo until bitmap synced */ 71 sb->s_dirt = !clean; /* redo until bitmap synced */
64 } else 72 } else
65 sb->s_dirt = 0; 73 sb->s_dirt = 0;
74 unlock_super(sb);
66 75
67 pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); 76 pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean);
68} 77}
69 78
79static int
80affs_sync_fs(struct super_block *sb, int wait)
81{
82 lock_super(sb);
83 affs_commit_super(sb, 2);
84 sb->s_dirt = 0;
85 unlock_super(sb);
86 return 0;
87}
88
70static struct kmem_cache * affs_inode_cachep; 89static struct kmem_cache * affs_inode_cachep;
71 90
72static struct inode *affs_alloc_inode(struct super_block *sb) 91static struct inode *affs_alloc_inode(struct super_block *sb)
@@ -124,6 +143,7 @@ static const struct super_operations affs_sops = {
124 .clear_inode = affs_clear_inode, 143 .clear_inode = affs_clear_inode,
125 .put_super = affs_put_super, 144 .put_super = affs_put_super,
126 .write_super = affs_write_super, 145 .write_super = affs_write_super,
146 .sync_fs = affs_sync_fs,
127 .statfs = affs_statfs, 147 .statfs = affs_statfs,
128 .remount_fs = affs_remount, 148 .remount_fs = affs_remount,
129 .show_options = generic_show_options, 149 .show_options = generic_show_options,
@@ -507,6 +527,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
507 kfree(new_opts); 527 kfree(new_opts);
508 return -EINVAL; 528 return -EINVAL;
509 } 529 }
530 lock_kernel();
510 replace_mount_options(sb, new_opts); 531 replace_mount_options(sb, new_opts);
511 532
512 sbi->s_flags = mount_flags; 533 sbi->s_flags = mount_flags;
@@ -514,8 +535,10 @@ affs_remount(struct super_block *sb, int *flags, char *data)
514 sbi->s_uid = uid; 535 sbi->s_uid = uid;
515 sbi->s_gid = gid; 536 sbi->s_gid = gid;
516 537
517 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 538 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
539 unlock_kernel();
518 return 0; 540 return 0;
541 }
519 if (*flags & MS_RDONLY) { 542 if (*flags & MS_RDONLY) {
520 sb->s_dirt = 1; 543 sb->s_dirt = 1;
521 while (sb->s_dirt) 544 while (sb->s_dirt)
@@ -524,6 +547,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
524 } else 547 } else
525 res = affs_init_bitmap(sb, flags); 548 res = affs_init_bitmap(sb, flags);
526 549
550 unlock_kernel();
527 return res; 551 return res;
528} 552}
529 553
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 2b9e2d03a390..c52be53f6946 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -244,7 +244,7 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
244 case -EBUSY: 244 case -EBUSY:
245 /* someone else made a mount here whilst we were busy */ 245 /* someone else made a mount here whilst we were busy */
246 while (d_mountpoint(nd->path.dentry) && 246 while (d_mountpoint(nd->path.dentry) &&
247 follow_down(&nd->path.mnt, &nd->path.dentry)) 247 follow_down(&nd->path))
248 ; 248 ;
249 err = 0; 249 err = 0;
250 default: 250 default:
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 76828e5f8a39..ad0514d0115f 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -440,8 +440,12 @@ static void afs_put_super(struct super_block *sb)
440 440
441 _enter(""); 441 _enter("");
442 442
443 lock_kernel();
444
443 afs_put_volume(as->volume); 445 afs_put_volume(as->volume);
444 446
447 unlock_kernel();
448
445 _leave(""); 449 _leave("");
446} 450}
447 451
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
index 4eb4d8dfb2f1..2316e944a109 100644
--- a/fs/autofs/dirhash.c
+++ b/fs/autofs/dirhash.c
@@ -85,13 +85,12 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
85 } 85 }
86 path.mnt = mnt; 86 path.mnt = mnt;
87 path_get(&path); 87 path_get(&path);
88 if (!follow_down(&path.mnt, &path.dentry)) { 88 if (!follow_down(&path)) {
89 path_put(&path); 89 path_put(&path);
90 DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); 90 DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
91 continue; 91 continue;
92 } 92 }
93 while (d_mountpoint(path.dentry) && 93 while (d_mountpoint(path.dentry) && follow_down(&path));
94 follow_down(&path.mnt, &path.dentry))
95 ; 94 ;
96 umount_ok = may_umount(path.mnt); 95 umount_ok = may_umount(path.mnt);
97 path_put(&path); 96 path_put(&path);
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index b7ff33c63101..8f7cdde41733 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -223,12 +223,12 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
223int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); 223int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
224void autofs4_catatonic_mode(struct autofs_sb_info *); 224void autofs4_catatonic_mode(struct autofs_sb_info *);
225 225
226static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry) 226static inline int autofs4_follow_mount(struct path *path)
227{ 227{
228 int res = 0; 228 int res = 0;
229 229
230 while (d_mountpoint(*dentry)) { 230 while (d_mountpoint(path->dentry)) {
231 int followed = follow_down(mnt, dentry); 231 int followed = follow_down(path);
232 if (!followed) 232 if (!followed)
233 break; 233 break;
234 res = 1; 234 res = 1;
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 84168c0dcc2d..f3da2eb51f56 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -192,77 +192,42 @@ static int autofs_dev_ioctl_protosubver(struct file *fp,
192 return 0; 192 return 0;
193} 193}
194 194
195/* 195static int find_autofs_mount(const char *pathname,
196 * Walk down the mount stack looking for an autofs mount that 196 struct path *res,
197 * has the requested device number (aka. new_encode_dev(sb->s_dev). 197 int test(struct path *path, void *data),
198 */ 198 void *data)
199static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
200{ 199{
201 struct dentry *dentry; 200 struct path path;
202 struct inode *inode; 201 int err = kern_path(pathname, 0, &path);
203 struct super_block *sb; 202 if (err)
204 dev_t s_dev; 203 return err;
205 unsigned int err;
206
207 err = -ENOENT; 204 err = -ENOENT;
208 205 while (path.dentry == path.mnt->mnt_root) {
209 /* Lookup the dentry name at the base of our mount point */ 206 if (path.mnt->mnt_sb->s_magic == AUTOFS_SUPER_MAGIC) {
210 dentry = d_lookup(nd->path.dentry, &nd->last); 207 if (test(&path, data)) {
211 if (!dentry) 208 path_get(&path);
212 goto out; 209 if (!err) /* already found some */
213 210 path_put(res);
214 dput(nd->path.dentry); 211 *res = path;
215 nd->path.dentry = dentry;
216
217 /* And follow the mount stack looking for our autofs mount */
218 while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
219 inode = nd->path.dentry->d_inode;
220 if (!inode)
221 break;
222
223 sb = inode->i_sb;
224 s_dev = new_encode_dev(sb->s_dev);
225 if (devno == s_dev) {
226 if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
227 err = 0; 212 err = 0;
228 break;
229 } 213 }
230 } 214 }
215 if (!follow_up(&path))
216 break;
231 } 217 }
232out: 218 path_put(&path);
233 return err; 219 return err;
234} 220}
235 221
236/* 222static int test_by_dev(struct path *path, void *p)
237 * Walk down the mount stack looking for an autofs mount that
238 * has the requested mount type (ie. indirect, direct or offset).
239 */
240static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
241{ 223{
242 struct dentry *dentry; 224 return path->mnt->mnt_sb->s_dev == *(dev_t *)p;
243 struct autofs_info *ino; 225}
244 unsigned int err;
245
246 err = -ENOENT;
247
248 /* Lookup the dentry name at the base of our mount point */
249 dentry = d_lookup(nd->path.dentry, &nd->last);
250 if (!dentry)
251 goto out;
252
253 dput(nd->path.dentry);
254 nd->path.dentry = dentry;
255 226
256 /* And follow the mount stack looking for our autofs mount */ 227static int test_by_type(struct path *path, void *p)
257 while (follow_down(&nd->path.mnt, &nd->path.dentry)) { 228{
258 ino = autofs4_dentry_ino(nd->path.dentry); 229 struct autofs_info *ino = autofs4_dentry_ino(path->dentry);
259 if (ino && ino->sbi->type & type) { 230 return ino && ino->sbi->type & *(unsigned *)p;
260 err = 0;
261 break;
262 }
263 }
264out:
265 return err;
266} 231}
267 232
268static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file) 233static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
@@ -283,31 +248,25 @@ static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
283 * Open a file descriptor on the autofs mount point corresponding 248 * Open a file descriptor on the autofs mount point corresponding
284 * to the given path and device number (aka. new_encode_dev(sb->s_dev)). 249 * to the given path and device number (aka. new_encode_dev(sb->s_dev)).
285 */ 250 */
286static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid) 251static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
287{ 252{
288 struct file *filp;
289 struct nameidata nd;
290 int err, fd; 253 int err, fd;
291 254
292 fd = get_unused_fd(); 255 fd = get_unused_fd();
293 if (likely(fd >= 0)) { 256 if (likely(fd >= 0)) {
294 /* Get nameidata of the parent directory */ 257 struct file *filp;
295 err = path_lookup(path, LOOKUP_PARENT, &nd); 258 struct path path;
259
260 err = find_autofs_mount(name, &path, test_by_dev, &devid);
296 if (err) 261 if (err)
297 goto out; 262 goto out;
298 263
299 /* 264 /*
300 * Search down, within the parent, looking for an 265 * Find autofs super block that has the device number
301 * autofs super block that has the device number
302 * corresponding to the autofs fs we want to open. 266 * corresponding to the autofs fs we want to open.
303 */ 267 */
304 err = autofs_dev_ioctl_find_super(&nd, devid);
305 if (err) {
306 path_put(&nd.path);
307 goto out;
308 }
309 268
310 filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, 269 filp = dentry_open(path.dentry, path.mnt, O_RDONLY,
311 current_cred()); 270 current_cred());
312 if (IS_ERR(filp)) { 271 if (IS_ERR(filp)) {
313 err = PTR_ERR(filp); 272 err = PTR_ERR(filp);
@@ -340,7 +299,7 @@ static int autofs_dev_ioctl_openmount(struct file *fp,
340 param->ioctlfd = -1; 299 param->ioctlfd = -1;
341 300
342 path = param->path; 301 path = param->path;
343 devid = param->openmount.devid; 302 devid = new_decode_dev(param->openmount.devid);
344 303
345 err = 0; 304 err = 0;
346 fd = autofs_dev_ioctl_open_mountpoint(path, devid); 305 fd = autofs_dev_ioctl_open_mountpoint(path, devid);
@@ -475,8 +434,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
475 struct autofs_dev_ioctl *param) 434 struct autofs_dev_ioctl *param)
476{ 435{
477 struct autofs_info *ino; 436 struct autofs_info *ino;
478 struct nameidata nd; 437 struct path path;
479 const char *path;
480 dev_t devid; 438 dev_t devid;
481 int err = -ENOENT; 439 int err = -ENOENT;
482 440
@@ -485,32 +443,24 @@ static int autofs_dev_ioctl_requester(struct file *fp,
485 goto out; 443 goto out;
486 } 444 }
487 445
488 path = param->path; 446 devid = sbi->sb->s_dev;
489 devid = new_encode_dev(sbi->sb->s_dev);
490 447
491 param->requester.uid = param->requester.gid = -1; 448 param->requester.uid = param->requester.gid = -1;
492 449
493 /* Get nameidata of the parent directory */ 450 err = find_autofs_mount(param->path, &path, test_by_dev, &devid);
494 err = path_lookup(path, LOOKUP_PARENT, &nd);
495 if (err) 451 if (err)
496 goto out; 452 goto out;
497 453
498 err = autofs_dev_ioctl_find_super(&nd, devid); 454 ino = autofs4_dentry_ino(path.dentry);
499 if (err)
500 goto out_release;
501
502 ino = autofs4_dentry_ino(nd.path.dentry);
503 if (ino) { 455 if (ino) {
504 err = 0; 456 err = 0;
505 autofs4_expire_wait(nd.path.dentry); 457 autofs4_expire_wait(path.dentry);
506 spin_lock(&sbi->fs_lock); 458 spin_lock(&sbi->fs_lock);
507 param->requester.uid = ino->uid; 459 param->requester.uid = ino->uid;
508 param->requester.gid = ino->gid; 460 param->requester.gid = ino->gid;
509 spin_unlock(&sbi->fs_lock); 461 spin_unlock(&sbi->fs_lock);
510 } 462 }
511 463 path_put(&path);
512out_release:
513 path_put(&nd.path);
514out: 464out:
515 return err; 465 return err;
516} 466}
@@ -569,8 +519,8 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
569 struct autofs_sb_info *sbi, 519 struct autofs_sb_info *sbi,
570 struct autofs_dev_ioctl *param) 520 struct autofs_dev_ioctl *param)
571{ 521{
572 struct nameidata nd; 522 struct path path;
573 const char *path; 523 const char *name;
574 unsigned int type; 524 unsigned int type;
575 unsigned int devid, magic; 525 unsigned int devid, magic;
576 int err = -ENOENT; 526 int err = -ENOENT;
@@ -580,71 +530,46 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
580 goto out; 530 goto out;
581 } 531 }
582 532
583 path = param->path; 533 name = param->path;
584 type = param->ismountpoint.in.type; 534 type = param->ismountpoint.in.type;
585 535
586 param->ismountpoint.out.devid = devid = 0; 536 param->ismountpoint.out.devid = devid = 0;
587 param->ismountpoint.out.magic = magic = 0; 537 param->ismountpoint.out.magic = magic = 0;
588 538
589 if (!fp || param->ioctlfd == -1) { 539 if (!fp || param->ioctlfd == -1) {
590 if (autofs_type_any(type)) { 540 if (autofs_type_any(type))
591 struct super_block *sb; 541 err = kern_path(name, LOOKUP_FOLLOW, &path);
592 542 else
593 err = path_lookup(path, LOOKUP_FOLLOW, &nd); 543 err = find_autofs_mount(name, &path, test_by_type, &type);
594 if (err) 544 if (err)
595 goto out; 545 goto out;
596 546 devid = new_encode_dev(path.mnt->mnt_sb->s_dev);
597 sb = nd.path.dentry->d_sb;
598 devid = new_encode_dev(sb->s_dev);
599 } else {
600 struct autofs_info *ino;
601
602 err = path_lookup(path, LOOKUP_PARENT, &nd);
603 if (err)
604 goto out;
605
606 err = autofs_dev_ioctl_find_sbi_type(&nd, type);
607 if (err)
608 goto out_release;
609
610 ino = autofs4_dentry_ino(nd.path.dentry);
611 devid = autofs4_get_dev(ino->sbi);
612 }
613
614 err = 0; 547 err = 0;
615 if (nd.path.dentry->d_inode && 548 if (path.dentry->d_inode &&
616 nd.path.mnt->mnt_root == nd.path.dentry) { 549 path.mnt->mnt_root == path.dentry) {
617 err = 1; 550 err = 1;
618 magic = nd.path.dentry->d_inode->i_sb->s_magic; 551 magic = path.dentry->d_inode->i_sb->s_magic;
619 } 552 }
620 } else { 553 } else {
621 dev_t dev = autofs4_get_dev(sbi); 554 dev_t dev = sbi->sb->s_dev;
622 555
623 err = path_lookup(path, LOOKUP_PARENT, &nd); 556 err = find_autofs_mount(name, &path, test_by_dev, &dev);
624 if (err) 557 if (err)
625 goto out; 558 goto out;
626 559
627 err = autofs_dev_ioctl_find_super(&nd, dev); 560 devid = new_encode_dev(dev);
628 if (err)
629 goto out_release;
630
631 devid = dev;
632 561
633 err = have_submounts(nd.path.dentry); 562 err = have_submounts(path.dentry);
634 563
635 if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { 564 if (path.mnt->mnt_mountpoint != path.mnt->mnt_root) {
636 if (follow_down(&nd.path.mnt, &nd.path.dentry)) { 565 if (follow_down(&path))
637 struct inode *inode = nd.path.dentry->d_inode; 566 magic = path.mnt->mnt_sb->s_magic;
638 magic = inode->i_sb->s_magic;
639 }
640 } 567 }
641 } 568 }
642 569
643 param->ismountpoint.out.devid = devid; 570 param->ismountpoint.out.devid = devid;
644 param->ismountpoint.out.magic = magic; 571 param->ismountpoint.out.magic = magic;
645 572 path_put(&path);
646out_release:
647 path_put(&nd.path);
648out: 573out:
649 return err; 574 return err;
650} 575}
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 3077d8f16523..aa39ae83f019 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -48,19 +48,19 @@ static inline int autofs4_can_expire(struct dentry *dentry,
48static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) 48static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
49{ 49{
50 struct dentry *top = dentry; 50 struct dentry *top = dentry;
51 struct path path = {.mnt = mnt, .dentry = dentry};
51 int status = 1; 52 int status = 1;
52 53
53 DPRINTK("dentry %p %.*s", 54 DPRINTK("dentry %p %.*s",
54 dentry, (int)dentry->d_name.len, dentry->d_name.name); 55 dentry, (int)dentry->d_name.len, dentry->d_name.name);
55 56
56 mntget(mnt); 57 path_get(&path);
57 dget(dentry);
58 58
59 if (!follow_down(&mnt, &dentry)) 59 if (!follow_down(&path))
60 goto done; 60 goto done;
61 61
62 if (is_autofs4_dentry(dentry)) { 62 if (is_autofs4_dentry(path.dentry)) {
63 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 63 struct autofs_sb_info *sbi = autofs4_sbi(path.dentry->d_sb);
64 64
65 /* This is an autofs submount, we can't expire it */ 65 /* This is an autofs submount, we can't expire it */
66 if (autofs_type_indirect(sbi->type)) 66 if (autofs_type_indirect(sbi->type))
@@ -70,7 +70,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
70 * Otherwise it's an offset mount and we need to check 70 * Otherwise it's an offset mount and we need to check
71 * if we can umount its mount, if there is one. 71 * if we can umount its mount, if there is one.
72 */ 72 */
73 if (!d_mountpoint(dentry)) { 73 if (!d_mountpoint(path.dentry)) {
74 status = 0; 74 status = 0;
75 goto done; 75 goto done;
76 } 76 }
@@ -86,8 +86,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
86 status = 0; 86 status = 0;
87done: 87done:
88 DPRINTK("returning = %d", status); 88 DPRINTK("returning = %d", status);
89 dput(dentry); 89 path_put(&path);
90 mntput(mnt);
91 return status; 90 return status;
92} 91}
93 92
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index e383bf0334f1..b96a3c57359d 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -181,7 +181,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
181 nd->flags); 181 nd->flags);
182 /* 182 /*
183 * For an expire of a covered direct or offset mount we need 183 * For an expire of a covered direct or offset mount we need
184 * to beeak out of follow_down() at the autofs mount trigger 184 * to break out of follow_down() at the autofs mount trigger
185 * (d_mounted--), so we can see the expiring flag, and manage 185 * (d_mounted--), so we can see the expiring flag, and manage
186 * the blocking and following here until the expire is completed. 186 * the blocking and following here until the expire is completed.
187 */ 187 */
@@ -190,7 +190,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
190 if (ino->flags & AUTOFS_INF_EXPIRING) { 190 if (ino->flags & AUTOFS_INF_EXPIRING) {
191 spin_unlock(&sbi->fs_lock); 191 spin_unlock(&sbi->fs_lock);
192 /* Follow down to our covering mount. */ 192 /* Follow down to our covering mount. */
193 if (!follow_down(&nd->path.mnt, &nd->path.dentry)) 193 if (!follow_down(&nd->path))
194 goto done; 194 goto done;
195 goto follow; 195 goto follow;
196 } 196 }
@@ -230,8 +230,7 @@ follow:
230 * to follow it. 230 * to follow it.
231 */ 231 */
232 if (d_mountpoint(dentry)) { 232 if (d_mountpoint(dentry)) {
233 if (!autofs4_follow_mount(&nd->path.mnt, 233 if (!autofs4_follow_mount(&nd->path)) {
234 &nd->path.dentry)) {
235 status = -ENOENT; 234 status = -ENOENT;
236 goto out_error; 235 goto out_error;
237 } 236 }
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 76afd0d6b86c..9367b6297d84 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -737,6 +737,8 @@ parse_options(char *options, befs_mount_options * opts)
737static void 737static void
738befs_put_super(struct super_block *sb) 738befs_put_super(struct super_block *sb)
739{ 739{
740 lock_kernel();
741
740 kfree(BEFS_SB(sb)->mount_opts.iocharset); 742 kfree(BEFS_SB(sb)->mount_opts.iocharset);
741 BEFS_SB(sb)->mount_opts.iocharset = NULL; 743 BEFS_SB(sb)->mount_opts.iocharset = NULL;
742 744
@@ -747,7 +749,8 @@ befs_put_super(struct super_block *sb)
747 749
748 kfree(sb->s_fs_info); 750 kfree(sb->s_fs_info);
749 sb->s_fs_info = NULL; 751 sb->s_fs_info = NULL;
750 return; 752
753 unlock_kernel();
751} 754}
752 755
753/* Allocate private field of the superblock, fill it. 756/* Allocate private field of the superblock, fill it.
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 4dd1b623f937..54bd07d44e68 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -79,7 +79,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
79const struct file_operations bfs_dir_operations = { 79const struct file_operations bfs_dir_operations = {
80 .read = generic_read_dir, 80 .read = generic_read_dir,
81 .readdir = bfs_readdir, 81 .readdir = bfs_readdir,
82 .fsync = file_fsync, 82 .fsync = simple_fsync,
83 .llseek = generic_file_llseek, 83 .llseek = generic_file_llseek,
84}; 84};
85 85
@@ -205,7 +205,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry)
205 inode->i_nlink = 1; 205 inode->i_nlink = 1;
206 } 206 }
207 de->ino = 0; 207 de->ino = 0;
208 mark_buffer_dirty(bh); 208 mark_buffer_dirty_inode(bh, dir);
209 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 209 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
210 mark_inode_dirty(dir); 210 mark_inode_dirty(dir);
211 inode->i_ctime = dir->i_ctime; 211 inode->i_ctime = dir->i_ctime;
@@ -267,7 +267,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
267 new_inode->i_ctime = CURRENT_TIME_SEC; 267 new_inode->i_ctime = CURRENT_TIME_SEC;
268 inode_dec_link_count(new_inode); 268 inode_dec_link_count(new_inode);
269 } 269 }
270 mark_buffer_dirty(old_bh); 270 mark_buffer_dirty_inode(old_bh, old_dir);
271 error = 0; 271 error = 0;
272 272
273end_rename: 273end_rename:
@@ -320,7 +320,7 @@ static int bfs_add_entry(struct inode *dir, const unsigned char *name,
320 for (i = 0; i < BFS_NAMELEN; i++) 320 for (i = 0; i < BFS_NAMELEN; i++)
321 de->name[i] = 321 de->name[i] =
322 (i < namelen) ? name[i] : 0; 322 (i < namelen) ? name[i] : 0;
323 mark_buffer_dirty(bh); 323 mark_buffer_dirty_inode(bh, dir);
324 brelse(bh); 324 brelse(bh);
325 return 0; 325 return 0;
326 } 326 }
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index cc4062d12ca2..6f60336c6628 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -30,6 +30,7 @@ MODULE_LICENSE("GPL");
30#define dprintf(x...) 30#define dprintf(x...)
31#endif 31#endif
32 32
33static void bfs_write_super(struct super_block *s);
33void dump_imap(const char *prefix, struct super_block *s); 34void dump_imap(const char *prefix, struct super_block *s);
34 35
35struct inode *bfs_iget(struct super_block *sb, unsigned long ino) 36struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
@@ -97,14 +98,15 @@ error:
97 return ERR_PTR(-EIO); 98 return ERR_PTR(-EIO);
98} 99}
99 100
100static int bfs_write_inode(struct inode *inode, int unused) 101static int bfs_write_inode(struct inode *inode, int wait)
101{ 102{
103 struct bfs_sb_info *info = BFS_SB(inode->i_sb);
102 unsigned int ino = (u16)inode->i_ino; 104 unsigned int ino = (u16)inode->i_ino;
103 unsigned long i_sblock; 105 unsigned long i_sblock;
104 struct bfs_inode *di; 106 struct bfs_inode *di;
105 struct buffer_head *bh; 107 struct buffer_head *bh;
106 int block, off; 108 int block, off;
107 struct bfs_sb_info *info = BFS_SB(inode->i_sb); 109 int err = 0;
108 110
109 dprintf("ino=%08x\n", ino); 111 dprintf("ino=%08x\n", ino);
110 112
@@ -145,9 +147,14 @@ static int bfs_write_inode(struct inode *inode, int unused)
145 di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); 147 di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
146 148
147 mark_buffer_dirty(bh); 149 mark_buffer_dirty(bh);
150 if (wait) {
151 sync_dirty_buffer(bh);
152 if (buffer_req(bh) && !buffer_uptodate(bh))
153 err = -EIO;
154 }
148 brelse(bh); 155 brelse(bh);
149 mutex_unlock(&info->bfs_lock); 156 mutex_unlock(&info->bfs_lock);
150 return 0; 157 return err;
151} 158}
152 159
153static void bfs_delete_inode(struct inode *inode) 160static void bfs_delete_inode(struct inode *inode)
@@ -209,6 +216,26 @@ static void bfs_delete_inode(struct inode *inode)
209 clear_inode(inode); 216 clear_inode(inode);
210} 217}
211 218
219static int bfs_sync_fs(struct super_block *sb, int wait)
220{
221 struct bfs_sb_info *info = BFS_SB(sb);
222
223 mutex_lock(&info->bfs_lock);
224 mark_buffer_dirty(info->si_sbh);
225 sb->s_dirt = 0;
226 mutex_unlock(&info->bfs_lock);
227
228 return 0;
229}
230
231static void bfs_write_super(struct super_block *sb)
232{
233 if (!(sb->s_flags & MS_RDONLY))
234 bfs_sync_fs(sb, 1);
235 else
236 sb->s_dirt = 0;
237}
238
212static void bfs_put_super(struct super_block *s) 239static void bfs_put_super(struct super_block *s)
213{ 240{
214 struct bfs_sb_info *info = BFS_SB(s); 241 struct bfs_sb_info *info = BFS_SB(s);
@@ -216,11 +243,18 @@ static void bfs_put_super(struct super_block *s)
216 if (!info) 243 if (!info)
217 return; 244 return;
218 245
246 lock_kernel();
247
248 if (s->s_dirt)
249 bfs_write_super(s);
250
219 brelse(info->si_sbh); 251 brelse(info->si_sbh);
220 mutex_destroy(&info->bfs_lock); 252 mutex_destroy(&info->bfs_lock);
221 kfree(info->si_imap); 253 kfree(info->si_imap);
222 kfree(info); 254 kfree(info);
223 s->s_fs_info = NULL; 255 s->s_fs_info = NULL;
256
257 unlock_kernel();
224} 258}
225 259
226static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) 260static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -240,17 +274,6 @@ static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
240 return 0; 274 return 0;
241} 275}
242 276
243static void bfs_write_super(struct super_block *s)
244{
245 struct bfs_sb_info *info = BFS_SB(s);
246
247 mutex_lock(&info->bfs_lock);
248 if (!(s->s_flags & MS_RDONLY))
249 mark_buffer_dirty(info->si_sbh);
250 s->s_dirt = 0;
251 mutex_unlock(&info->bfs_lock);
252}
253
254static struct kmem_cache *bfs_inode_cachep; 277static struct kmem_cache *bfs_inode_cachep;
255 278
256static struct inode *bfs_alloc_inode(struct super_block *sb) 279static struct inode *bfs_alloc_inode(struct super_block *sb)
@@ -298,6 +321,7 @@ static const struct super_operations bfs_sops = {
298 .delete_inode = bfs_delete_inode, 321 .delete_inode = bfs_delete_inode,
299 .put_super = bfs_put_super, 322 .put_super = bfs_put_super,
300 .write_super = bfs_write_super, 323 .write_super = bfs_write_super,
324 .sync_fs = bfs_sync_fs,
301 .statfs = bfs_statfs, 325 .statfs = bfs_statfs,
302}; 326};
303 327
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 931f6b8c4b2f..3a6d4fb2a329 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -176,17 +176,22 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
176 iov, offset, nr_segs, blkdev_get_blocks, NULL); 176 iov, offset, nr_segs, blkdev_get_blocks, NULL);
177} 177}
178 178
179int __sync_blockdev(struct block_device *bdev, int wait)
180{
181 if (!bdev)
182 return 0;
183 if (!wait)
184 return filemap_flush(bdev->bd_inode->i_mapping);
185 return filemap_write_and_wait(bdev->bd_inode->i_mapping);
186}
187
179/* 188/*
180 * Write out and wait upon all the dirty data associated with a block 189 * Write out and wait upon all the dirty data associated with a block
181 * device via its mapping. Does not take the superblock lock. 190 * device via its mapping. Does not take the superblock lock.
182 */ 191 */
183int sync_blockdev(struct block_device *bdev) 192int sync_blockdev(struct block_device *bdev)
184{ 193{
185 int ret = 0; 194 return __sync_blockdev(bdev, 1);
186
187 if (bdev)
188 ret = filemap_write_and_wait(bdev->bd_inode->i_mapping);
189 return ret;
190} 195}
191EXPORT_SYMBOL(sync_blockdev); 196EXPORT_SYMBOL(sync_blockdev);
192 197
@@ -199,7 +204,7 @@ int fsync_bdev(struct block_device *bdev)
199{ 204{
200 struct super_block *sb = get_super(bdev); 205 struct super_block *sb = get_super(bdev);
201 if (sb) { 206 if (sb) {
202 int res = fsync_super(sb); 207 int res = sync_filesystem(sb);
203 drop_super(sb); 208 drop_super(sb);
204 return res; 209 return res;
205 } 210 }
@@ -241,7 +246,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
241 sb->s_frozen = SB_FREEZE_WRITE; 246 sb->s_frozen = SB_FREEZE_WRITE;
242 smp_wmb(); 247 smp_wmb();
243 248
244 __fsync_super(sb); 249 sync_filesystem(sb);
245 250
246 sb->s_frozen = SB_FREEZE_TRANS; 251 sb->s_frozen = SB_FREEZE_TRANS;
247 smp_wmb(); 252 smp_wmb();
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5b68330f8585..8612b3a09811 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2322,7 +2322,6 @@ err:
2322 btrfs_update_inode(trans, root, dir); 2322 btrfs_update_inode(trans, root, dir);
2323 btrfs_drop_nlink(inode); 2323 btrfs_drop_nlink(inode);
2324 ret = btrfs_update_inode(trans, root, inode); 2324 ret = btrfs_update_inode(trans, root, inode);
2325 dir->i_sb->s_dirt = 1;
2326out: 2325out:
2327 return ret; 2326 return ret;
2328} 2327}
@@ -2806,7 +2805,6 @@ error:
2806 pending_del_nr); 2805 pending_del_nr);
2807 } 2806 }
2808 btrfs_free_path(path); 2807 btrfs_free_path(path);
2809 inode->i_sb->s_dirt = 1;
2810 return ret; 2808 return ret;
2811} 2809}
2812 2810
@@ -3768,7 +3766,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
3768 init_special_inode(inode, inode->i_mode, rdev); 3766 init_special_inode(inode, inode->i_mode, rdev);
3769 btrfs_update_inode(trans, root, inode); 3767 btrfs_update_inode(trans, root, inode);
3770 } 3768 }
3771 dir->i_sb->s_dirt = 1;
3772 btrfs_update_inode_block_group(trans, inode); 3769 btrfs_update_inode_block_group(trans, inode);
3773 btrfs_update_inode_block_group(trans, dir); 3770 btrfs_update_inode_block_group(trans, dir);
3774out_unlock: 3771out_unlock:
@@ -3833,7 +3830,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
3833 inode->i_op = &btrfs_file_inode_operations; 3830 inode->i_op = &btrfs_file_inode_operations;
3834 BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; 3831 BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
3835 } 3832 }
3836 dir->i_sb->s_dirt = 1;
3837 btrfs_update_inode_block_group(trans, inode); 3833 btrfs_update_inode_block_group(trans, inode);
3838 btrfs_update_inode_block_group(trans, dir); 3834 btrfs_update_inode_block_group(trans, dir);
3839out_unlock: 3835out_unlock:
@@ -3880,7 +3876,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
3880 if (err) 3876 if (err)
3881 drop_inode = 1; 3877 drop_inode = 1;
3882 3878
3883 dir->i_sb->s_dirt = 1;
3884 btrfs_update_inode_block_group(trans, dir); 3879 btrfs_update_inode_block_group(trans, dir);
3885 err = btrfs_update_inode(trans, root, inode); 3880 err = btrfs_update_inode(trans, root, inode);
3886 3881
@@ -3962,7 +3957,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
3962 3957
3963 d_instantiate(dentry, inode); 3958 d_instantiate(dentry, inode);
3964 drop_on_err = 0; 3959 drop_on_err = 0;
3965 dir->i_sb->s_dirt = 1;
3966 btrfs_update_inode_block_group(trans, inode); 3960 btrfs_update_inode_block_group(trans, inode);
3967 btrfs_update_inode_block_group(trans, dir); 3961 btrfs_update_inode_block_group(trans, dir);
3968 3962
@@ -4991,7 +4985,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
4991 inode->i_op = &btrfs_file_inode_operations; 4985 inode->i_op = &btrfs_file_inode_operations;
4992 BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; 4986 BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
4993 } 4987 }
4994 dir->i_sb->s_dirt = 1;
4995 btrfs_update_inode_block_group(trans, inode); 4988 btrfs_update_inode_block_group(trans, inode);
4996 btrfs_update_inode_block_group(trans, dir); 4989 btrfs_update_inode_block_group(trans, dir);
4997 if (drop_inode) 4990 if (drop_inode)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 708ac06b953b..9f179d4832d5 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -394,10 +394,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
394 struct btrfs_root *root = btrfs_sb(sb); 394 struct btrfs_root *root = btrfs_sb(sb);
395 int ret; 395 int ret;
396 396
397 if (sb->s_flags & MS_RDONLY)
398 return 0;
399
400 sb->s_dirt = 0;
401 if (!wait) { 397 if (!wait) {
402 filemap_flush(root->fs_info->btree_inode->i_mapping); 398 filemap_flush(root->fs_info->btree_inode->i_mapping);
403 return 0; 399 return 0;
@@ -408,7 +404,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
408 404
409 trans = btrfs_start_transaction(root, 1); 405 trans = btrfs_start_transaction(root, 1);
410 ret = btrfs_commit_transaction(trans, root); 406 ret = btrfs_commit_transaction(trans, root);
411 sb->s_dirt = 0;
412 return ret; 407 return ret;
413} 408}
414 409
@@ -454,11 +449,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
454 return 0; 449 return 0;
455} 450}
456 451
457static void btrfs_write_super(struct super_block *sb)
458{
459 sb->s_dirt = 0;
460}
461
462static int btrfs_test_super(struct super_block *s, void *data) 452static int btrfs_test_super(struct super_block *s, void *data)
463{ 453{
464 struct btrfs_fs_devices *test_fs_devices = data; 454 struct btrfs_fs_devices *test_fs_devices = data;
@@ -689,7 +679,6 @@ static int btrfs_unfreeze(struct super_block *sb)
689static struct super_operations btrfs_super_ops = { 679static struct super_operations btrfs_super_ops = {
690 .delete_inode = btrfs_delete_inode, 680 .delete_inode = btrfs_delete_inode,
691 .put_super = btrfs_put_super, 681 .put_super = btrfs_put_super,
692 .write_super = btrfs_write_super,
693 .sync_fs = btrfs_sync_fs, 682 .sync_fs = btrfs_sync_fs,
694 .show_options = btrfs_show_options, 683 .show_options = btrfs_show_options,
695 .write_inode = btrfs_write_inode, 684 .write_inode = btrfs_write_inode,
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 1e962348d111..431accd475a7 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -354,7 +354,9 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache)
354 /* make sure all pages pinned by operations on behalf of the netfs are 354 /* make sure all pages pinned by operations on behalf of the netfs are
355 * written to disc */ 355 * written to disc */
356 cachefiles_begin_secure(cache, &saved_cred); 356 cachefiles_begin_secure(cache, &saved_cred);
357 ret = fsync_super(cache->mnt->mnt_sb); 357 down_read(&cache->mnt->mnt_sb->s_umount);
358 ret = sync_filesystem(cache->mnt->mnt_sb);
359 up_read(&cache->mnt->mnt_sb->s_umount);
358 cachefiles_end_secure(cache, saved_cred); 360 cachefiles_end_secure(cache, saved_cred);
359 361
360 if (ret == -EIO) 362 if (ret == -EIO)
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 38f71222a552..b7c9d5187a75 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -375,7 +375,6 @@ static int chrdev_open(struct inode *inode, struct file *filp)
375 p = inode->i_cdev; 375 p = inode->i_cdev;
376 if (!p) { 376 if (!p) {
377 inode->i_cdev = p = new; 377 inode->i_cdev = p = new;
378 inode->i_cindex = idx;
379 list_add(&inode->i_devices, &p->list); 378 list_add(&inode->i_devices, &p->list);
380 new = NULL; 379 new = NULL;
381 } else if (!cdev_get(p)) 380 } else if (!cdev_get(p))
@@ -405,6 +404,18 @@ static int chrdev_open(struct inode *inode, struct file *filp)
405 return ret; 404 return ret;
406} 405}
407 406
407int cdev_index(struct inode *inode)
408{
409 int idx;
410 struct kobject *kobj;
411
412 kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
413 if (!kobj)
414 return -1;
415 kobject_put(kobj);
416 return idx;
417}
418
408void cd_forget(struct inode *inode) 419void cd_forget(struct inode *inode)
409{ 420{
410 spin_lock(&cdev_lock); 421 spin_lock(&cdev_lock);
@@ -557,6 +568,7 @@ EXPORT_SYMBOL(cdev_init);
557EXPORT_SYMBOL(cdev_alloc); 568EXPORT_SYMBOL(cdev_alloc);
558EXPORT_SYMBOL(cdev_del); 569EXPORT_SYMBOL(cdev_del);
559EXPORT_SYMBOL(cdev_add); 570EXPORT_SYMBOL(cdev_add);
571EXPORT_SYMBOL(cdev_index);
560EXPORT_SYMBOL(register_chrdev); 572EXPORT_SYMBOL(register_chrdev);
561EXPORT_SYMBOL(unregister_chrdev); 573EXPORT_SYMBOL(unregister_chrdev);
562EXPORT_SYMBOL(directly_mappable_cdev_bdi); 574EXPORT_SYMBOL(directly_mappable_cdev_bdi);
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 83d62759c7c7..3bb11be8b6a8 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -275,7 +275,7 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
275 case -EBUSY: 275 case -EBUSY:
276 /* someone else made a mount here whilst we were busy */ 276 /* someone else made a mount here whilst we were busy */
277 while (d_mountpoint(nd->path.dentry) && 277 while (d_mountpoint(nd->path.dentry) &&
278 follow_down(&nd->path.mnt, &nd->path.dentry)) 278 follow_down(&nd->path))
279 ; 279 ;
280 err = 0; 280 err = 0;
281 default: 281 default:
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 0a10a59b6392..0d92114195ab 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -204,6 +204,9 @@ cifs_put_super(struct super_block *sb)
204 cFYI(1, ("Empty cifs superblock info passed to unmount")); 204 cFYI(1, ("Empty cifs superblock info passed to unmount"));
205 return; 205 return;
206 } 206 }
207
208 lock_kernel();
209
207 rc = cifs_umount(sb, cifs_sb); 210 rc = cifs_umount(sb, cifs_sb);
208 if (rc) 211 if (rc)
209 cERROR(1, ("cifs_umount failed with return code %d", rc)); 212 cERROR(1, ("cifs_umount failed with return code %d", rc));
@@ -216,7 +219,8 @@ cifs_put_super(struct super_block *sb)
216 219
217 unload_nls(cifs_sb->local_nls); 220 unload_nls(cifs_sb->local_nls);
218 kfree(cifs_sb); 221 kfree(cifs_sb);
219 return; 222
223 unlock_kernel();
220} 224}
221 225
222static int 226static int
diff --git a/fs/compat.c b/fs/compat.c
index bb2a9b2e8173..6aefb776dfeb 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -812,10 +812,8 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
812 } 812 }
813 } 813 }
814 814
815 lock_kernel();
816 retval = do_mount((char*)dev_page, dir_page, (char*)type_page, 815 retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
817 flags, (void*)data_page); 816 flags, (void*)data_page);
818 unlock_kernel();
819 817
820 out4: 818 out4:
821 free_page(data_page); 819 free_page(data_page);
diff --git a/fs/dcache.c b/fs/dcache.c
index 75659a6fd1f8..9e5cd3c3a6ba 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1910,7 +1910,7 @@ char *__d_path(const struct path *path, struct path *root,
1910 1910
1911 spin_lock(&vfsmount_lock); 1911 spin_lock(&vfsmount_lock);
1912 prepend(&end, &buflen, "\0", 1); 1912 prepend(&end, &buflen, "\0", 1);
1913 if (!IS_ROOT(dentry) && d_unhashed(dentry) && 1913 if (d_unlinked(dentry) &&
1914 (prepend(&end, &buflen, " (deleted)", 10) != 0)) 1914 (prepend(&end, &buflen, " (deleted)", 10) != 0))
1915 goto Elong; 1915 goto Elong;
1916 1916
@@ -2035,7 +2035,7 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2035 2035
2036 spin_lock(&dcache_lock); 2036 spin_lock(&dcache_lock);
2037 prepend(&end, &buflen, "\0", 1); 2037 prepend(&end, &buflen, "\0", 1);
2038 if (!IS_ROOT(dentry) && d_unhashed(dentry) && 2038 if (d_unlinked(dentry) &&
2039 (prepend(&end, &buflen, "//deleted", 9) != 0)) 2039 (prepend(&end, &buflen, "//deleted", 9) != 0))
2040 goto Elong; 2040 goto Elong;
2041 if (buflen < 1) 2041 if (buflen < 1)
@@ -2097,9 +2097,8 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
2097 read_unlock(&current->fs->lock); 2097 read_unlock(&current->fs->lock);
2098 2098
2099 error = -ENOENT; 2099 error = -ENOENT;
2100 /* Has the current directory has been unlinked? */
2101 spin_lock(&dcache_lock); 2100 spin_lock(&dcache_lock);
2102 if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) { 2101 if (!d_unlinked(pwd.dentry)) {
2103 unsigned long len; 2102 unsigned long len;
2104 struct path tmp = root; 2103 struct path tmp = root;
2105 char * cwd; 2104 char * cwd;
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index fa4c7e7d15d9..12d649602d3a 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -27,6 +27,7 @@
27#include <linux/mount.h> 27#include <linux/mount.h>
28#include <linux/key.h> 28#include <linux/key.h>
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/smp_lock.h>
30#include <linux/file.h> 31#include <linux/file.h>
31#include <linux/crypto.h> 32#include <linux/crypto.h>
32#include "ecryptfs_kernel.h" 33#include "ecryptfs_kernel.h"
@@ -120,9 +121,13 @@ static void ecryptfs_put_super(struct super_block *sb)
120{ 121{
121 struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); 122 struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
122 123
124 lock_kernel();
125
123 ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); 126 ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
124 kmem_cache_free(ecryptfs_sb_info_cache, sb_info); 127 kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
125 ecryptfs_set_superblock_private(sb, NULL); 128 ecryptfs_set_superblock_private(sb, NULL);
129
130 unlock_kernel();
126} 131}
127 132
128/** 133/**
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 9f1985e857e2..8216c5b77b53 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -200,20 +200,21 @@ static const struct export_operations exofs_export_ops;
200/* 200/*
201 * Write the superblock to the OSD 201 * Write the superblock to the OSD
202 */ 202 */
203static void exofs_write_super(struct super_block *sb) 203static int exofs_sync_fs(struct super_block *sb, int wait)
204{ 204{
205 struct exofs_sb_info *sbi; 205 struct exofs_sb_info *sbi;
206 struct exofs_fscb *fscb; 206 struct exofs_fscb *fscb;
207 struct osd_request *or; 207 struct osd_request *or;
208 struct osd_obj_id obj; 208 struct osd_obj_id obj;
209 int ret; 209 int ret = -ENOMEM;
210 210
211 fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL); 211 fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
212 if (!fscb) { 212 if (!fscb) {
213 EXOFS_ERR("exofs_write_super: memory allocation failed.\n"); 213 EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
214 return; 214 return -ENOMEM;
215 } 215 }
216 216
217 lock_super(sb);
217 lock_kernel(); 218 lock_kernel();
218 sbi = sb->s_fs_info; 219 sbi = sb->s_fs_info;
219 fscb->s_nextid = cpu_to_le64(sbi->s_nextid); 220 fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
@@ -246,7 +247,17 @@ out:
246 if (or) 247 if (or)
247 osd_end_request(or); 248 osd_end_request(or);
248 unlock_kernel(); 249 unlock_kernel();
250 unlock_super(sb);
249 kfree(fscb); 251 kfree(fscb);
252 return ret;
253}
254
255static void exofs_write_super(struct super_block *sb)
256{
257 if (!(sb->s_flags & MS_RDONLY))
258 exofs_sync_fs(sb, 1);
259 else
260 sb->s_dirt = 0;
250} 261}
251 262
252/* 263/*
@@ -258,6 +269,11 @@ static void exofs_put_super(struct super_block *sb)
258 int num_pend; 269 int num_pend;
259 struct exofs_sb_info *sbi = sb->s_fs_info; 270 struct exofs_sb_info *sbi = sb->s_fs_info;
260 271
272 lock_kernel();
273
274 if (sb->s_dirt)
275 exofs_write_super(sb);
276
261 /* make sure there are no pending commands */ 277 /* make sure there are no pending commands */
262 for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0; 278 for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
263 num_pend = atomic_read(&sbi->s_curr_pending)) { 279 num_pend = atomic_read(&sbi->s_curr_pending)) {
@@ -271,6 +287,8 @@ static void exofs_put_super(struct super_block *sb)
271 osduld_put_device(sbi->s_dev); 287 osduld_put_device(sbi->s_dev);
272 kfree(sb->s_fs_info); 288 kfree(sb->s_fs_info);
273 sb->s_fs_info = NULL; 289 sb->s_fs_info = NULL;
290
291 unlock_kernel();
274} 292}
275 293
276/* 294/*
@@ -484,6 +502,7 @@ static const struct super_operations exofs_sops = {
484 .delete_inode = exofs_delete_inode, 502 .delete_inode = exofs_delete_inode,
485 .put_super = exofs_put_super, 503 .put_super = exofs_put_super,
486 .write_super = exofs_write_super, 504 .write_super = exofs_write_super,
505 .sync_fs = exofs_sync_fs,
487 .statfs = exofs_statfs, 506 .statfs = exofs_statfs,
488}; 507};
489 508
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile
index e0b2b43c1fdb..f42af45cfd88 100644
--- a/fs/ext2/Makefile
+++ b/fs/ext2/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_EXT2_FS) += ext2.o 5obj-$(CONFIG_EXT2_FS) += ext2.o
6 6
7ext2-y := balloc.o dir.o file.o fsync.o ialloc.o inode.o \ 7ext2-y := balloc.o dir.o file.o ialloc.o inode.o \
8 ioctl.o namei.o super.o symlink.o 8 ioctl.o namei.o super.o symlink.o
9 9
10ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o 10ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 2999d72153b7..003500498c22 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -720,5 +720,5 @@ const struct file_operations ext2_dir_operations = {
720#ifdef CONFIG_COMPAT 720#ifdef CONFIG_COMPAT
721 .compat_ioctl = ext2_compat_ioctl, 721 .compat_ioctl = ext2_compat_ioctl,
722#endif 722#endif
723 .fsync = ext2_sync_file, 723 .fsync = simple_fsync,
724}; 724};
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 3203042b36ef..b2bbf45039e0 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -113,9 +113,6 @@ extern int ext2_empty_dir (struct inode *);
113extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **); 113extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
114extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *); 114extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
115 115
116/* fsync.c */
117extern int ext2_sync_file (struct file *, struct dentry *, int);
118
119/* ialloc.c */ 116/* ialloc.c */
120extern struct inode * ext2_new_inode (struct inode *, int); 117extern struct inode * ext2_new_inode (struct inode *, int);
121extern void ext2_free_inode (struct inode *); 118extern void ext2_free_inode (struct inode *);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 45ed07122182..2b9e47dc9222 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -55,7 +55,7 @@ const struct file_operations ext2_file_operations = {
55 .mmap = generic_file_mmap, 55 .mmap = generic_file_mmap,
56 .open = generic_file_open, 56 .open = generic_file_open,
57 .release = ext2_release_file, 57 .release = ext2_release_file,
58 .fsync = ext2_sync_file, 58 .fsync = simple_fsync,
59 .splice_read = generic_file_splice_read, 59 .splice_read = generic_file_splice_read,
60 .splice_write = generic_file_splice_write, 60 .splice_write = generic_file_splice_write,
61}; 61};
@@ -72,7 +72,7 @@ const struct file_operations ext2_xip_file_operations = {
72 .mmap = xip_file_mmap, 72 .mmap = xip_file_mmap,
73 .open = generic_file_open, 73 .open = generic_file_open,
74 .release = ext2_release_file, 74 .release = ext2_release_file,
75 .fsync = ext2_sync_file, 75 .fsync = simple_fsync,
76}; 76};
77#endif 77#endif
78 78
diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c
deleted file mode 100644
index fc66c93fcb5c..000000000000
--- a/fs/ext2/fsync.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * linux/fs/ext2/fsync.c
3 *
4 * Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk)
5 * from
6 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
7 * Laboratoire MASI - Institut Blaise Pascal
8 * Universite Pierre et Marie Curie (Paris VI)
9 * from
10 * linux/fs/minix/truncate.c Copyright (C) 1991, 1992 Linus Torvalds
11 *
12 * ext2fs fsync primitive
13 *
14 * Big-endian to little-endian byte-swapping/bitmaps by
15 * David S. Miller (davem@caip.rutgers.edu), 1995
16 *
17 * Removed unnecessary code duplication for little endian machines
18 * and excessive __inline__s.
19 * Andi Kleen, 1997
20 *
21 * Major simplications and cleanup - we only need to do the metadata, because
22 * we can depend on generic_block_fdatasync() to sync the data blocks.
23 */
24
25#include "ext2.h"
26#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
27
28
29/*
30 * File may be NULL when we are called. Perhaps we shouldn't
31 * even pass file to fsync ?
32 */
33
34int ext2_sync_file(struct file *file, struct dentry *dentry, int datasync)
35{
36 struct inode *inode = dentry->d_inode;
37 int err;
38 int ret;
39
40 ret = sync_mapping_buffers(inode->i_mapping);
41 if (!(inode->i_state & I_DIRTY))
42 return ret;
43 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
44 return ret;
45
46 err = ext2_sync_inode(inode);
47 if (ret == 0)
48 ret = err;
49 return ret;
50}
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index acf678831103..29ed682061f6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -41,8 +41,6 @@ MODULE_AUTHOR("Remy Card and others");
41MODULE_DESCRIPTION("Second Extended Filesystem"); 41MODULE_DESCRIPTION("Second Extended Filesystem");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43 43
44static int ext2_update_inode(struct inode * inode, int do_sync);
45
46/* 44/*
47 * Test whether an inode is a fast symlink. 45 * Test whether an inode is a fast symlink.
48 */ 46 */
@@ -66,7 +64,7 @@ void ext2_delete_inode (struct inode * inode)
66 goto no_delete; 64 goto no_delete;
67 EXT2_I(inode)->i_dtime = get_seconds(); 65 EXT2_I(inode)->i_dtime = get_seconds();
68 mark_inode_dirty(inode); 66 mark_inode_dirty(inode);
69 ext2_update_inode(inode, inode_needs_sync(inode)); 67 ext2_write_inode(inode, inode_needs_sync(inode));
70 68
71 inode->i_size = 0; 69 inode->i_size = 0;
72 if (inode->i_blocks) 70 if (inode->i_blocks)
@@ -1337,7 +1335,7 @@ bad_inode:
1337 return ERR_PTR(ret); 1335 return ERR_PTR(ret);
1338} 1336}
1339 1337
1340static int ext2_update_inode(struct inode * inode, int do_sync) 1338int ext2_write_inode(struct inode *inode, int do_sync)
1341{ 1339{
1342 struct ext2_inode_info *ei = EXT2_I(inode); 1340 struct ext2_inode_info *ei = EXT2_I(inode);
1343 struct super_block *sb = inode->i_sb; 1341 struct super_block *sb = inode->i_sb;
@@ -1442,11 +1440,6 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
1442 return err; 1440 return err;
1443} 1441}
1444 1442
1445int ext2_write_inode(struct inode *inode, int wait)
1446{
1447 return ext2_update_inode(inode, wait);
1448}
1449
1450int ext2_sync_inode(struct inode *inode) 1443int ext2_sync_inode(struct inode *inode)
1451{ 1444{
1452 struct writeback_control wbc = { 1445 struct writeback_control wbc = {
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index e3c748faf2db..458999638c3d 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -42,6 +42,7 @@ static void ext2_sync_super(struct super_block *sb,
42 struct ext2_super_block *es); 42 struct ext2_super_block *es);
43static int ext2_remount (struct super_block * sb, int * flags, char * data); 43static int ext2_remount (struct super_block * sb, int * flags, char * data);
44static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); 44static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
45static int ext2_sync_fs(struct super_block *sb, int wait);
45 46
46void ext2_error (struct super_block * sb, const char * function, 47void ext2_error (struct super_block * sb, const char * function,
47 const char * fmt, ...) 48 const char * fmt, ...)
@@ -114,6 +115,11 @@ static void ext2_put_super (struct super_block * sb)
114 int i; 115 int i;
115 struct ext2_sb_info *sbi = EXT2_SB(sb); 116 struct ext2_sb_info *sbi = EXT2_SB(sb);
116 117
118 lock_kernel();
119
120 if (sb->s_dirt)
121 ext2_write_super(sb);
122
117 ext2_xattr_put_super(sb); 123 ext2_xattr_put_super(sb);
118 if (!(sb->s_flags & MS_RDONLY)) { 124 if (!(sb->s_flags & MS_RDONLY)) {
119 struct ext2_super_block *es = sbi->s_es; 125 struct ext2_super_block *es = sbi->s_es;
@@ -135,7 +141,7 @@ static void ext2_put_super (struct super_block * sb)
135 kfree(sbi->s_blockgroup_lock); 141 kfree(sbi->s_blockgroup_lock);
136 kfree(sbi); 142 kfree(sbi);
137 143
138 return; 144 unlock_kernel();
139} 145}
140 146
141static struct kmem_cache * ext2_inode_cachep; 147static struct kmem_cache * ext2_inode_cachep;
@@ -304,6 +310,7 @@ static const struct super_operations ext2_sops = {
304 .delete_inode = ext2_delete_inode, 310 .delete_inode = ext2_delete_inode,
305 .put_super = ext2_put_super, 311 .put_super = ext2_put_super,
306 .write_super = ext2_write_super, 312 .write_super = ext2_write_super,
313 .sync_fs = ext2_sync_fs,
307 .statfs = ext2_statfs, 314 .statfs = ext2_statfs,
308 .remount_fs = ext2_remount, 315 .remount_fs = ext2_remount,
309 .clear_inode = ext2_clear_inode, 316 .clear_inode = ext2_clear_inode,
@@ -1127,25 +1134,36 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es)
1127 * set s_state to EXT2_VALID_FS after some corrections. 1134 * set s_state to EXT2_VALID_FS after some corrections.
1128 */ 1135 */
1129 1136
1130void ext2_write_super (struct super_block * sb) 1137static int ext2_sync_fs(struct super_block *sb, int wait)
1131{ 1138{
1132 struct ext2_super_block * es; 1139 struct ext2_super_block *es = EXT2_SB(sb)->s_es;
1140
1133 lock_kernel(); 1141 lock_kernel();
1134 if (!(sb->s_flags & MS_RDONLY)) { 1142 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {
1135 es = EXT2_SB(sb)->s_es; 1143 ext2_debug("setting valid to 0\n");
1136 1144 es->s_state &= cpu_to_le16(~EXT2_VALID_FS);
1137 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { 1145 es->s_free_blocks_count =
1138 ext2_debug ("setting valid to 0\n"); 1146 cpu_to_le32(ext2_count_free_blocks(sb));
1139 es->s_state &= cpu_to_le16(~EXT2_VALID_FS); 1147 es->s_free_inodes_count =
1140 es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); 1148 cpu_to_le32(ext2_count_free_inodes(sb));
1141 es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); 1149 es->s_mtime = cpu_to_le32(get_seconds());
1142 es->s_mtime = cpu_to_le32(get_seconds()); 1150 ext2_sync_super(sb, es);
1143 ext2_sync_super(sb, es); 1151 } else {
1144 } else 1152 ext2_commit_super(sb, es);
1145 ext2_commit_super (sb, es);
1146 } 1153 }
1147 sb->s_dirt = 0; 1154 sb->s_dirt = 0;
1148 unlock_kernel(); 1155 unlock_kernel();
1156
1157 return 0;
1158}
1159
1160
1161void ext2_write_super(struct super_block *sb)
1162{
1163 if (!(sb->s_flags & MS_RDONLY))
1164 ext2_sync_fs(sb, 1);
1165 else
1166 sb->s_dirt = 0;
1149} 1167}
1150 1168
1151static int ext2_remount (struct super_block * sb, int * flags, char * data) 1169static int ext2_remount (struct super_block * sb, int * flags, char * data)
@@ -1157,6 +1175,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1157 unsigned long old_sb_flags; 1175 unsigned long old_sb_flags;
1158 int err; 1176 int err;
1159 1177
1178 lock_kernel();
1179
1160 /* Store the old options */ 1180 /* Store the old options */
1161 old_sb_flags = sb->s_flags; 1181 old_sb_flags = sb->s_flags;
1162 old_opts.s_mount_opt = sbi->s_mount_opt; 1182 old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -1192,12 +1212,16 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1192 sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; 1212 sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
1193 sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; 1213 sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
1194 } 1214 }
1195 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1215 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
1216 unlock_kernel();
1196 return 0; 1217 return 0;
1218 }
1197 if (*flags & MS_RDONLY) { 1219 if (*flags & MS_RDONLY) {
1198 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || 1220 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
1199 !(sbi->s_mount_state & EXT2_VALID_FS)) 1221 !(sbi->s_mount_state & EXT2_VALID_FS)) {
1222 unlock_kernel();
1200 return 0; 1223 return 0;
1224 }
1201 /* 1225 /*
1202 * OK, we are remounting a valid rw partition rdonly, so set 1226 * OK, we are remounting a valid rw partition rdonly, so set
1203 * the rdonly flag and then mark the partition as valid again. 1227 * the rdonly flag and then mark the partition as valid again.
@@ -1224,12 +1248,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1224 sb->s_flags &= ~MS_RDONLY; 1248 sb->s_flags &= ~MS_RDONLY;
1225 } 1249 }
1226 ext2_sync_super(sb, es); 1250 ext2_sync_super(sb, es);
1251 unlock_kernel();
1227 return 0; 1252 return 0;
1228restore_opts: 1253restore_opts:
1229 sbi->s_mount_opt = old_opts.s_mount_opt; 1254 sbi->s_mount_opt = old_opts.s_mount_opt;
1230 sbi->s_resuid = old_opts.s_resuid; 1255 sbi->s_resuid = old_opts.s_resuid;
1231 sbi->s_resgid = old_opts.s_resgid; 1256 sbi->s_resgid = old_opts.s_resgid;
1232 sb->s_flags = old_sb_flags; 1257 sb->s_flags = old_sb_flags;
1258 unlock_kernel();
1233 return err; 1259 return err;
1234} 1260}
1235 1261
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 225202db8974..27967f92e820 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -649,7 +649,7 @@ do_more:
649 count = overflow; 649 count = overflow;
650 goto do_more; 650 goto do_more;
651 } 651 }
652 sb->s_dirt = 1; 652
653error_return: 653error_return:
654 brelse(bitmap_bh); 654 brelse(bitmap_bh);
655 ext3_std_error(sb, err); 655 ext3_std_error(sb, err);
@@ -1708,7 +1708,6 @@ allocated:
1708 if (!fatal) 1708 if (!fatal)
1709 fatal = err; 1709 fatal = err;
1710 1710
1711 sb->s_dirt = 1;
1712 if (fatal) 1711 if (fatal)
1713 goto out; 1712 goto out;
1714 1713
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index dd13d60d524b..b39991285136 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -181,7 +181,7 @@ void ext3_free_inode (handle_t *handle, struct inode * inode)
181 err = ext3_journal_dirty_metadata(handle, bitmap_bh); 181 err = ext3_journal_dirty_metadata(handle, bitmap_bh);
182 if (!fatal) 182 if (!fatal)
183 fatal = err; 183 fatal = err;
184 sb->s_dirt = 1; 184
185error_return: 185error_return:
186 brelse(bitmap_bh); 186 brelse(bitmap_bh);
187 ext3_std_error(sb, fatal); 187 ext3_std_error(sb, fatal);
@@ -537,7 +537,6 @@ got:
537 percpu_counter_dec(&sbi->s_freeinodes_counter); 537 percpu_counter_dec(&sbi->s_freeinodes_counter);
538 if (S_ISDIR(mode)) 538 if (S_ISDIR(mode))
539 percpu_counter_inc(&sbi->s_dirs_counter); 539 percpu_counter_inc(&sbi->s_dirs_counter);
540 sb->s_dirt = 1;
541 540
542 inode->i_uid = current_fsuid(); 541 inode->i_uid = current_fsuid();
543 if (test_opt (sb, GRPID)) 542 if (test_opt (sb, GRPID))
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index fcfa24361856..b0248c6d5d4c 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2960,7 +2960,6 @@ static int ext3_do_update_inode(handle_t *handle,
2960 ext3_update_dynamic_rev(sb); 2960 ext3_update_dynamic_rev(sb);
2961 EXT3_SET_RO_COMPAT_FEATURE(sb, 2961 EXT3_SET_RO_COMPAT_FEATURE(sb,
2962 EXT3_FEATURE_RO_COMPAT_LARGE_FILE); 2962 EXT3_FEATURE_RO_COMPAT_LARGE_FILE);
2963 sb->s_dirt = 1;
2964 handle->h_sync = 1; 2963 handle->h_sync = 1;
2965 err = ext3_journal_dirty_metadata(handle, 2964 err = ext3_journal_dirty_metadata(handle,
2966 EXT3_SB(sb)->s_sbh); 2965 EXT3_SB(sb)->s_sbh);
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 78fdf3836370..8a0b26340b54 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -934,7 +934,6 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
934 EXT3_INODES_PER_GROUP(sb)); 934 EXT3_INODES_PER_GROUP(sb));
935 935
936 ext3_journal_dirty_metadata(handle, sbi->s_sbh); 936 ext3_journal_dirty_metadata(handle, sbi->s_sbh);
937 sb->s_dirt = 1;
938 937
939exit_journal: 938exit_journal:
940 unlock_super(sb); 939 unlock_super(sb);
@@ -1066,7 +1065,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
1066 } 1065 }
1067 es->s_blocks_count = cpu_to_le32(o_blocks_count + add); 1066 es->s_blocks_count = cpu_to_le32(o_blocks_count + add);
1068 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); 1067 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
1069 sb->s_dirt = 1;
1070 unlock_super(sb); 1068 unlock_super(sb);
1071 ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count, 1069 ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count,
1072 o_blocks_count + add); 1070 o_blocks_count + add);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 3c70d52afb10..26aa64dee6aa 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -67,7 +67,6 @@ static const char *ext3_decode_error(struct super_block * sb, int errno,
67static int ext3_remount (struct super_block * sb, int * flags, char * data); 67static int ext3_remount (struct super_block * sb, int * flags, char * data);
68static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf); 68static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf);
69static int ext3_unfreeze(struct super_block *sb); 69static int ext3_unfreeze(struct super_block *sb);
70static void ext3_write_super (struct super_block * sb);
71static int ext3_freeze(struct super_block *sb); 70static int ext3_freeze(struct super_block *sb);
72 71
73/* 72/*
@@ -399,6 +398,8 @@ static void ext3_put_super (struct super_block * sb)
399 struct ext3_super_block *es = sbi->s_es; 398 struct ext3_super_block *es = sbi->s_es;
400 int i, err; 399 int i, err;
401 400
401 lock_kernel();
402
402 ext3_xattr_put_super(sb); 403 ext3_xattr_put_super(sb);
403 err = journal_destroy(sbi->s_journal); 404 err = journal_destroy(sbi->s_journal);
404 sbi->s_journal = NULL; 405 sbi->s_journal = NULL;
@@ -447,7 +448,8 @@ static void ext3_put_super (struct super_block * sb)
447 sb->s_fs_info = NULL; 448 sb->s_fs_info = NULL;
448 kfree(sbi->s_blockgroup_lock); 449 kfree(sbi->s_blockgroup_lock);
449 kfree(sbi); 450 kfree(sbi);
450 return; 451
452 unlock_kernel();
451} 453}
452 454
453static struct kmem_cache *ext3_inode_cachep; 455static struct kmem_cache *ext3_inode_cachep;
@@ -761,7 +763,6 @@ static const struct super_operations ext3_sops = {
761 .dirty_inode = ext3_dirty_inode, 763 .dirty_inode = ext3_dirty_inode,
762 .delete_inode = ext3_delete_inode, 764 .delete_inode = ext3_delete_inode,
763 .put_super = ext3_put_super, 765 .put_super = ext3_put_super,
764 .write_super = ext3_write_super,
765 .sync_fs = ext3_sync_fs, 766 .sync_fs = ext3_sync_fs,
766 .freeze_fs = ext3_freeze, 767 .freeze_fs = ext3_freeze,
767 .unfreeze_fs = ext3_unfreeze, 768 .unfreeze_fs = ext3_unfreeze,
@@ -1785,7 +1786,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1785#else 1786#else
1786 es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); 1787 es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
1787#endif 1788#endif
1788 sb->s_dirt = 1;
1789 } 1789 }
1790 1790
1791 if (sbi->s_blocks_per_group > blocksize * 8) { 1791 if (sbi->s_blocks_per_group > blocksize * 8) {
@@ -2265,7 +2265,6 @@ static int ext3_load_journal(struct super_block *sb,
2265 if (journal_devnum && 2265 if (journal_devnum &&
2266 journal_devnum != le32_to_cpu(es->s_journal_dev)) { 2266 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
2267 es->s_journal_dev = cpu_to_le32(journal_devnum); 2267 es->s_journal_dev = cpu_to_le32(journal_devnum);
2268 sb->s_dirt = 1;
2269 2268
2270 /* Make sure we flush the recovery flag to disk. */ 2269 /* Make sure we flush the recovery flag to disk. */
2271 ext3_commit_super(sb, es, 1); 2270 ext3_commit_super(sb, es, 1);
@@ -2308,7 +2307,6 @@ static int ext3_create_journal(struct super_block * sb,
2308 EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL); 2307 EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL);
2309 2308
2310 es->s_journal_inum = cpu_to_le32(journal_inum); 2309 es->s_journal_inum = cpu_to_le32(journal_inum);
2311 sb->s_dirt = 1;
2312 2310
2313 /* Make sure we flush the recovery flag to disk. */ 2311 /* Make sure we flush the recovery flag to disk. */
2314 ext3_commit_super(sb, es, 1); 2312 ext3_commit_super(sb, es, 1);
@@ -2354,7 +2352,6 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
2354 if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && 2352 if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
2355 sb->s_flags & MS_RDONLY) { 2353 sb->s_flags & MS_RDONLY) {
2356 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); 2354 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
2357 sb->s_dirt = 0;
2358 ext3_commit_super(sb, es, 1); 2355 ext3_commit_super(sb, es, 1);
2359 } 2356 }
2360 unlock_super(sb); 2357 unlock_super(sb);
@@ -2413,29 +2410,14 @@ int ext3_force_commit(struct super_block *sb)
2413 return 0; 2410 return 0;
2414 2411
2415 journal = EXT3_SB(sb)->s_journal; 2412 journal = EXT3_SB(sb)->s_journal;
2416 sb->s_dirt = 0;
2417 ret = ext3_journal_force_commit(journal); 2413 ret = ext3_journal_force_commit(journal);
2418 return ret; 2414 return ret;
2419} 2415}
2420 2416
2421/*
2422 * Ext3 always journals updates to the superblock itself, so we don't
2423 * have to propagate any other updates to the superblock on disk at this
2424 * point. (We can probably nuke this function altogether, and remove
2425 * any mention to sb->s_dirt in all of fs/ext3; eventual cleanup...)
2426 */
2427static void ext3_write_super (struct super_block * sb)
2428{
2429 if (mutex_trylock(&sb->s_lock) != 0)
2430 BUG();
2431 sb->s_dirt = 0;
2432}
2433
2434static int ext3_sync_fs(struct super_block *sb, int wait) 2417static int ext3_sync_fs(struct super_block *sb, int wait)
2435{ 2418{
2436 tid_t target; 2419 tid_t target;
2437 2420
2438 sb->s_dirt = 0;
2439 if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) { 2421 if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
2440 if (wait) 2422 if (wait)
2441 log_wait_commit(EXT3_SB(sb)->s_journal, target); 2423 log_wait_commit(EXT3_SB(sb)->s_journal, target);
@@ -2451,7 +2433,6 @@ static int ext3_freeze(struct super_block *sb)
2451{ 2433{
2452 int error = 0; 2434 int error = 0;
2453 journal_t *journal; 2435 journal_t *journal;
2454 sb->s_dirt = 0;
2455 2436
2456 if (!(sb->s_flags & MS_RDONLY)) { 2437 if (!(sb->s_flags & MS_RDONLY)) {
2457 journal = EXT3_SB(sb)->s_journal; 2438 journal = EXT3_SB(sb)->s_journal;
@@ -2509,7 +2490,10 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2509 int i; 2490 int i;
2510#endif 2491#endif
2511 2492
2493 lock_kernel();
2494
2512 /* Store the original options */ 2495 /* Store the original options */
2496 lock_super(sb);
2513 old_sb_flags = sb->s_flags; 2497 old_sb_flags = sb->s_flags;
2514 old_opts.s_mount_opt = sbi->s_mount_opt; 2498 old_opts.s_mount_opt = sbi->s_mount_opt;
2515 old_opts.s_resuid = sbi->s_resuid; 2499 old_opts.s_resuid = sbi->s_resuid;
@@ -2617,6 +2601,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2617 old_opts.s_qf_names[i] != sbi->s_qf_names[i]) 2601 old_opts.s_qf_names[i] != sbi->s_qf_names[i])
2618 kfree(old_opts.s_qf_names[i]); 2602 kfree(old_opts.s_qf_names[i]);
2619#endif 2603#endif
2604 unlock_super(sb);
2605 unlock_kernel();
2620 return 0; 2606 return 0;
2621restore_opts: 2607restore_opts:
2622 sb->s_flags = old_sb_flags; 2608 sb->s_flags = old_sb_flags;
@@ -2633,6 +2619,8 @@ restore_opts:
2633 sbi->s_qf_names[i] = old_opts.s_qf_names[i]; 2619 sbi->s_qf_names[i] = old_opts.s_qf_names[i];
2634 } 2620 }
2635#endif 2621#endif
2622 unlock_super(sb);
2623 unlock_kernel();
2636 return err; 2624 return err;
2637} 2625}
2638 2626
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 83b7be849bd5..545e37c4b91e 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -463,7 +463,6 @@ static void ext3_xattr_update_super_block(handle_t *handle,
463 463
464 if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { 464 if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) {
465 EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR); 465 EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR);
466 sb->s_dirt = 1;
467 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); 466 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
468 } 467 }
469} 468}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index f016707597a7..012c4251397e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -576,6 +576,11 @@ static void ext4_put_super(struct super_block *sb)
576 struct ext4_super_block *es = sbi->s_es; 576 struct ext4_super_block *es = sbi->s_es;
577 int i, err; 577 int i, err;
578 578
579 lock_super(sb);
580 lock_kernel();
581 if (sb->s_dirt)
582 ext4_commit_super(sb, 1);
583
579 ext4_release_system_zone(sb); 584 ext4_release_system_zone(sb);
580 ext4_mb_release(sb); 585 ext4_mb_release(sb);
581 ext4_ext_release(sb); 586 ext4_ext_release(sb);
@@ -642,8 +647,6 @@ static void ext4_put_super(struct super_block *sb)
642 unlock_super(sb); 647 unlock_super(sb);
643 kobject_put(&sbi->s_kobj); 648 kobject_put(&sbi->s_kobj);
644 wait_for_completion(&sbi->s_kobj_unregister); 649 wait_for_completion(&sbi->s_kobj_unregister);
645 lock_super(sb);
646 lock_kernel();
647 kfree(sbi->s_blockgroup_lock); 650 kfree(sbi->s_blockgroup_lock);
648 kfree(sbi); 651 kfree(sbi);
649} 652}
@@ -3333,7 +3336,9 @@ int ext4_force_commit(struct super_block *sb)
3333 3336
3334static void ext4_write_super(struct super_block *sb) 3337static void ext4_write_super(struct super_block *sb)
3335{ 3338{
3339 lock_super(sb);
3336 ext4_commit_super(sb, 1); 3340 ext4_commit_super(sb, 1);
3341 unlock_super(sb);
3337} 3342}
3338 3343
3339static int ext4_sync_fs(struct super_block *sb, int wait) 3344static int ext4_sync_fs(struct super_block *sb, int wait)
@@ -3417,7 +3422,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3417 int i; 3422 int i;
3418#endif 3423#endif
3419 3424
3425 lock_kernel();
3426
3420 /* Store the original options */ 3427 /* Store the original options */
3428 lock_super(sb);
3421 old_sb_flags = sb->s_flags; 3429 old_sb_flags = sb->s_flags;
3422 old_opts.s_mount_opt = sbi->s_mount_opt; 3430 old_opts.s_mount_opt = sbi->s_mount_opt;
3423 old_opts.s_resuid = sbi->s_resuid; 3431 old_opts.s_resuid = sbi->s_resuid;
@@ -3551,6 +3559,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3551 old_opts.s_qf_names[i] != sbi->s_qf_names[i]) 3559 old_opts.s_qf_names[i] != sbi->s_qf_names[i])
3552 kfree(old_opts.s_qf_names[i]); 3560 kfree(old_opts.s_qf_names[i]);
3553#endif 3561#endif
3562 unlock_super(sb);
3563 unlock_kernel();
3554 return 0; 3564 return 0;
3555 3565
3556restore_opts: 3566restore_opts:
@@ -3570,6 +3580,8 @@ restore_opts:
3570 sbi->s_qf_names[i] = old_opts.s_qf_names[i]; 3580 sbi->s_qf_names[i] = old_opts.s_qf_names[i];
3571 } 3581 }
3572#endif 3582#endif
3583 unlock_super(sb);
3584 unlock_kernel();
3573 return err; 3585 return err;
3574} 3586}
3575 3587
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 3a7f603b6982..f3500294eec5 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -840,7 +840,7 @@ const struct file_operations fat_dir_operations = {
840#ifdef CONFIG_COMPAT 840#ifdef CONFIG_COMPAT
841 .compat_ioctl = fat_compat_dir_ioctl, 841 .compat_ioctl = fat_compat_dir_ioctl,
842#endif 842#endif
843 .fsync = file_fsync, 843 .fsync = fat_file_fsync,
844}; 844};
845 845
846static int fat_get_short_entry(struct inode *dir, loff_t *pos, 846static int fat_get_short_entry(struct inode *dir, loff_t *pos,
@@ -967,7 +967,7 @@ static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
967 de++; 967 de++;
968 nr_slots--; 968 nr_slots--;
969 } 969 }
970 mark_buffer_dirty(bh); 970 mark_buffer_dirty_inode(bh, dir);
971 if (IS_DIRSYNC(dir)) 971 if (IS_DIRSYNC(dir))
972 err = sync_dirty_buffer(bh); 972 err = sync_dirty_buffer(bh);
973 brelse(bh); 973 brelse(bh);
@@ -1001,7 +1001,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
1001 de--; 1001 de--;
1002 nr_slots--; 1002 nr_slots--;
1003 } 1003 }
1004 mark_buffer_dirty(bh); 1004 mark_buffer_dirty_inode(bh, dir);
1005 if (IS_DIRSYNC(dir)) 1005 if (IS_DIRSYNC(dir))
1006 err = sync_dirty_buffer(bh); 1006 err = sync_dirty_buffer(bh);
1007 brelse(bh); 1007 brelse(bh);
@@ -1051,7 +1051,7 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
1051 } 1051 }
1052 memset(bhs[n]->b_data, 0, sb->s_blocksize); 1052 memset(bhs[n]->b_data, 0, sb->s_blocksize);
1053 set_buffer_uptodate(bhs[n]); 1053 set_buffer_uptodate(bhs[n]);
1054 mark_buffer_dirty(bhs[n]); 1054 mark_buffer_dirty_inode(bhs[n], dir);
1055 1055
1056 n++; 1056 n++;
1057 blknr++; 1057 blknr++;
@@ -1131,7 +1131,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec *ts)
1131 de[0].size = de[1].size = 0; 1131 de[0].size = de[1].size = 0;
1132 memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); 1132 memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
1133 set_buffer_uptodate(bhs[0]); 1133 set_buffer_uptodate(bhs[0]);
1134 mark_buffer_dirty(bhs[0]); 1134 mark_buffer_dirty_inode(bhs[0], dir);
1135 1135
1136 err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); 1136 err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
1137 if (err) 1137 if (err)
@@ -1193,7 +1193,7 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
1193 slots += copy; 1193 slots += copy;
1194 size -= copy; 1194 size -= copy;
1195 set_buffer_uptodate(bhs[n]); 1195 set_buffer_uptodate(bhs[n]);
1196 mark_buffer_dirty(bhs[n]); 1196 mark_buffer_dirty_inode(bhs[n], dir);
1197 if (!size) 1197 if (!size)
1198 break; 1198 break;
1199 n++; 1199 n++;
@@ -1293,7 +1293,7 @@ found:
1293 for (i = 0; i < long_bhs; i++) { 1293 for (i = 0; i < long_bhs; i++) {
1294 int copy = min_t(int, sb->s_blocksize - offset, size); 1294 int copy = min_t(int, sb->s_blocksize - offset, size);
1295 memcpy(bhs[i]->b_data + offset, slots, copy); 1295 memcpy(bhs[i]->b_data + offset, slots, copy);
1296 mark_buffer_dirty(bhs[i]); 1296 mark_buffer_dirty_inode(bhs[i], dir);
1297 offset = 0; 1297 offset = 0;
1298 slots += copy; 1298 slots += copy;
1299 size -= copy; 1299 size -= copy;
@@ -1304,7 +1304,7 @@ found:
1304 /* Fill the short name slot. */ 1304 /* Fill the short name slot. */
1305 int copy = min_t(int, sb->s_blocksize - offset, size); 1305 int copy = min_t(int, sb->s_blocksize - offset, size);
1306 memcpy(bhs[i]->b_data + offset, slots, copy); 1306 memcpy(bhs[i]->b_data + offset, slots, copy);
1307 mark_buffer_dirty(bhs[i]); 1307 mark_buffer_dirty_inode(bhs[i], dir);
1308 if (IS_DIRSYNC(dir)) 1308 if (IS_DIRSYNC(dir))
1309 err = sync_dirty_buffer(bhs[i]); 1309 err = sync_dirty_buffer(bhs[i]);
1310 } 1310 }
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index ea440d65819c..e4d88527b5dd 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -74,6 +74,7 @@ struct msdos_sb_info {
74 74
75 int fatent_shift; 75 int fatent_shift;
76 struct fatent_operations *fatent_ops; 76 struct fatent_operations *fatent_ops;
77 struct inode *fat_inode;
77 78
78 spinlock_t inode_hash_lock; 79 spinlock_t inode_hash_lock;
79 struct hlist_head inode_hashtable[FAT_HASH_SIZE]; 80 struct hlist_head inode_hashtable[FAT_HASH_SIZE];
@@ -251,6 +252,7 @@ struct fat_entry {
251 } u; 252 } u;
252 int nr_bhs; 253 int nr_bhs;
253 struct buffer_head *bhs[2]; 254 struct buffer_head *bhs[2];
255 struct inode *fat_inode;
254}; 256};
255 257
256static inline void fatent_init(struct fat_entry *fatent) 258static inline void fatent_init(struct fat_entry *fatent)
@@ -259,6 +261,7 @@ static inline void fatent_init(struct fat_entry *fatent)
259 fatent->entry = 0; 261 fatent->entry = 0;
260 fatent->u.ent32_p = NULL; 262 fatent->u.ent32_p = NULL;
261 fatent->bhs[0] = fatent->bhs[1] = NULL; 263 fatent->bhs[0] = fatent->bhs[1] = NULL;
264 fatent->fat_inode = NULL;
262} 265}
263 266
264static inline void fatent_set_entry(struct fat_entry *fatent, int entry) 267static inline void fatent_set_entry(struct fat_entry *fatent, int entry)
@@ -275,6 +278,7 @@ static inline void fatent_brelse(struct fat_entry *fatent)
275 brelse(fatent->bhs[i]); 278 brelse(fatent->bhs[i]);
276 fatent->nr_bhs = 0; 279 fatent->nr_bhs = 0;
277 fatent->bhs[0] = fatent->bhs[1] = NULL; 280 fatent->bhs[0] = fatent->bhs[1] = NULL;
281 fatent->fat_inode = NULL;
278} 282}
279 283
280extern void fat_ent_access_init(struct super_block *sb); 284extern void fat_ent_access_init(struct super_block *sb);
@@ -296,6 +300,8 @@ extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
296extern void fat_truncate(struct inode *inode); 300extern void fat_truncate(struct inode *inode);
297extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, 301extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
298 struct kstat *stat); 302 struct kstat *stat);
303extern int fat_file_fsync(struct file *file, struct dentry *dentry,
304 int datasync);
299 305
300/* fat/inode.c */ 306/* fat/inode.c */
301extern void fat_attach(struct inode *inode, loff_t i_pos); 307extern void fat_attach(struct inode *inode, loff_t i_pos);
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index da6eea47872f..618f5305c2e4 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -73,6 +73,8 @@ static int fat12_ent_bread(struct super_block *sb, struct fat_entry *fatent,
73 struct buffer_head **bhs = fatent->bhs; 73 struct buffer_head **bhs = fatent->bhs;
74 74
75 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start); 75 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
76 fatent->fat_inode = MSDOS_SB(sb)->fat_inode;
77
76 bhs[0] = sb_bread(sb, blocknr); 78 bhs[0] = sb_bread(sb, blocknr);
77 if (!bhs[0]) 79 if (!bhs[0])
78 goto err; 80 goto err;
@@ -103,6 +105,7 @@ static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent,
103 struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops; 105 struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
104 106
105 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start); 107 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
108 fatent->fat_inode = MSDOS_SB(sb)->fat_inode;
106 fatent->bhs[0] = sb_bread(sb, blocknr); 109 fatent->bhs[0] = sb_bread(sb, blocknr);
107 if (!fatent->bhs[0]) { 110 if (!fatent->bhs[0]) {
108 printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", 111 printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n",
@@ -167,9 +170,9 @@ static void fat12_ent_put(struct fat_entry *fatent, int new)
167 } 170 }
168 spin_unlock(&fat12_entry_lock); 171 spin_unlock(&fat12_entry_lock);
169 172
170 mark_buffer_dirty(fatent->bhs[0]); 173 mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
171 if (fatent->nr_bhs == 2) 174 if (fatent->nr_bhs == 2)
172 mark_buffer_dirty(fatent->bhs[1]); 175 mark_buffer_dirty_inode(fatent->bhs[1], fatent->fat_inode);
173} 176}
174 177
175static void fat16_ent_put(struct fat_entry *fatent, int new) 178static void fat16_ent_put(struct fat_entry *fatent, int new)
@@ -178,7 +181,7 @@ static void fat16_ent_put(struct fat_entry *fatent, int new)
178 new = EOF_FAT16; 181 new = EOF_FAT16;
179 182
180 *fatent->u.ent16_p = cpu_to_le16(new); 183 *fatent->u.ent16_p = cpu_to_le16(new);
181 mark_buffer_dirty(fatent->bhs[0]); 184 mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
182} 185}
183 186
184static void fat32_ent_put(struct fat_entry *fatent, int new) 187static void fat32_ent_put(struct fat_entry *fatent, int new)
@@ -189,7 +192,7 @@ static void fat32_ent_put(struct fat_entry *fatent, int new)
189 WARN_ON(new & 0xf0000000); 192 WARN_ON(new & 0xf0000000);
190 new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff; 193 new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff;
191 *fatent->u.ent32_p = cpu_to_le32(new); 194 *fatent->u.ent32_p = cpu_to_le32(new);
192 mark_buffer_dirty(fatent->bhs[0]); 195 mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
193} 196}
194 197
195static int fat12_ent_next(struct fat_entry *fatent) 198static int fat12_ent_next(struct fat_entry *fatent)
@@ -381,7 +384,7 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
381 } 384 }
382 memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize); 385 memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
383 set_buffer_uptodate(c_bh); 386 set_buffer_uptodate(c_bh);
384 mark_buffer_dirty(c_bh); 387 mark_buffer_dirty_inode(c_bh, sbi->fat_inode);
385 if (sb->s_flags & MS_SYNCHRONOUS) 388 if (sb->s_flags & MS_SYNCHRONOUS)
386 err = sync_dirty_buffer(c_bh); 389 err = sync_dirty_buffer(c_bh);
387 brelse(c_bh); 390 brelse(c_bh);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 0a7f4a9918b3..e955a56b4e5e 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -133,6 +133,18 @@ static int fat_file_release(struct inode *inode, struct file *filp)
133 return 0; 133 return 0;
134} 134}
135 135
136int fat_file_fsync(struct file *filp, struct dentry *dentry, int datasync)
137{
138 struct inode *inode = dentry->d_inode;
139 int res, err;
140
141 res = simple_fsync(filp, dentry, datasync);
142 err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);
143
144 return res ? res : err;
145}
146
147
136const struct file_operations fat_file_operations = { 148const struct file_operations fat_file_operations = {
137 .llseek = generic_file_llseek, 149 .llseek = generic_file_llseek,
138 .read = do_sync_read, 150 .read = do_sync_read,
@@ -142,7 +154,7 @@ const struct file_operations fat_file_operations = {
142 .mmap = generic_file_mmap, 154 .mmap = generic_file_mmap,
143 .release = fat_file_release, 155 .release = fat_file_release,
144 .ioctl = fat_generic_ioctl, 156 .ioctl = fat_generic_ioctl,
145 .fsync = file_fsync, 157 .fsync = fat_file_fsync,
146 .splice_read = generic_file_splice_read, 158 .splice_read = generic_file_splice_read,
147}; 159};
148 160
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 296785a0dec8..51a5ecf9000a 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -441,16 +441,35 @@ static void fat_clear_inode(struct inode *inode)
441 441
442static void fat_write_super(struct super_block *sb) 442static void fat_write_super(struct super_block *sb)
443{ 443{
444 lock_super(sb);
444 sb->s_dirt = 0; 445 sb->s_dirt = 0;
445 446
446 if (!(sb->s_flags & MS_RDONLY)) 447 if (!(sb->s_flags & MS_RDONLY))
447 fat_clusters_flush(sb); 448 fat_clusters_flush(sb);
449 unlock_super(sb);
450}
451
452static int fat_sync_fs(struct super_block *sb, int wait)
453{
454 lock_super(sb);
455 fat_clusters_flush(sb);
456 sb->s_dirt = 0;
457 unlock_super(sb);
458
459 return 0;
448} 460}
449 461
450static void fat_put_super(struct super_block *sb) 462static void fat_put_super(struct super_block *sb)
451{ 463{
452 struct msdos_sb_info *sbi = MSDOS_SB(sb); 464 struct msdos_sb_info *sbi = MSDOS_SB(sb);
453 465
466 lock_kernel();
467
468 if (sb->s_dirt)
469 fat_write_super(sb);
470
471 iput(sbi->fat_inode);
472
454 if (sbi->nls_disk) { 473 if (sbi->nls_disk) {
455 unload_nls(sbi->nls_disk); 474 unload_nls(sbi->nls_disk);
456 sbi->nls_disk = NULL; 475 sbi->nls_disk = NULL;
@@ -467,6 +486,8 @@ static void fat_put_super(struct super_block *sb)
467 486
468 sb->s_fs_info = NULL; 487 sb->s_fs_info = NULL;
469 kfree(sbi); 488 kfree(sbi);
489
490 unlock_kernel();
470} 491}
471 492
472static struct kmem_cache *fat_inode_cachep; 493static struct kmem_cache *fat_inode_cachep;
@@ -632,6 +653,7 @@ static const struct super_operations fat_sops = {
632 .delete_inode = fat_delete_inode, 653 .delete_inode = fat_delete_inode,
633 .put_super = fat_put_super, 654 .put_super = fat_put_super,
634 .write_super = fat_write_super, 655 .write_super = fat_write_super,
656 .sync_fs = fat_sync_fs,
635 .statfs = fat_statfs, 657 .statfs = fat_statfs,
636 .clear_inode = fat_clear_inode, 658 .clear_inode = fat_clear_inode,
637 .remount_fs = fat_remount, 659 .remount_fs = fat_remount,
@@ -1174,7 +1196,7 @@ static int fat_read_root(struct inode *inode)
1174int fat_fill_super(struct super_block *sb, void *data, int silent, 1196int fat_fill_super(struct super_block *sb, void *data, int silent,
1175 const struct inode_operations *fs_dir_inode_ops, int isvfat) 1197 const struct inode_operations *fs_dir_inode_ops, int isvfat)
1176{ 1198{
1177 struct inode *root_inode = NULL; 1199 struct inode *root_inode = NULL, *fat_inode = NULL;
1178 struct buffer_head *bh; 1200 struct buffer_head *bh;
1179 struct fat_boot_sector *b; 1201 struct fat_boot_sector *b;
1180 struct msdos_sb_info *sbi; 1202 struct msdos_sb_info *sbi;
@@ -1414,6 +1436,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
1414 } 1436 }
1415 1437
1416 error = -ENOMEM; 1438 error = -ENOMEM;
1439 fat_inode = new_inode(sb);
1440 if (!fat_inode)
1441 goto out_fail;
1442 MSDOS_I(fat_inode)->i_pos = 0;
1443 sbi->fat_inode = fat_inode;
1417 root_inode = new_inode(sb); 1444 root_inode = new_inode(sb);
1418 if (!root_inode) 1445 if (!root_inode)
1419 goto out_fail; 1446 goto out_fail;
@@ -1439,6 +1466,8 @@ out_invalid:
1439 " on dev %s.\n", sb->s_id); 1466 " on dev %s.\n", sb->s_id);
1440 1467
1441out_fail: 1468out_fail:
1469 if (fat_inode)
1470 iput(fat_inode);
1442 if (root_inode) 1471 if (root_inode)
1443 iput(root_inode); 1472 iput(root_inode);
1444 if (sbi->nls_io) 1473 if (sbi->nls_io)
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index da3f361a37dd..20f522861355 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -544,7 +544,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
544 int start = MSDOS_I(new_dir)->i_logstart; 544 int start = MSDOS_I(new_dir)->i_logstart;
545 dotdot_de->start = cpu_to_le16(start); 545 dotdot_de->start = cpu_to_le16(start);
546 dotdot_de->starthi = cpu_to_le16(start >> 16); 546 dotdot_de->starthi = cpu_to_le16(start >> 16);
547 mark_buffer_dirty(dotdot_bh); 547 mark_buffer_dirty_inode(dotdot_bh, old_inode);
548 if (IS_DIRSYNC(new_dir)) { 548 if (IS_DIRSYNC(new_dir)) {
549 err = sync_dirty_buffer(dotdot_bh); 549 err = sync_dirty_buffer(dotdot_bh);
550 if (err) 550 if (err)
@@ -586,7 +586,7 @@ error_dotdot:
586 int start = MSDOS_I(old_dir)->i_logstart; 586 int start = MSDOS_I(old_dir)->i_logstart;
587 dotdot_de->start = cpu_to_le16(start); 587 dotdot_de->start = cpu_to_le16(start);
588 dotdot_de->starthi = cpu_to_le16(start >> 16); 588 dotdot_de->starthi = cpu_to_le16(start >> 16);
589 mark_buffer_dirty(dotdot_bh); 589 mark_buffer_dirty_inode(dotdot_bh, old_inode);
590 corrupt |= sync_dirty_buffer(dotdot_bh); 590 corrupt |= sync_dirty_buffer(dotdot_bh);
591 } 591 }
592error_inode: 592error_inode:
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index a0e00e3a46e9..b50ecbe97f83 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -965,7 +965,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
965 int start = MSDOS_I(new_dir)->i_logstart; 965 int start = MSDOS_I(new_dir)->i_logstart;
966 dotdot_de->start = cpu_to_le16(start); 966 dotdot_de->start = cpu_to_le16(start);
967 dotdot_de->starthi = cpu_to_le16(start >> 16); 967 dotdot_de->starthi = cpu_to_le16(start >> 16);
968 mark_buffer_dirty(dotdot_bh); 968 mark_buffer_dirty_inode(dotdot_bh, old_inode);
969 if (IS_DIRSYNC(new_dir)) { 969 if (IS_DIRSYNC(new_dir)) {
970 err = sync_dirty_buffer(dotdot_bh); 970 err = sync_dirty_buffer(dotdot_bh);
971 if (err) 971 if (err)
@@ -1009,7 +1009,7 @@ error_dotdot:
1009 int start = MSDOS_I(old_dir)->i_logstart; 1009 int start = MSDOS_I(old_dir)->i_logstart;
1010 dotdot_de->start = cpu_to_le16(start); 1010 dotdot_de->start = cpu_to_le16(start);
1011 dotdot_de->starthi = cpu_to_le16(start >> 16); 1011 dotdot_de->starthi = cpu_to_le16(start >> 16);
1012 mark_buffer_dirty(dotdot_bh); 1012 mark_buffer_dirty_inode(dotdot_bh, old_inode);
1013 corrupt |= sync_dirty_buffer(dotdot_bh); 1013 corrupt |= sync_dirty_buffer(dotdot_bh);
1014 } 1014 }
1015error_inode: 1015error_inode:
diff --git a/fs/file_table.c b/fs/file_table.c
index 54018fe48840..334ce39881f8 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -214,7 +214,7 @@ int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
214 */ 214 */
215 if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) { 215 if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) {
216 file_take_write(file); 216 file_take_write(file);
217 error = mnt_want_write(mnt); 217 error = mnt_clone_write(mnt);
218 WARN_ON(error); 218 WARN_ON(error);
219 } 219 }
220 return error; 220 return error;
@@ -399,6 +399,44 @@ too_bad:
399 return 0; 399 return 0;
400} 400}
401 401
402/**
403 * mark_files_ro - mark all files read-only
404 * @sb: superblock in question
405 *
406 * All files are marked read-only. We don't care about pending
407 * delete files so this should be used in 'force' mode only.
408 */
409void mark_files_ro(struct super_block *sb)
410{
411 struct file *f;
412
413retry:
414 file_list_lock();
415 list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
416 struct vfsmount *mnt;
417 if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
418 continue;
419 if (!file_count(f))
420 continue;
421 if (!(f->f_mode & FMODE_WRITE))
422 continue;
423 f->f_mode &= ~FMODE_WRITE;
424 if (file_check_writeable(f) != 0)
425 continue;
426 file_release_write(f);
427 mnt = mntget(f->f_path.mnt);
428 file_list_unlock();
429 /*
430 * This can sleep, so we can't hold
431 * the file_list_lock() spinlock.
432 */
433 mnt_drop_write(mnt);
434 mntput(mnt);
435 goto retry;
436 }
437 file_list_unlock();
438}
439
402void __init files_init(unsigned long mempages) 440void __init files_init(unsigned long mempages)
403{ 441{
404 int n; 442 int n;
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 1dacda831577..cdbd1654e4cd 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -80,12 +80,16 @@ vxfs_put_super(struct super_block *sbp)
80{ 80{
81 struct vxfs_sb_info *infp = VXFS_SBI(sbp); 81 struct vxfs_sb_info *infp = VXFS_SBI(sbp);
82 82
83 lock_kernel();
84
83 vxfs_put_fake_inode(infp->vsi_fship); 85 vxfs_put_fake_inode(infp->vsi_fship);
84 vxfs_put_fake_inode(infp->vsi_ilist); 86 vxfs_put_fake_inode(infp->vsi_ilist);
85 vxfs_put_fake_inode(infp->vsi_stilist); 87 vxfs_put_fake_inode(infp->vsi_stilist);
86 88
87 brelse(infp->vsi_bp); 89 brelse(infp->vsi_bp);
88 kfree(infp); 90 kfree(infp);
91
92 unlock_kernel();
89} 93}
90 94
91/** 95/**
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 91013ff7dd53..40308e98c6a4 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -64,6 +64,28 @@ static void writeback_release(struct backing_dev_info *bdi)
64 clear_bit(BDI_pdflush, &bdi->state); 64 clear_bit(BDI_pdflush, &bdi->state);
65} 65}
66 66
67static noinline void block_dump___mark_inode_dirty(struct inode *inode)
68{
69 if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {
70 struct dentry *dentry;
71 const char *name = "?";
72
73 dentry = d_find_alias(inode);
74 if (dentry) {
75 spin_lock(&dentry->d_lock);
76 name = (const char *) dentry->d_name.name;
77 }
78 printk(KERN_DEBUG
79 "%s(%d): dirtied inode %lu (%s) on %s\n",
80 current->comm, task_pid_nr(current), inode->i_ino,
81 name, inode->i_sb->s_id);
82 if (dentry) {
83 spin_unlock(&dentry->d_lock);
84 dput(dentry);
85 }
86 }
87}
88
67/** 89/**
68 * __mark_inode_dirty - internal function 90 * __mark_inode_dirty - internal function
69 * @inode: inode to mark 91 * @inode: inode to mark
@@ -114,23 +136,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
114 if ((inode->i_state & flags) == flags) 136 if ((inode->i_state & flags) == flags)
115 return; 137 return;
116 138
117 if (unlikely(block_dump)) { 139 if (unlikely(block_dump))
118 struct dentry *dentry = NULL; 140 block_dump___mark_inode_dirty(inode);
119 const char *name = "?";
120
121 if (!list_empty(&inode->i_dentry)) {
122 dentry = list_entry(inode->i_dentry.next,
123 struct dentry, d_alias);
124 if (dentry && dentry->d_name.name)
125 name = (const char *) dentry->d_name.name;
126 }
127
128 if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev"))
129 printk(KERN_DEBUG
130 "%s(%d): dirtied inode %lu (%s) on %s\n",
131 current->comm, task_pid_nr(current), inode->i_ino,
132 name, inode->i_sb->s_id);
133 }
134 141
135 spin_lock(&inode_lock); 142 spin_lock(&inode_lock);
136 if ((inode->i_state & flags) != flags) { 143 if ((inode->i_state & flags) != flags) {
@@ -289,7 +296,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
289 int ret; 296 int ret;
290 297
291 BUG_ON(inode->i_state & I_SYNC); 298 BUG_ON(inode->i_state & I_SYNC);
292 WARN_ON(inode->i_state & I_NEW);
293 299
294 /* Set I_SYNC, reset I_DIRTY */ 300 /* Set I_SYNC, reset I_DIRTY */
295 dirty = inode->i_state & I_DIRTY; 301 dirty = inode->i_state & I_DIRTY;
@@ -314,7 +320,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
314 } 320 }
315 321
316 spin_lock(&inode_lock); 322 spin_lock(&inode_lock);
317 WARN_ON(inode->i_state & I_NEW);
318 inode->i_state &= ~I_SYNC; 323 inode->i_state &= ~I_SYNC;
319 if (!(inode->i_state & I_FREEING)) { 324 if (!(inode->i_state & I_FREEING)) {
320 if (!(inode->i_state & I_DIRTY) && 325 if (!(inode->i_state & I_DIRTY) &&
@@ -679,55 +684,6 @@ void sync_inodes_sb(struct super_block *sb, int wait)
679} 684}
680 685
681/** 686/**
682 * sync_inodes - writes all inodes to disk
683 * @wait: wait for completion
684 *
685 * sync_inodes() goes through each super block's dirty inode list, writes the
686 * inodes out, waits on the writeout and puts the inodes back on the normal
687 * list.
688 *
689 * This is for sys_sync(). fsync_dev() uses the same algorithm. The subtle
690 * part of the sync functions is that the blockdev "superblock" is processed
691 * last. This is because the write_inode() function of a typical fs will
692 * perform no I/O, but will mark buffers in the blockdev mapping as dirty.
693 * What we want to do is to perform all that dirtying first, and then write
694 * back all those inode blocks via the blockdev mapping in one sweep. So the
695 * additional (somewhat redundant) sync_blockdev() calls here are to make
696 * sure that really happens. Because if we call sync_inodes_sb(wait=1) with
697 * outstanding dirty inodes, the writeback goes block-at-a-time within the
698 * filesystem's write_inode(). This is extremely slow.
699 */
700static void __sync_inodes(int wait)
701{
702 struct super_block *sb;
703
704 spin_lock(&sb_lock);
705restart:
706 list_for_each_entry(sb, &super_blocks, s_list) {
707 sb->s_count++;
708 spin_unlock(&sb_lock);
709 down_read(&sb->s_umount);
710 if (sb->s_root) {
711 sync_inodes_sb(sb, wait);
712 sync_blockdev(sb->s_bdev);
713 }
714 up_read(&sb->s_umount);
715 spin_lock(&sb_lock);
716 if (__put_super_and_need_restart(sb))
717 goto restart;
718 }
719 spin_unlock(&sb_lock);
720}
721
722void sync_inodes(int wait)
723{
724 __sync_inodes(0);
725
726 if (wait)
727 __sync_inodes(1);
728}
729
730/**
731 * write_inode_now - write an inode to disk 687 * write_inode_now - write an inode to disk
732 * @inode: inode to write to disk 688 * @inode: inode to write to disk
733 * @sync: whether the write should be synchronous or not 689 * @sync: whether the write should be synchronous or not
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index aa62cf5976e8..f2e449c595b4 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -764,7 +764,6 @@ void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
764 } 764 }
765 gfs2_log_unlock(sdp); 765 gfs2_log_unlock(sdp);
766 766
767 sdp->sd_vfs->s_dirt = 0;
768 up_write(&sdp->sd_log_flush_lock); 767 up_write(&sdp->sd_log_flush_lock);
769 768
770 kfree(ai); 769 kfree(ai);
@@ -823,7 +822,6 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
823 log_refund(sdp, tr); 822 log_refund(sdp, tr);
824 buf_lo_incore_commit(sdp, tr); 823 buf_lo_incore_commit(sdp, tr);
825 824
826 sdp->sd_vfs->s_dirt = 1;
827 up_read(&sdp->sd_log_flush_lock); 825 up_read(&sdp->sd_log_flush_lock);
828 826
829 gfs2_log_lock(sdp); 827 gfs2_log_lock(sdp);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 40bcc37e5a70..c8930b31cdf0 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -719,6 +719,8 @@ static void gfs2_put_super(struct super_block *sb)
719 int error; 719 int error;
720 struct gfs2_jdesc *jd; 720 struct gfs2_jdesc *jd;
721 721
722 lock_kernel();
723
722 /* Unfreeze the filesystem, if we need to */ 724 /* Unfreeze the filesystem, if we need to */
723 725
724 mutex_lock(&sdp->sd_freeze_lock); 726 mutex_lock(&sdp->sd_freeze_lock);
@@ -785,17 +787,8 @@ restart:
785 787
786 /* At this point, we're through participating in the lockspace */ 788 /* At this point, we're through participating in the lockspace */
787 gfs2_sys_fs_del(sdp); 789 gfs2_sys_fs_del(sdp);
788}
789
790/**
791 * gfs2_write_super
792 * @sb: the superblock
793 *
794 */
795 790
796static void gfs2_write_super(struct super_block *sb) 791 unlock_kernel();
797{
798 sb->s_dirt = 0;
799} 792}
800 793
801/** 794/**
@@ -807,7 +800,6 @@ static void gfs2_write_super(struct super_block *sb)
807 800
808static int gfs2_sync_fs(struct super_block *sb, int wait) 801static int gfs2_sync_fs(struct super_block *sb, int wait)
809{ 802{
810 sb->s_dirt = 0;
811 if (wait && sb->s_fs_info) 803 if (wait && sb->s_fs_info)
812 gfs2_log_flush(sb->s_fs_info, NULL); 804 gfs2_log_flush(sb->s_fs_info, NULL);
813 return 0; 805 return 0;
@@ -1324,7 +1316,6 @@ const struct super_operations gfs2_super_ops = {
1324 .write_inode = gfs2_write_inode, 1316 .write_inode = gfs2_write_inode,
1325 .delete_inode = gfs2_delete_inode, 1317 .delete_inode = gfs2_delete_inode,
1326 .put_super = gfs2_put_super, 1318 .put_super = gfs2_put_super,
1327 .write_super = gfs2_write_super,
1328 .sync_fs = gfs2_sync_fs, 1319 .sync_fs = gfs2_sync_fs,
1329 .freeze_fs = gfs2_freeze, 1320 .freeze_fs = gfs2_freeze,
1330 .unfreeze_fs = gfs2_unfreeze, 1321 .unfreeze_fs = gfs2_unfreeze,
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index a36bb749926d..6f833dc8e910 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -49,11 +49,23 @@ MODULE_LICENSE("GPL");
49 */ 49 */
50static void hfs_write_super(struct super_block *sb) 50static void hfs_write_super(struct super_block *sb)
51{ 51{
52 lock_super(sb);
52 sb->s_dirt = 0; 53 sb->s_dirt = 0;
53 if (sb->s_flags & MS_RDONLY) 54
54 return;
55 /* sync everything to the buffers */ 55 /* sync everything to the buffers */
56 if (!(sb->s_flags & MS_RDONLY))
57 hfs_mdb_commit(sb);
58 unlock_super(sb);
59}
60
61static int hfs_sync_fs(struct super_block *sb, int wait)
62{
63 lock_super(sb);
56 hfs_mdb_commit(sb); 64 hfs_mdb_commit(sb);
65 sb->s_dirt = 0;
66 unlock_super(sb);
67
68 return 0;
57} 69}
58 70
59/* 71/*
@@ -65,9 +77,15 @@ static void hfs_write_super(struct super_block *sb)
65 */ 77 */
66static void hfs_put_super(struct super_block *sb) 78static void hfs_put_super(struct super_block *sb)
67{ 79{
80 lock_kernel();
81
82 if (sb->s_dirt)
83 hfs_write_super(sb);
68 hfs_mdb_close(sb); 84 hfs_mdb_close(sb);
69 /* release the MDB's resources */ 85 /* release the MDB's resources */
70 hfs_mdb_put(sb); 86 hfs_mdb_put(sb);
87
88 unlock_kernel();
71} 89}
72 90
73/* 91/*
@@ -164,6 +182,7 @@ static const struct super_operations hfs_super_operations = {
164 .clear_inode = hfs_clear_inode, 182 .clear_inode = hfs_clear_inode,
165 .put_super = hfs_put_super, 183 .put_super = hfs_put_super,
166 .write_super = hfs_write_super, 184 .write_super = hfs_write_super,
185 .sync_fs = hfs_sync_fs,
167 .statfs = hfs_statfs, 186 .statfs = hfs_statfs,
168 .remount_fs = hfs_remount, 187 .remount_fs = hfs_remount,
169 .show_options = hfs_show_options, 188 .show_options = hfs_show_options,
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index f2a64020f42e..9fc3af0c0dab 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -152,15 +152,14 @@ static void hfsplus_clear_inode(struct inode *inode)
152 } 152 }
153} 153}
154 154
155static void hfsplus_write_super(struct super_block *sb) 155static int hfsplus_sync_fs(struct super_block *sb, int wait)
156{ 156{
157 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; 157 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
158 158
159 dprint(DBG_SUPER, "hfsplus_write_super\n"); 159 dprint(DBG_SUPER, "hfsplus_write_super\n");
160
161 lock_super(sb);
160 sb->s_dirt = 0; 162 sb->s_dirt = 0;
161 if (sb->s_flags & MS_RDONLY)
162 /* warn? */
163 return;
164 163
165 vhdr->free_blocks = cpu_to_be32(HFSPLUS_SB(sb).free_blocks); 164 vhdr->free_blocks = cpu_to_be32(HFSPLUS_SB(sb).free_blocks);
166 vhdr->next_alloc = cpu_to_be32(HFSPLUS_SB(sb).next_alloc); 165 vhdr->next_alloc = cpu_to_be32(HFSPLUS_SB(sb).next_alloc);
@@ -192,6 +191,16 @@ static void hfsplus_write_super(struct super_block *sb)
192 } 191 }
193 HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP; 192 HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP;
194 } 193 }
194 unlock_super(sb);
195 return 0;
196}
197
198static void hfsplus_write_super(struct super_block *sb)
199{
200 if (!(sb->s_flags & MS_RDONLY))
201 hfsplus_sync_fs(sb, 1);
202 else
203 sb->s_dirt = 0;
195} 204}
196 205
197static void hfsplus_put_super(struct super_block *sb) 206static void hfsplus_put_super(struct super_block *sb)
@@ -199,6 +208,11 @@ static void hfsplus_put_super(struct super_block *sb)
199 dprint(DBG_SUPER, "hfsplus_put_super\n"); 208 dprint(DBG_SUPER, "hfsplus_put_super\n");
200 if (!sb->s_fs_info) 209 if (!sb->s_fs_info)
201 return; 210 return;
211
212 lock_kernel();
213
214 if (sb->s_dirt)
215 hfsplus_write_super(sb);
202 if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) { 216 if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) {
203 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; 217 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
204 218
@@ -218,6 +232,8 @@ static void hfsplus_put_super(struct super_block *sb)
218 unload_nls(HFSPLUS_SB(sb).nls); 232 unload_nls(HFSPLUS_SB(sb).nls);
219 kfree(sb->s_fs_info); 233 kfree(sb->s_fs_info);
220 sb->s_fs_info = NULL; 234 sb->s_fs_info = NULL;
235
236 unlock_kernel();
221} 237}
222 238
223static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf) 239static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -279,6 +295,7 @@ static const struct super_operations hfsplus_sops = {
279 .clear_inode = hfsplus_clear_inode, 295 .clear_inode = hfsplus_clear_inode,
280 .put_super = hfsplus_put_super, 296 .put_super = hfsplus_put_super,
281 .write_super = hfsplus_write_super, 297 .write_super = hfsplus_write_super,
298 .sync_fs = hfsplus_sync_fs,
282 .statfs = hfsplus_statfs, 299 .statfs = hfsplus_statfs,
283 .remount_fs = hfsplus_remount, 300 .remount_fs = hfsplus_remount,
284 .show_options = hfsplus_show_options, 301 .show_options = hfsplus_show_options,
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index fc77965be841..f2feaa06bf26 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -13,6 +13,7 @@
13#include <linux/statfs.h> 13#include <linux/statfs.h>
14#include <linux/magic.h> 14#include <linux/magic.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/smp_lock.h>
16 17
17/* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ 18/* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
18 19
@@ -99,11 +100,16 @@ int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
99static void hpfs_put_super(struct super_block *s) 100static void hpfs_put_super(struct super_block *s)
100{ 101{
101 struct hpfs_sb_info *sbi = hpfs_sb(s); 102 struct hpfs_sb_info *sbi = hpfs_sb(s);
103
104 lock_kernel();
105
102 kfree(sbi->sb_cp_table); 106 kfree(sbi->sb_cp_table);
103 kfree(sbi->sb_bmp_dir); 107 kfree(sbi->sb_bmp_dir);
104 unmark_dirty(s); 108 unmark_dirty(s);
105 s->s_fs_info = NULL; 109 s->s_fs_info = NULL;
106 kfree(sbi); 110 kfree(sbi);
111
112 unlock_kernel();
107} 113}
108 114
109unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno) 115unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
@@ -393,6 +399,8 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
393 399
394 *flags |= MS_NOATIME; 400 *flags |= MS_NOATIME;
395 401
402 lock_kernel();
403 lock_super(s);
396 uid = sbi->sb_uid; gid = sbi->sb_gid; 404 uid = sbi->sb_uid; gid = sbi->sb_gid;
397 umask = 0777 & ~sbi->sb_mode; 405 umask = 0777 & ~sbi->sb_mode;
398 lowercase = sbi->sb_lowercase; conv = sbi->sb_conv; 406 lowercase = sbi->sb_lowercase; conv = sbi->sb_conv;
@@ -425,9 +433,13 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
425 433
426 replace_mount_options(s, new_opts); 434 replace_mount_options(s, new_opts);
427 435
436 unlock_super(s);
437 unlock_kernel();
428 return 0; 438 return 0;
429 439
430out_err: 440out_err:
441 unlock_super(s);
442 unlock_kernel();
431 kfree(new_opts); 443 kfree(new_opts);
432 return -EINVAL; 444 return -EINVAL;
433} 445}
diff --git a/fs/inode.c b/fs/inode.c
index ca337014ae29..a88baebf77cf 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1422,7 +1422,7 @@ void file_update_time(struct file *file)
1422 if (IS_NOCMTIME(inode)) 1422 if (IS_NOCMTIME(inode))
1423 return; 1423 return;
1424 1424
1425 err = mnt_want_write(file->f_path.mnt); 1425 err = mnt_want_write_file(file);
1426 if (err) 1426 if (err)
1427 return; 1427 return;
1428 1428
diff --git a/fs/internal.h b/fs/internal.h
index b4dac4fb6b61..d55ef562f0bb 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -25,6 +25,8 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
25 return sb == blockdev_superblock; 25 return sb == blockdev_superblock;
26} 26}
27 27
28extern int __sync_blockdev(struct block_device *bdev, int wait);
29
28#else 30#else
29static inline void bdev_cache_init(void) 31static inline void bdev_cache_init(void)
30{ 32{
@@ -34,6 +36,11 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
34{ 36{
35 return 0; 37 return 0;
36} 38}
39
40static inline int __sync_blockdev(struct block_device *bdev, int wait)
41{
42 return 0;
43}
37#endif 44#endif
38 45
39/* 46/*
@@ -66,3 +73,13 @@ extern void __init mnt_init(void);
66 * fs_struct.c 73 * fs_struct.c
67 */ 74 */
68extern void chroot_fs_refs(struct path *, struct path *); 75extern void chroot_fs_refs(struct path *, struct path *);
76
77/*
78 * file_table.c
79 */
80extern void mark_files_ro(struct super_block *);
81
82/*
83 * super.c
84 */
85extern int do_remount_sb(struct super_block *, int, void *, int);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index b4cbe9603c7d..068b34b5a107 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -42,11 +42,16 @@ static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qst
42static void isofs_put_super(struct super_block *sb) 42static void isofs_put_super(struct super_block *sb)
43{ 43{
44 struct isofs_sb_info *sbi = ISOFS_SB(sb); 44 struct isofs_sb_info *sbi = ISOFS_SB(sb);
45
45#ifdef CONFIG_JOLIET 46#ifdef CONFIG_JOLIET
47 lock_kernel();
48
46 if (sbi->s_nls_iocharset) { 49 if (sbi->s_nls_iocharset) {
47 unload_nls(sbi->s_nls_iocharset); 50 unload_nls(sbi->s_nls_iocharset);
48 sbi->s_nls_iocharset = NULL; 51 sbi->s_nls_iocharset = NULL;
49 } 52 }
53
54 unlock_kernel();
50#endif 55#endif
51 56
52 kfree(sbi); 57 kfree(sbi);
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 249305d65d5b..3451a81b2142 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -20,6 +20,7 @@
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/vfs.h> 21#include <linux/vfs.h>
22#include <linux/crc32.h> 22#include <linux/crc32.h>
23#include <linux/smp_lock.h>
23#include "nodelist.h" 24#include "nodelist.h"
24 25
25static int jffs2_flash_setup(struct jffs2_sb_info *c); 26static int jffs2_flash_setup(struct jffs2_sb_info *c);
@@ -387,6 +388,7 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
387 This also catches the case where it was stopped and this 388 This also catches the case where it was stopped and this
388 is just a remount to restart it. 389 is just a remount to restart it.
389 Flush the writebuffer, if neccecary, else we loose it */ 390 Flush the writebuffer, if neccecary, else we loose it */
391 lock_kernel();
390 if (!(sb->s_flags & MS_RDONLY)) { 392 if (!(sb->s_flags & MS_RDONLY)) {
391 jffs2_stop_garbage_collect_thread(c); 393 jffs2_stop_garbage_collect_thread(c);
392 mutex_lock(&c->alloc_sem); 394 mutex_lock(&c->alloc_sem);
@@ -399,24 +401,10 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
399 401
400 *flags |= MS_NOATIME; 402 *flags |= MS_NOATIME;
401 403
404 unlock_kernel();
402 return 0; 405 return 0;
403} 406}
404 407
405void jffs2_write_super (struct super_block *sb)
406{
407 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
408 sb->s_dirt = 0;
409
410 if (sb->s_flags & MS_RDONLY)
411 return;
412
413 D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
414 jffs2_garbage_collect_trigger(c);
415 jffs2_erase_pending_blocks(c, 0);
416 jffs2_flush_wbuf_gc(c, 0);
417}
418
419
420/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, 408/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
421 fill in the raw_inode while you're at it. */ 409 fill in the raw_inode while you're at it. */
422struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) 410struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 5e194a5c8e29..2228380c47b9 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -181,7 +181,6 @@ void jffs2_dirty_inode(struct inode *inode);
181struct inode *jffs2_new_inode (struct inode *dir_i, int mode, 181struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
182 struct jffs2_raw_inode *ri); 182 struct jffs2_raw_inode *ri);
183int jffs2_statfs (struct dentry *, struct kstatfs *); 183int jffs2_statfs (struct dentry *, struct kstatfs *);
184void jffs2_write_super (struct super_block *);
185int jffs2_remount_fs (struct super_block *, int *, char *); 184int jffs2_remount_fs (struct super_block *, int *, char *);
186int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); 185int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
187void jffs2_gc_release_inode(struct jffs2_sb_info *c, 186void jffs2_gc_release_inode(struct jffs2_sb_info *c,
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 4c4e18c54a51..07a22caf2687 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -53,10 +53,29 @@ static void jffs2_i_init_once(void *foo)
53 inode_init_once(&f->vfs_inode); 53 inode_init_once(&f->vfs_inode);
54} 54}
55 55
56static void jffs2_write_super(struct super_block *sb)
57{
58 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
59
60 lock_super(sb);
61 sb->s_dirt = 0;
62
63 if (!(sb->s_flags & MS_RDONLY)) {
64 D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
65 jffs2_garbage_collect_trigger(c);
66 jffs2_erase_pending_blocks(c, 0);
67 jffs2_flush_wbuf_gc(c, 0);
68 }
69
70 unlock_super(sb);
71}
72
56static int jffs2_sync_fs(struct super_block *sb, int wait) 73static int jffs2_sync_fs(struct super_block *sb, int wait)
57{ 74{
58 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 75 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
59 76
77 jffs2_write_super(sb);
78
60 mutex_lock(&c->alloc_sem); 79 mutex_lock(&c->alloc_sem);
61 jffs2_flush_wbuf_pad(c); 80 jffs2_flush_wbuf_pad(c);
62 mutex_unlock(&c->alloc_sem); 81 mutex_unlock(&c->alloc_sem);
@@ -174,6 +193,11 @@ static void jffs2_put_super (struct super_block *sb)
174 193
175 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); 194 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
176 195
196 lock_kernel();
197
198 if (sb->s_dirt)
199 jffs2_write_super(sb);
200
177 mutex_lock(&c->alloc_sem); 201 mutex_lock(&c->alloc_sem);
178 jffs2_flush_wbuf_pad(c); 202 jffs2_flush_wbuf_pad(c);
179 mutex_unlock(&c->alloc_sem); 203 mutex_unlock(&c->alloc_sem);
@@ -192,6 +216,8 @@ static void jffs2_put_super (struct super_block *sb)
192 if (c->mtd->sync) 216 if (c->mtd->sync)
193 c->mtd->sync(c->mtd); 217 c->mtd->sync(c->mtd);
194 218
219 unlock_kernel();
220
195 D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); 221 D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
196} 222}
197 223
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index d9b0e92b3602..09b1b6ee2186 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -32,6 +32,7 @@
32#include <linux/crc32.h> 32#include <linux/crc32.h>
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/smp_lock.h>
35 36
36#include "jfs_incore.h" 37#include "jfs_incore.h"
37#include "jfs_filsys.h" 38#include "jfs_filsys.h"
@@ -183,6 +184,9 @@ static void jfs_put_super(struct super_block *sb)
183 int rc; 184 int rc;
184 185
185 jfs_info("In jfs_put_super"); 186 jfs_info("In jfs_put_super");
187
188 lock_kernel();
189
186 rc = jfs_umount(sb); 190 rc = jfs_umount(sb);
187 if (rc) 191 if (rc)
188 jfs_err("jfs_umount failed with return code %d", rc); 192 jfs_err("jfs_umount failed with return code %d", rc);
@@ -195,6 +199,8 @@ static void jfs_put_super(struct super_block *sb)
195 sbi->direct_inode = NULL; 199 sbi->direct_inode = NULL;
196 200
197 kfree(sbi); 201 kfree(sbi);
202
203 unlock_kernel();
198} 204}
199 205
200enum { 206enum {
@@ -370,19 +376,24 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
370 s64 newLVSize = 0; 376 s64 newLVSize = 0;
371 int rc = 0; 377 int rc = 0;
372 int flag = JFS_SBI(sb)->flag; 378 int flag = JFS_SBI(sb)->flag;
379 int ret;
373 380
374 if (!parse_options(data, sb, &newLVSize, &flag)) { 381 if (!parse_options(data, sb, &newLVSize, &flag)) {
375 return -EINVAL; 382 return -EINVAL;
376 } 383 }
384 lock_kernel();
377 if (newLVSize) { 385 if (newLVSize) {
378 if (sb->s_flags & MS_RDONLY) { 386 if (sb->s_flags & MS_RDONLY) {
379 printk(KERN_ERR 387 printk(KERN_ERR
380 "JFS: resize requires volume to be mounted read-write\n"); 388 "JFS: resize requires volume to be mounted read-write\n");
389 unlock_kernel();
381 return -EROFS; 390 return -EROFS;
382 } 391 }
383 rc = jfs_extendfs(sb, newLVSize, 0); 392 rc = jfs_extendfs(sb, newLVSize, 0);
384 if (rc) 393 if (rc) {
394 unlock_kernel();
385 return rc; 395 return rc;
396 }
386 } 397 }
387 398
388 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { 399 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
@@ -393,23 +404,31 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
393 truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0); 404 truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0);
394 405
395 JFS_SBI(sb)->flag = flag; 406 JFS_SBI(sb)->flag = flag;
396 return jfs_mount_rw(sb, 1); 407 ret = jfs_mount_rw(sb, 1);
408 unlock_kernel();
409 return ret;
397 } 410 }
398 if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { 411 if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
399 rc = jfs_umount_rw(sb); 412 rc = jfs_umount_rw(sb);
400 JFS_SBI(sb)->flag = flag; 413 JFS_SBI(sb)->flag = flag;
414 unlock_kernel();
401 return rc; 415 return rc;
402 } 416 }
403 if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY)) 417 if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
404 if (!(sb->s_flags & MS_RDONLY)) { 418 if (!(sb->s_flags & MS_RDONLY)) {
405 rc = jfs_umount_rw(sb); 419 rc = jfs_umount_rw(sb);
406 if (rc) 420 if (rc) {
421 unlock_kernel();
407 return rc; 422 return rc;
423 }
408 JFS_SBI(sb)->flag = flag; 424 JFS_SBI(sb)->flag = flag;
409 return jfs_mount_rw(sb, 1); 425 ret = jfs_mount_rw(sb, 1);
426 unlock_kernel();
427 return ret;
410 } 428 }
411 JFS_SBI(sb)->flag = flag; 429 JFS_SBI(sb)->flag = flag;
412 430
431 unlock_kernel();
413 return 0; 432 return 0;
414} 433}
415 434
diff --git a/fs/libfs.c b/fs/libfs.c
index 80046ddf5063..ddfa89948c3f 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -9,6 +9,8 @@
9#include <linux/vfs.h> 9#include <linux/vfs.h>
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11#include <linux/exportfs.h> 11#include <linux/exportfs.h>
12#include <linux/writeback.h>
13#include <linux/buffer_head.h>
12 14
13#include <asm/uaccess.h> 15#include <asm/uaccess.h>
14 16
@@ -807,6 +809,29 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
807} 809}
808EXPORT_SYMBOL_GPL(generic_fh_to_parent); 810EXPORT_SYMBOL_GPL(generic_fh_to_parent);
809 811
812int simple_fsync(struct file *file, struct dentry *dentry, int datasync)
813{
814 struct writeback_control wbc = {
815 .sync_mode = WB_SYNC_ALL,
816 .nr_to_write = 0, /* metadata-only; caller takes care of data */
817 };
818 struct inode *inode = dentry->d_inode;
819 int err;
820 int ret;
821
822 ret = sync_mapping_buffers(inode->i_mapping);
823 if (!(inode->i_state & I_DIRTY))
824 return ret;
825 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
826 return ret;
827
828 err = sync_inode(inode, &wbc);
829 if (ret == 0)
830 ret = err;
831 return ret;
832}
833EXPORT_SYMBOL(simple_fsync);
834
810EXPORT_SYMBOL(dcache_dir_close); 835EXPORT_SYMBOL(dcache_dir_close);
811EXPORT_SYMBOL(dcache_dir_lseek); 836EXPORT_SYMBOL(dcache_dir_lseek);
812EXPORT_SYMBOL(dcache_dir_open); 837EXPORT_SYMBOL(dcache_dir_open);
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index d4946c4c90e2..e5f206467e40 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -22,7 +22,7 @@ static int minix_readdir(struct file *, void *, filldir_t);
22const struct file_operations minix_dir_operations = { 22const struct file_operations minix_dir_operations = {
23 .read = generic_read_dir, 23 .read = generic_read_dir,
24 .readdir = minix_readdir, 24 .readdir = minix_readdir,
25 .fsync = minix_sync_file, 25 .fsync = simple_fsync,
26}; 26};
27 27
28static inline void dir_put_page(struct page *page) 28static inline void dir_put_page(struct page *page)
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 17765f697e50..3eec3e607a87 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -6,15 +6,12 @@
6 * minix regular file handling primitives 6 * minix regular file handling primitives
7 */ 7 */
8 8
9#include <linux/buffer_head.h> /* for fsync_inode_buffers() */
10#include "minix.h" 9#include "minix.h"
11 10
12/* 11/*
13 * We have mostly NULLs here: the current defaults are OK for 12 * We have mostly NULLs here: the current defaults are OK for
14 * the minix filesystem. 13 * the minix filesystem.
15 */ 14 */
16int minix_sync_file(struct file *, struct dentry *, int);
17
18const struct file_operations minix_file_operations = { 15const struct file_operations minix_file_operations = {
19 .llseek = generic_file_llseek, 16 .llseek = generic_file_llseek,
20 .read = do_sync_read, 17 .read = do_sync_read,
@@ -22,7 +19,7 @@ const struct file_operations minix_file_operations = {
22 .write = do_sync_write, 19 .write = do_sync_write,
23 .aio_write = generic_file_aio_write, 20 .aio_write = generic_file_aio_write,
24 .mmap = generic_file_mmap, 21 .mmap = generic_file_mmap,
25 .fsync = minix_sync_file, 22 .fsync = simple_fsync,
26 .splice_read = generic_file_splice_read, 23 .splice_read = generic_file_splice_read,
27}; 24};
28 25
@@ -30,18 +27,3 @@ const struct inode_operations minix_file_inode_operations = {
30 .truncate = minix_truncate, 27 .truncate = minix_truncate,
31 .getattr = minix_getattr, 28 .getattr = minix_getattr,
32}; 29};
33
34int minix_sync_file(struct file * file, struct dentry *dentry, int datasync)
35{
36 struct inode *inode = dentry->d_inode;
37 int err;
38
39 err = sync_mapping_buffers(inode->i_mapping);
40 if (!(inode->i_state & I_DIRTY))
41 return err;
42 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
43 return err;
44
45 err |= minix_sync_inode(inode);
46 return err ? -EIO : 0;
47}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index daad3c2740db..f91a23693597 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -35,6 +35,8 @@ static void minix_put_super(struct super_block *sb)
35 int i; 35 int i;
36 struct minix_sb_info *sbi = minix_sb(sb); 36 struct minix_sb_info *sbi = minix_sb(sb);
37 37
38 lock_kernel();
39
38 if (!(sb->s_flags & MS_RDONLY)) { 40 if (!(sb->s_flags & MS_RDONLY)) {
39 if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ 41 if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */
40 sbi->s_ms->s_state = sbi->s_mount_state; 42 sbi->s_ms->s_state = sbi->s_mount_state;
@@ -49,7 +51,7 @@ static void minix_put_super(struct super_block *sb)
49 sb->s_fs_info = NULL; 51 sb->s_fs_info = NULL;
50 kfree(sbi); 52 kfree(sbi);
51 53
52 return; 54 unlock_kernel();
53} 55}
54 56
55static struct kmem_cache * minix_inode_cachep; 57static struct kmem_cache * minix_inode_cachep;
@@ -554,38 +556,25 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
554 return bh; 556 return bh;
555} 557}
556 558
557static struct buffer_head *minix_update_inode(struct inode *inode) 559static int minix_write_inode(struct inode *inode, int wait)
558{
559 if (INODE_VERSION(inode) == MINIX_V1)
560 return V1_minix_update_inode(inode);
561 else
562 return V2_minix_update_inode(inode);
563}
564
565static int minix_write_inode(struct inode * inode, int wait)
566{
567 brelse(minix_update_inode(inode));
568 return 0;
569}
570
571int minix_sync_inode(struct inode * inode)
572{ 560{
573 int err = 0; 561 int err = 0;
574 struct buffer_head *bh; 562 struct buffer_head *bh;
575 563
576 bh = minix_update_inode(inode); 564 if (INODE_VERSION(inode) == MINIX_V1)
577 if (bh && buffer_dirty(bh)) 565 bh = V1_minix_update_inode(inode);
578 { 566 else
567 bh = V2_minix_update_inode(inode);
568 if (!bh)
569 return -EIO;
570 if (wait && buffer_dirty(bh)) {
579 sync_dirty_buffer(bh); 571 sync_dirty_buffer(bh);
580 if (buffer_req(bh) && !buffer_uptodate(bh)) 572 if (buffer_req(bh) && !buffer_uptodate(bh)) {
581 {
582 printk("IO error syncing minix inode [%s:%08lx]\n", 573 printk("IO error syncing minix inode [%s:%08lx]\n",
583 inode->i_sb->s_id, inode->i_ino); 574 inode->i_sb->s_id, inode->i_ino);
584 err = -1; 575 err = -EIO;
585 } 576 }
586 } 577 }
587 else if (!bh)
588 err = -1;
589 brelse (bh); 578 brelse (bh);
590 return err; 579 return err;
591} 580}
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index e6a0b193bea4..cb7fdd11f9a5 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -57,7 +57,6 @@ extern int __minix_write_begin(struct file *file, struct address_space *mapping,
57extern void V1_minix_truncate(struct inode *); 57extern void V1_minix_truncate(struct inode *);
58extern void V2_minix_truncate(struct inode *); 58extern void V2_minix_truncate(struct inode *);
59extern void minix_truncate(struct inode *); 59extern void minix_truncate(struct inode *);
60extern int minix_sync_inode(struct inode *);
61extern void minix_set_inode(struct inode *, dev_t); 60extern void minix_set_inode(struct inode *, dev_t);
62extern int V1_minix_get_block(struct inode *, long, struct buffer_head *, int); 61extern int V1_minix_get_block(struct inode *, long, struct buffer_head *, int);
63extern int V2_minix_get_block(struct inode *, long, struct buffer_head *, int); 62extern int V2_minix_get_block(struct inode *, long, struct buffer_head *, int);
@@ -72,7 +71,6 @@ extern int minix_empty_dir(struct inode*);
72extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*); 71extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*);
73extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**); 72extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**);
74extern ino_t minix_inode_by_name(struct dentry*); 73extern ino_t minix_inode_by_name(struct dentry*);
75extern int minix_sync_file(struct file *, struct dentry *, int);
76 74
77extern const struct inode_operations minix_file_inode_operations; 75extern const struct inode_operations minix_file_inode_operations;
78extern const struct inode_operations minix_dir_inode_operations; 76extern const struct inode_operations minix_dir_inode_operations;
diff --git a/fs/namei.c b/fs/namei.c
index c82805d088e1..527119afb6a5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -552,6 +552,17 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
552 return result; 552 return result;
553} 553}
554 554
555static __always_inline void set_root(struct nameidata *nd)
556{
557 if (!nd->root.mnt) {
558 struct fs_struct *fs = current->fs;
559 read_lock(&fs->lock);
560 nd->root = fs->root;
561 path_get(&nd->root);
562 read_unlock(&fs->lock);
563 }
564}
565
555static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) 566static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
556{ 567{
557 int res = 0; 568 int res = 0;
@@ -560,14 +571,10 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
560 goto fail; 571 goto fail;
561 572
562 if (*link == '/') { 573 if (*link == '/') {
563 struct fs_struct *fs = current->fs; 574 set_root(nd);
564
565 path_put(&nd->path); 575 path_put(&nd->path);
566 576 nd->path = nd->root;
567 read_lock(&fs->lock); 577 path_get(&nd->root);
568 nd->path = fs->root;
569 path_get(&fs->root);
570 read_unlock(&fs->lock);
571 } 578 }
572 579
573 res = link_path_walk(link, nd); 580 res = link_path_walk(link, nd);
@@ -668,23 +675,23 @@ loop:
668 return err; 675 return err;
669} 676}
670 677
671int follow_up(struct vfsmount **mnt, struct dentry **dentry) 678int follow_up(struct path *path)
672{ 679{
673 struct vfsmount *parent; 680 struct vfsmount *parent;
674 struct dentry *mountpoint; 681 struct dentry *mountpoint;
675 spin_lock(&vfsmount_lock); 682 spin_lock(&vfsmount_lock);
676 parent=(*mnt)->mnt_parent; 683 parent = path->mnt->mnt_parent;
677 if (parent == *mnt) { 684 if (parent == path->mnt) {
678 spin_unlock(&vfsmount_lock); 685 spin_unlock(&vfsmount_lock);
679 return 0; 686 return 0;
680 } 687 }
681 mntget(parent); 688 mntget(parent);
682 mountpoint=dget((*mnt)->mnt_mountpoint); 689 mountpoint = dget(path->mnt->mnt_mountpoint);
683 spin_unlock(&vfsmount_lock); 690 spin_unlock(&vfsmount_lock);
684 dput(*dentry); 691 dput(path->dentry);
685 *dentry = mountpoint; 692 path->dentry = mountpoint;
686 mntput(*mnt); 693 mntput(path->mnt);
687 *mnt = parent; 694 path->mnt = parent;
688 return 1; 695 return 1;
689} 696}
690 697
@@ -695,7 +702,7 @@ static int __follow_mount(struct path *path)
695{ 702{
696 int res = 0; 703 int res = 0;
697 while (d_mountpoint(path->dentry)) { 704 while (d_mountpoint(path->dentry)) {
698 struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry); 705 struct vfsmount *mounted = lookup_mnt(path);
699 if (!mounted) 706 if (!mounted)
700 break; 707 break;
701 dput(path->dentry); 708 dput(path->dentry);
@@ -708,32 +715,32 @@ static int __follow_mount(struct path *path)
708 return res; 715 return res;
709} 716}
710 717
711static void follow_mount(struct vfsmount **mnt, struct dentry **dentry) 718static void follow_mount(struct path *path)
712{ 719{
713 while (d_mountpoint(*dentry)) { 720 while (d_mountpoint(path->dentry)) {
714 struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); 721 struct vfsmount *mounted = lookup_mnt(path);
715 if (!mounted) 722 if (!mounted)
716 break; 723 break;
717 dput(*dentry); 724 dput(path->dentry);
718 mntput(*mnt); 725 mntput(path->mnt);
719 *mnt = mounted; 726 path->mnt = mounted;
720 *dentry = dget(mounted->mnt_root); 727 path->dentry = dget(mounted->mnt_root);
721 } 728 }
722} 729}
723 730
724/* no need for dcache_lock, as serialization is taken care in 731/* no need for dcache_lock, as serialization is taken care in
725 * namespace.c 732 * namespace.c
726 */ 733 */
727int follow_down(struct vfsmount **mnt, struct dentry **dentry) 734int follow_down(struct path *path)
728{ 735{
729 struct vfsmount *mounted; 736 struct vfsmount *mounted;
730 737
731 mounted = lookup_mnt(*mnt, *dentry); 738 mounted = lookup_mnt(path);
732 if (mounted) { 739 if (mounted) {
733 dput(*dentry); 740 dput(path->dentry);
734 mntput(*mnt); 741 mntput(path->mnt);
735 *mnt = mounted; 742 path->mnt = mounted;
736 *dentry = dget(mounted->mnt_root); 743 path->dentry = dget(mounted->mnt_root);
737 return 1; 744 return 1;
738 } 745 }
739 return 0; 746 return 0;
@@ -741,19 +748,16 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
741 748
742static __always_inline void follow_dotdot(struct nameidata *nd) 749static __always_inline void follow_dotdot(struct nameidata *nd)
743{ 750{
744 struct fs_struct *fs = current->fs; 751 set_root(nd);
745 752
746 while(1) { 753 while(1) {
747 struct vfsmount *parent; 754 struct vfsmount *parent;
748 struct dentry *old = nd->path.dentry; 755 struct dentry *old = nd->path.dentry;
749 756
750 read_lock(&fs->lock); 757 if (nd->path.dentry == nd->root.dentry &&
751 if (nd->path.dentry == fs->root.dentry && 758 nd->path.mnt == nd->root.mnt) {
752 nd->path.mnt == fs->root.mnt) {
753 read_unlock(&fs->lock);
754 break; 759 break;
755 } 760 }
756 read_unlock(&fs->lock);
757 spin_lock(&dcache_lock); 761 spin_lock(&dcache_lock);
758 if (nd->path.dentry != nd->path.mnt->mnt_root) { 762 if (nd->path.dentry != nd->path.mnt->mnt_root) {
759 nd->path.dentry = dget(nd->path.dentry->d_parent); 763 nd->path.dentry = dget(nd->path.dentry->d_parent);
@@ -775,7 +779,7 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
775 mntput(nd->path.mnt); 779 mntput(nd->path.mnt);
776 nd->path.mnt = parent; 780 nd->path.mnt = parent;
777 } 781 }
778 follow_mount(&nd->path.mnt, &nd->path.dentry); 782 follow_mount(&nd->path);
779} 783}
780 784
781/* 785/*
@@ -1017,25 +1021,23 @@ static int path_walk(const char *name, struct nameidata *nd)
1017 return link_path_walk(name, nd); 1021 return link_path_walk(name, nd);
1018} 1022}
1019 1023
1020/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ 1024static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
1021static int do_path_lookup(int dfd, const char *name,
1022 unsigned int flags, struct nameidata *nd)
1023{ 1025{
1024 int retval = 0; 1026 int retval = 0;
1025 int fput_needed; 1027 int fput_needed;
1026 struct file *file; 1028 struct file *file;
1027 struct fs_struct *fs = current->fs;
1028 1029
1029 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1030 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1030 nd->flags = flags; 1031 nd->flags = flags;
1031 nd->depth = 0; 1032 nd->depth = 0;
1033 nd->root.mnt = NULL;
1032 1034
1033 if (*name=='/') { 1035 if (*name=='/') {
1034 read_lock(&fs->lock); 1036 set_root(nd);
1035 nd->path = fs->root; 1037 nd->path = nd->root;
1036 path_get(&fs->root); 1038 path_get(&nd->root);
1037 read_unlock(&fs->lock);
1038 } else if (dfd == AT_FDCWD) { 1039 } else if (dfd == AT_FDCWD) {
1040 struct fs_struct *fs = current->fs;
1039 read_lock(&fs->lock); 1041 read_lock(&fs->lock);
1040 nd->path = fs->pwd; 1042 nd->path = fs->pwd;
1041 path_get(&fs->pwd); 1043 path_get(&fs->pwd);
@@ -1063,17 +1065,29 @@ static int do_path_lookup(int dfd, const char *name,
1063 1065
1064 fput_light(file, fput_needed); 1066 fput_light(file, fput_needed);
1065 } 1067 }
1068 return 0;
1066 1069
1067 retval = path_walk(name, nd); 1070fput_fail:
1071 fput_light(file, fput_needed);
1072out_fail:
1073 return retval;
1074}
1075
1076/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
1077static int do_path_lookup(int dfd, const char *name,
1078 unsigned int flags, struct nameidata *nd)
1079{
1080 int retval = path_init(dfd, name, flags, nd);
1081 if (!retval)
1082 retval = path_walk(name, nd);
1068 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1083 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
1069 nd->path.dentry->d_inode)) 1084 nd->path.dentry->d_inode))
1070 audit_inode(name, nd->path.dentry); 1085 audit_inode(name, nd->path.dentry);
1071out_fail: 1086 if (nd->root.mnt) {
1087 path_put(&nd->root);
1088 nd->root.mnt = NULL;
1089 }
1072 return retval; 1090 return retval;
1073
1074fput_fail:
1075 fput_light(file, fput_needed);
1076 goto out_fail;
1077} 1091}
1078 1092
1079int path_lookup(const char *name, unsigned int flags, 1093int path_lookup(const char *name, unsigned int flags,
@@ -1113,14 +1127,18 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1113 nd->path.dentry = dentry; 1127 nd->path.dentry = dentry;
1114 nd->path.mnt = mnt; 1128 nd->path.mnt = mnt;
1115 path_get(&nd->path); 1129 path_get(&nd->path);
1130 nd->root = nd->path;
1131 path_get(&nd->root);
1116 1132
1117 retval = path_walk(name, nd); 1133 retval = path_walk(name, nd);
1118 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1134 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
1119 nd->path.dentry->d_inode)) 1135 nd->path.dentry->d_inode))
1120 audit_inode(name, nd->path.dentry); 1136 audit_inode(name, nd->path.dentry);
1121 1137
1122 return retval; 1138 path_put(&nd->root);
1139 nd->root.mnt = NULL;
1123 1140
1141 return retval;
1124} 1142}
1125 1143
1126/** 1144/**
@@ -1676,9 +1694,14 @@ struct file *do_filp_open(int dfd, const char *pathname,
1676 /* 1694 /*
1677 * Create - we need to know the parent. 1695 * Create - we need to know the parent.
1678 */ 1696 */
1679 error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd); 1697 error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
1680 if (error) 1698 if (error)
1681 return ERR_PTR(error); 1699 return ERR_PTR(error);
1700 error = path_walk(pathname, &nd);
1701 if (error)
1702 return ERR_PTR(error);
1703 if (unlikely(!audit_dummy_context()))
1704 audit_inode(pathname, nd.path.dentry);
1682 1705
1683 /* 1706 /*
1684 * We have the parent and last component. First of all, check 1707 * We have the parent and last component. First of all, check
@@ -1806,6 +1829,8 @@ exit:
1806 if (!IS_ERR(nd.intent.open.file)) 1829 if (!IS_ERR(nd.intent.open.file))
1807 release_open_intent(&nd); 1830 release_open_intent(&nd);
1808exit_parent: 1831exit_parent:
1832 if (nd.root.mnt)
1833 path_put(&nd.root);
1809 path_put(&nd.path); 1834 path_put(&nd.path);
1810 return ERR_PTR(error); 1835 return ERR_PTR(error);
1811 1836
diff --git a/fs/namespace.c b/fs/namespace.c
index 134d494158d9..2dd333b0fe7f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -131,10 +131,20 @@ struct vfsmount *alloc_vfsmnt(const char *name)
131 INIT_LIST_HEAD(&mnt->mnt_share); 131 INIT_LIST_HEAD(&mnt->mnt_share);
132 INIT_LIST_HEAD(&mnt->mnt_slave_list); 132 INIT_LIST_HEAD(&mnt->mnt_slave_list);
133 INIT_LIST_HEAD(&mnt->mnt_slave); 133 INIT_LIST_HEAD(&mnt->mnt_slave);
134 atomic_set(&mnt->__mnt_writers, 0); 134#ifdef CONFIG_SMP
135 mnt->mnt_writers = alloc_percpu(int);
136 if (!mnt->mnt_writers)
137 goto out_free_devname;
138#else
139 mnt->mnt_writers = 0;
140#endif
135 } 141 }
136 return mnt; 142 return mnt;
137 143
144#ifdef CONFIG_SMP
145out_free_devname:
146 kfree(mnt->mnt_devname);
147#endif
138out_free_id: 148out_free_id:
139 mnt_free_id(mnt); 149 mnt_free_id(mnt);
140out_free_cache: 150out_free_cache:
@@ -171,65 +181,38 @@ int __mnt_is_readonly(struct vfsmount *mnt)
171} 181}
172EXPORT_SYMBOL_GPL(__mnt_is_readonly); 182EXPORT_SYMBOL_GPL(__mnt_is_readonly);
173 183
174struct mnt_writer { 184static inline void inc_mnt_writers(struct vfsmount *mnt)
175 /* 185{
176 * If holding multiple instances of this lock, they 186#ifdef CONFIG_SMP
177 * must be ordered by cpu number. 187 (*per_cpu_ptr(mnt->mnt_writers, smp_processor_id()))++;
178 */ 188#else
179 spinlock_t lock; 189 mnt->mnt_writers++;
180 struct lock_class_key lock_class; /* compiles out with !lockdep */ 190#endif
181 unsigned long count; 191}
182 struct vfsmount *mnt;
183} ____cacheline_aligned_in_smp;
184static DEFINE_PER_CPU(struct mnt_writer, mnt_writers);
185 192
186static int __init init_mnt_writers(void) 193static inline void dec_mnt_writers(struct vfsmount *mnt)
187{ 194{
188 int cpu; 195#ifdef CONFIG_SMP
189 for_each_possible_cpu(cpu) { 196 (*per_cpu_ptr(mnt->mnt_writers, smp_processor_id()))--;
190 struct mnt_writer *writer = &per_cpu(mnt_writers, cpu); 197#else
191 spin_lock_init(&writer->lock); 198 mnt->mnt_writers--;
192 lockdep_set_class(&writer->lock, &writer->lock_class); 199#endif
193 writer->count = 0;
194 }
195 return 0;
196} 200}
197fs_initcall(init_mnt_writers);
198 201
199static void unlock_mnt_writers(void) 202static unsigned int count_mnt_writers(struct vfsmount *mnt)
200{ 203{
204#ifdef CONFIG_SMP
205 unsigned int count = 0;
201 int cpu; 206 int cpu;
202 struct mnt_writer *cpu_writer;
203 207
204 for_each_possible_cpu(cpu) { 208 for_each_possible_cpu(cpu) {
205 cpu_writer = &per_cpu(mnt_writers, cpu); 209 count += *per_cpu_ptr(mnt->mnt_writers, cpu);
206 spin_unlock(&cpu_writer->lock);
207 } 210 }
208}
209 211
210static inline void __clear_mnt_count(struct mnt_writer *cpu_writer) 212 return count;
211{ 213#else
212 if (!cpu_writer->mnt) 214 return mnt->mnt_writers;
213 return; 215#endif
214 /*
215 * This is in case anyone ever leaves an invalid,
216 * old ->mnt and a count of 0.
217 */
218 if (!cpu_writer->count)
219 return;
220 atomic_add(cpu_writer->count, &cpu_writer->mnt->__mnt_writers);
221 cpu_writer->count = 0;
222}
223 /*
224 * must hold cpu_writer->lock
225 */
226static inline void use_cpu_writer_for_mount(struct mnt_writer *cpu_writer,
227 struct vfsmount *mnt)
228{
229 if (cpu_writer->mnt == mnt)
230 return;
231 __clear_mnt_count(cpu_writer);
232 cpu_writer->mnt = mnt;
233} 216}
234 217
235/* 218/*
@@ -253,74 +236,73 @@ static inline void use_cpu_writer_for_mount(struct mnt_writer *cpu_writer,
253int mnt_want_write(struct vfsmount *mnt) 236int mnt_want_write(struct vfsmount *mnt)
254{ 237{
255 int ret = 0; 238 int ret = 0;
256 struct mnt_writer *cpu_writer;
257 239
258 cpu_writer = &get_cpu_var(mnt_writers); 240 preempt_disable();
259 spin_lock(&cpu_writer->lock); 241 inc_mnt_writers(mnt);
242 /*
243 * The store to inc_mnt_writers must be visible before we pass
244 * MNT_WRITE_HOLD loop below, so that the slowpath can see our
245 * incremented count after it has set MNT_WRITE_HOLD.
246 */
247 smp_mb();
248 while (mnt->mnt_flags & MNT_WRITE_HOLD)
249 cpu_relax();
250 /*
251 * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will
252 * be set to match its requirements. So we must not load that until
253 * MNT_WRITE_HOLD is cleared.
254 */
255 smp_rmb();
260 if (__mnt_is_readonly(mnt)) { 256 if (__mnt_is_readonly(mnt)) {
257 dec_mnt_writers(mnt);
261 ret = -EROFS; 258 ret = -EROFS;
262 goto out; 259 goto out;
263 } 260 }
264 use_cpu_writer_for_mount(cpu_writer, mnt);
265 cpu_writer->count++;
266out: 261out:
267 spin_unlock(&cpu_writer->lock); 262 preempt_enable();
268 put_cpu_var(mnt_writers);
269 return ret; 263 return ret;
270} 264}
271EXPORT_SYMBOL_GPL(mnt_want_write); 265EXPORT_SYMBOL_GPL(mnt_want_write);
272 266
273static void lock_mnt_writers(void) 267/**
274{ 268 * mnt_clone_write - get write access to a mount
275 int cpu; 269 * @mnt: the mount on which to take a write
276 struct mnt_writer *cpu_writer; 270 *
277 271 * This is effectively like mnt_want_write, except
278 for_each_possible_cpu(cpu) { 272 * it must only be used to take an extra write reference
279 cpu_writer = &per_cpu(mnt_writers, cpu); 273 * on a mountpoint that we already know has a write reference
280 spin_lock(&cpu_writer->lock); 274 * on it. This allows some optimisation.
281 __clear_mnt_count(cpu_writer); 275 *
282 cpu_writer->mnt = NULL; 276 * After finished, mnt_drop_write must be called as usual to
283 } 277 * drop the reference.
278 */
279int mnt_clone_write(struct vfsmount *mnt)
280{
281 /* superblock may be r/o */
282 if (__mnt_is_readonly(mnt))
283 return -EROFS;
284 preempt_disable();
285 inc_mnt_writers(mnt);
286 preempt_enable();
287 return 0;
284} 288}
289EXPORT_SYMBOL_GPL(mnt_clone_write);
285 290
286/* 291/**
287 * These per-cpu write counts are not guaranteed to have 292 * mnt_want_write_file - get write access to a file's mount
288 * matched increments and decrements on any given cpu. 293 * @file: the file who's mount on which to take a write
289 * A file open()ed for write on one cpu and close()d on 294 *
290 * another cpu will imbalance this count. Make sure it 295 * This is like mnt_want_write, but it takes a file and can
291 * does not get too far out of whack. 296 * do some optimisations if the file is open for write already
292 */ 297 */
293static void handle_write_count_underflow(struct vfsmount *mnt) 298int mnt_want_write_file(struct file *file)
294{ 299{
295 if (atomic_read(&mnt->__mnt_writers) >= 300 if (!(file->f_mode & FMODE_WRITE))
296 MNT_WRITER_UNDERFLOW_LIMIT) 301 return mnt_want_write(file->f_path.mnt);
297 return; 302 else
298 /* 303 return mnt_clone_write(file->f_path.mnt);
299 * It isn't necessary to hold all of the locks
300 * at the same time, but doing it this way makes
301 * us share a lot more code.
302 */
303 lock_mnt_writers();
304 /*
305 * vfsmount_lock is for mnt_flags.
306 */
307 spin_lock(&vfsmount_lock);
308 /*
309 * If coalescing the per-cpu writer counts did not
310 * get us back to a positive writer count, we have
311 * a bug.
312 */
313 if ((atomic_read(&mnt->__mnt_writers) < 0) &&
314 !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) {
315 WARN(1, KERN_DEBUG "leak detected on mount(%p) writers "
316 "count: %d\n",
317 mnt, atomic_read(&mnt->__mnt_writers));
318 /* use the flag to keep the dmesg spam down */
319 mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT;
320 }
321 spin_unlock(&vfsmount_lock);
322 unlock_mnt_writers();
323} 304}
305EXPORT_SYMBOL_GPL(mnt_want_write_file);
324 306
325/** 307/**
326 * mnt_drop_write - give up write access to a mount 308 * mnt_drop_write - give up write access to a mount
@@ -332,37 +314,9 @@ static void handle_write_count_underflow(struct vfsmount *mnt)
332 */ 314 */
333void mnt_drop_write(struct vfsmount *mnt) 315void mnt_drop_write(struct vfsmount *mnt)
334{ 316{
335 int must_check_underflow = 0; 317 preempt_disable();
336 struct mnt_writer *cpu_writer; 318 dec_mnt_writers(mnt);
337 319 preempt_enable();
338 cpu_writer = &get_cpu_var(mnt_writers);
339 spin_lock(&cpu_writer->lock);
340
341 use_cpu_writer_for_mount(cpu_writer, mnt);
342 if (cpu_writer->count > 0) {
343 cpu_writer->count--;
344 } else {
345 must_check_underflow = 1;
346 atomic_dec(&mnt->__mnt_writers);
347 }
348
349 spin_unlock(&cpu_writer->lock);
350 /*
351 * Logically, we could call this each time,
352 * but the __mnt_writers cacheline tends to
353 * be cold, and makes this expensive.
354 */
355 if (must_check_underflow)
356 handle_write_count_underflow(mnt);
357 /*
358 * This could be done right after the spinlock
359 * is taken because the spinlock keeps us on
360 * the cpu, and disables preemption. However,
361 * putting it here bounds the amount that
362 * __mnt_writers can underflow. Without it,
363 * we could theoretically wrap __mnt_writers.
364 */
365 put_cpu_var(mnt_writers);
366} 320}
367EXPORT_SYMBOL_GPL(mnt_drop_write); 321EXPORT_SYMBOL_GPL(mnt_drop_write);
368 322
@@ -370,24 +324,41 @@ static int mnt_make_readonly(struct vfsmount *mnt)
370{ 324{
371 int ret = 0; 325 int ret = 0;
372 326
373 lock_mnt_writers(); 327 spin_lock(&vfsmount_lock);
328 mnt->mnt_flags |= MNT_WRITE_HOLD;
374 /* 329 /*
375 * With all the locks held, this value is stable 330 * After storing MNT_WRITE_HOLD, we'll read the counters. This store
331 * should be visible before we do.
376 */ 332 */
377 if (atomic_read(&mnt->__mnt_writers) > 0) { 333 smp_mb();
378 ret = -EBUSY; 334
379 goto out;
380 }
381 /* 335 /*
382 * nobody can do a successful mnt_want_write() with all 336 * With writers on hold, if this value is zero, then there are
383 * of the counts in MNT_DENIED_WRITE and the locks held. 337 * definitely no active writers (although held writers may subsequently
338 * increment the count, they'll have to wait, and decrement it after
339 * seeing MNT_READONLY).
340 *
341 * It is OK to have counter incremented on one CPU and decremented on
342 * another: the sum will add up correctly. The danger would be when we
343 * sum up each counter, if we read a counter before it is incremented,
344 * but then read another CPU's count which it has been subsequently
345 * decremented from -- we would see more decrements than we should.
346 * MNT_WRITE_HOLD protects against this scenario, because
347 * mnt_want_write first increments count, then smp_mb, then spins on
348 * MNT_WRITE_HOLD, so it can't be decremented by another CPU while
349 * we're counting up here.
384 */ 350 */
385 spin_lock(&vfsmount_lock); 351 if (count_mnt_writers(mnt) > 0)
386 if (!ret) 352 ret = -EBUSY;
353 else
387 mnt->mnt_flags |= MNT_READONLY; 354 mnt->mnt_flags |= MNT_READONLY;
355 /*
356 * MNT_READONLY must become visible before ~MNT_WRITE_HOLD, so writers
357 * that become unheld will see MNT_READONLY.
358 */
359 smp_wmb();
360 mnt->mnt_flags &= ~MNT_WRITE_HOLD;
388 spin_unlock(&vfsmount_lock); 361 spin_unlock(&vfsmount_lock);
389out:
390 unlock_mnt_writers();
391 return ret; 362 return ret;
392} 363}
393 364
@@ -410,6 +381,9 @@ void free_vfsmnt(struct vfsmount *mnt)
410{ 381{
411 kfree(mnt->mnt_devname); 382 kfree(mnt->mnt_devname);
412 mnt_free_id(mnt); 383 mnt_free_id(mnt);
384#ifdef CONFIG_SMP
385 free_percpu(mnt->mnt_writers);
386#endif
413 kmem_cache_free(mnt_cache, mnt); 387 kmem_cache_free(mnt_cache, mnt);
414} 388}
415 389
@@ -442,11 +416,11 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
442 * lookup_mnt increments the ref count before returning 416 * lookup_mnt increments the ref count before returning
443 * the vfsmount struct. 417 * the vfsmount struct.
444 */ 418 */
445struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry) 419struct vfsmount *lookup_mnt(struct path *path)
446{ 420{
447 struct vfsmount *child_mnt; 421 struct vfsmount *child_mnt;
448 spin_lock(&vfsmount_lock); 422 spin_lock(&vfsmount_lock);
449 if ((child_mnt = __lookup_mnt(mnt, dentry, 1))) 423 if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1)))
450 mntget(child_mnt); 424 mntget(child_mnt);
451 spin_unlock(&vfsmount_lock); 425 spin_unlock(&vfsmount_lock);
452 return child_mnt; 426 return child_mnt;
@@ -604,38 +578,18 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
604 578
605static inline void __mntput(struct vfsmount *mnt) 579static inline void __mntput(struct vfsmount *mnt)
606{ 580{
607 int cpu;
608 struct super_block *sb = mnt->mnt_sb; 581 struct super_block *sb = mnt->mnt_sb;
609 /* 582 /*
610 * We don't have to hold all of the locks at the
611 * same time here because we know that we're the
612 * last reference to mnt and that no new writers
613 * can come in.
614 */
615 for_each_possible_cpu(cpu) {
616 struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu);
617 spin_lock(&cpu_writer->lock);
618 if (cpu_writer->mnt != mnt) {
619 spin_unlock(&cpu_writer->lock);
620 continue;
621 }
622 atomic_add(cpu_writer->count, &mnt->__mnt_writers);
623 cpu_writer->count = 0;
624 /*
625 * Might as well do this so that no one
626 * ever sees the pointer and expects
627 * it to be valid.
628 */
629 cpu_writer->mnt = NULL;
630 spin_unlock(&cpu_writer->lock);
631 }
632 /*
633 * This probably indicates that somebody messed 583 * This probably indicates that somebody messed
634 * up a mnt_want/drop_write() pair. If this 584 * up a mnt_want/drop_write() pair. If this
635 * happens, the filesystem was probably unable 585 * happens, the filesystem was probably unable
636 * to make r/w->r/o transitions. 586 * to make r/w->r/o transitions.
637 */ 587 */
638 WARN_ON(atomic_read(&mnt->__mnt_writers)); 588 /*
589 * atomic_dec_and_lock() used to deal with ->mnt_count decrements
590 * provides barriers, so count_mnt_writers() below is safe. AV
591 */
592 WARN_ON(count_mnt_writers(mnt));
639 dput(mnt->mnt_root); 593 dput(mnt->mnt_root);
640 free_vfsmnt(mnt); 594 free_vfsmnt(mnt);
641 deactivate_super(sb); 595 deactivate_super(sb);
@@ -1106,11 +1060,8 @@ static int do_umount(struct vfsmount *mnt, int flags)
1106 * we just try to remount it readonly. 1060 * we just try to remount it readonly.
1107 */ 1061 */
1108 down_write(&sb->s_umount); 1062 down_write(&sb->s_umount);
1109 if (!(sb->s_flags & MS_RDONLY)) { 1063 if (!(sb->s_flags & MS_RDONLY))
1110 lock_kernel();
1111 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); 1064 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
1112 unlock_kernel();
1113 }
1114 up_write(&sb->s_umount); 1065 up_write(&sb->s_umount);
1115 return retval; 1066 return retval;
1116 } 1067 }
@@ -1253,11 +1204,11 @@ Enomem:
1253 return NULL; 1204 return NULL;
1254} 1205}
1255 1206
1256struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry) 1207struct vfsmount *collect_mounts(struct path *path)
1257{ 1208{
1258 struct vfsmount *tree; 1209 struct vfsmount *tree;
1259 down_write(&namespace_sem); 1210 down_write(&namespace_sem);
1260 tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE); 1211 tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE);
1261 up_write(&namespace_sem); 1212 up_write(&namespace_sem);
1262 return tree; 1213 return tree;
1263} 1214}
@@ -1430,7 +1381,7 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
1430 goto out_unlock; 1381 goto out_unlock;
1431 1382
1432 err = -ENOENT; 1383 err = -ENOENT;
1433 if (IS_ROOT(path->dentry) || !d_unhashed(path->dentry)) 1384 if (!d_unlinked(path->dentry))
1434 err = attach_recursive_mnt(mnt, path, NULL); 1385 err = attach_recursive_mnt(mnt, path, NULL);
1435out_unlock: 1386out_unlock:
1436 mutex_unlock(&path->dentry->d_inode->i_mutex); 1387 mutex_unlock(&path->dentry->d_inode->i_mutex);
@@ -1601,7 +1552,7 @@ static int do_move_mount(struct path *path, char *old_name)
1601 1552
1602 down_write(&namespace_sem); 1553 down_write(&namespace_sem);
1603 while (d_mountpoint(path->dentry) && 1554 while (d_mountpoint(path->dentry) &&
1604 follow_down(&path->mnt, &path->dentry)) 1555 follow_down(path))
1605 ; 1556 ;
1606 err = -EINVAL; 1557 err = -EINVAL;
1607 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt)) 1558 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
@@ -1612,7 +1563,7 @@ static int do_move_mount(struct path *path, char *old_name)
1612 if (IS_DEADDIR(path->dentry->d_inode)) 1563 if (IS_DEADDIR(path->dentry->d_inode))
1613 goto out1; 1564 goto out1;
1614 1565
1615 if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry)) 1566 if (d_unlinked(path->dentry))
1616 goto out1; 1567 goto out1;
1617 1568
1618 err = -EINVAL; 1569 err = -EINVAL;
@@ -1676,7 +1627,9 @@ static int do_new_mount(struct path *path, char *type, int flags,
1676 if (!capable(CAP_SYS_ADMIN)) 1627 if (!capable(CAP_SYS_ADMIN))
1677 return -EPERM; 1628 return -EPERM;
1678 1629
1630 lock_kernel();
1679 mnt = do_kern_mount(type, flags, name, data); 1631 mnt = do_kern_mount(type, flags, name, data);
1632 unlock_kernel();
1680 if (IS_ERR(mnt)) 1633 if (IS_ERR(mnt))
1681 return PTR_ERR(mnt); 1634 return PTR_ERR(mnt);
1682 1635
@@ -1695,10 +1648,10 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path,
1695 down_write(&namespace_sem); 1648 down_write(&namespace_sem);
1696 /* Something was mounted here while we slept */ 1649 /* Something was mounted here while we slept */
1697 while (d_mountpoint(path->dentry) && 1650 while (d_mountpoint(path->dentry) &&
1698 follow_down(&path->mnt, &path->dentry)) 1651 follow_down(path))
1699 ; 1652 ;
1700 err = -EINVAL; 1653 err = -EINVAL;
1701 if (!check_mnt(path->mnt)) 1654 if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
1702 goto unlock; 1655 goto unlock;
1703 1656
1704 /* Refuse the same filesystem on the same mount point */ 1657 /* Refuse the same filesystem on the same mount point */
@@ -2092,10 +2045,8 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2092 if (retval < 0) 2045 if (retval < 0)
2093 goto out3; 2046 goto out3;
2094 2047
2095 lock_kernel();
2096 retval = do_mount((char *)dev_page, dir_page, (char *)type_page, 2048 retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
2097 flags, (void *)data_page); 2049 flags, (void *)data_page);
2098 unlock_kernel();
2099 free_page(data_page); 2050 free_page(data_page);
2100 2051
2101out3: 2052out3:
@@ -2175,9 +2126,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2175 error = -ENOENT; 2126 error = -ENOENT;
2176 if (IS_DEADDIR(new.dentry->d_inode)) 2127 if (IS_DEADDIR(new.dentry->d_inode))
2177 goto out2; 2128 goto out2;
2178 if (d_unhashed(new.dentry) && !IS_ROOT(new.dentry)) 2129 if (d_unlinked(new.dentry))
2179 goto out2; 2130 goto out2;
2180 if (d_unhashed(old.dentry) && !IS_ROOT(old.dentry)) 2131 if (d_unlinked(old.dentry))
2181 goto out2; 2132 goto out2;
2182 error = -EBUSY; 2133 error = -EBUSY;
2183 if (new.mnt == root.mnt || 2134 if (new.mnt == root.mnt ||
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index d642f0e5b365..b99ce205b1bd 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -736,6 +736,8 @@ static void ncp_put_super(struct super_block *sb)
736{ 736{
737 struct ncp_server *server = NCP_SBP(sb); 737 struct ncp_server *server = NCP_SBP(sb);
738 738
739 lock_kernel();
740
739 ncp_lock_server(server); 741 ncp_lock_server(server);
740 ncp_disconnect(server); 742 ncp_disconnect(server);
741 ncp_unlock_server(server); 743 ncp_unlock_server(server);
@@ -769,6 +771,8 @@ static void ncp_put_super(struct super_block *sb)
769 vfree(server->packet); 771 vfree(server->packet);
770 sb->s_fs_info = NULL; 772 sb->s_fs_info = NULL;
771 kfree(server); 773 kfree(server);
774
775 unlock_kernel();
772} 776}
773 777
774static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) 778static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 64a288ee046d..f01caec84463 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -154,7 +154,7 @@ out_err:
154 goto out; 154 goto out;
155out_follow: 155out_follow:
156 while (d_mountpoint(nd->path.dentry) && 156 while (d_mountpoint(nd->path.dentry) &&
157 follow_down(&nd->path.mnt, &nd->path.dentry)) 157 follow_down(&nd->path))
158 ; 158 ;
159 err = 0; 159 err = 0;
160 goto out; 160 goto out;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index d2d67781c579..26127b69a275 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1813,6 +1813,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1813 if (data == NULL) 1813 if (data == NULL)
1814 return -ENOMEM; 1814 return -ENOMEM;
1815 1815
1816 lock_kernel();
1816 /* fill out struct with values from existing mount */ 1817 /* fill out struct with values from existing mount */
1817 data->flags = nfss->flags; 1818 data->flags = nfss->flags;
1818 data->rsize = nfss->rsize; 1819 data->rsize = nfss->rsize;
@@ -1837,6 +1838,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1837 error = nfs_compare_remount_data(nfss, data); 1838 error = nfs_compare_remount_data(nfss, data);
1838out: 1839out:
1839 kfree(data); 1840 kfree(data);
1841 unlock_kernel();
1840 return error; 1842 return error;
1841} 1843}
1842 1844
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 5839b229cd0e..8b1f8efb4690 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -847,9 +847,8 @@ exp_get_fsid_key(svc_client *clp, int fsid)
847 return exp_find_key(clp, FSID_NUM, fsidv, NULL); 847 return exp_find_key(clp, FSID_NUM, fsidv, NULL);
848} 848}
849 849
850static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt, 850static svc_export *exp_get_by_name(svc_client *clp, const struct path *path,
851 struct dentry *dentry, 851 struct cache_req *reqp)
852 struct cache_req *reqp)
853{ 852{
854 struct svc_export *exp, key; 853 struct svc_export *exp, key;
855 int err; 854 int err;
@@ -858,8 +857,7 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
858 return ERR_PTR(-ENOENT); 857 return ERR_PTR(-ENOENT);
859 858
860 key.ex_client = clp; 859 key.ex_client = clp;
861 key.ex_path.mnt = mnt; 860 key.ex_path = *path;
862 key.ex_path.dentry = dentry;
863 861
864 exp = svc_export_lookup(&key); 862 exp = svc_export_lookup(&key);
865 if (exp == NULL) 863 if (exp == NULL)
@@ -873,24 +871,19 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
873/* 871/*
874 * Find the export entry for a given dentry. 872 * Find the export entry for a given dentry.
875 */ 873 */
876static struct svc_export *exp_parent(svc_client *clp, struct vfsmount *mnt, 874static struct svc_export *exp_parent(svc_client *clp, struct path *path)
877 struct dentry *dentry,
878 struct cache_req *reqp)
879{ 875{
880 svc_export *exp; 876 struct dentry *saved = dget(path->dentry);
881 877 svc_export *exp = exp_get_by_name(clp, path, NULL);
882 dget(dentry); 878
883 exp = exp_get_by_name(clp, mnt, dentry, reqp); 879 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
884 880 struct dentry *parent = dget_parent(path->dentry);
885 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { 881 dput(path->dentry);
886 struct dentry *parent; 882 path->dentry = parent;
887 883 exp = exp_get_by_name(clp, path, NULL);
888 parent = dget_parent(dentry);
889 dput(dentry);
890 dentry = parent;
891 exp = exp_get_by_name(clp, mnt, dentry, reqp);
892 } 884 }
893 dput(dentry); 885 dput(path->dentry);
886 path->dentry = saved;
894 return exp; 887 return exp;
895} 888}
896 889
@@ -1018,7 +1011,7 @@ exp_export(struct nfsctl_export *nxp)
1018 goto out_put_clp; 1011 goto out_put_clp;
1019 err = -EINVAL; 1012 err = -EINVAL;
1020 1013
1021 exp = exp_get_by_name(clp, path.mnt, path.dentry, NULL); 1014 exp = exp_get_by_name(clp, &path, NULL);
1022 1015
1023 memset(&new, 0, sizeof(new)); 1016 memset(&new, 0, sizeof(new));
1024 1017
@@ -1135,7 +1128,7 @@ exp_unexport(struct nfsctl_export *nxp)
1135 goto out_domain; 1128 goto out_domain;
1136 1129
1137 err = -EINVAL; 1130 err = -EINVAL;
1138 exp = exp_get_by_name(dom, path.mnt, path.dentry, NULL); 1131 exp = exp_get_by_name(dom, &path, NULL);
1139 path_put(&path); 1132 path_put(&path);
1140 if (IS_ERR(exp)) 1133 if (IS_ERR(exp))
1141 goto out_domain; 1134 goto out_domain;
@@ -1177,7 +1170,7 @@ exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize)
1177 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", 1170 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
1178 name, path.dentry, clp->name, 1171 name, path.dentry, clp->name,
1179 inode->i_sb->s_id, inode->i_ino); 1172 inode->i_sb->s_id, inode->i_ino);
1180 exp = exp_parent(clp, path.mnt, path.dentry, NULL); 1173 exp = exp_parent(clp, &path);
1181 if (IS_ERR(exp)) { 1174 if (IS_ERR(exp)) {
1182 err = PTR_ERR(exp); 1175 err = PTR_ERR(exp);
1183 goto out; 1176 goto out;
@@ -1207,7 +1200,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
1207 if (IS_ERR(ek)) 1200 if (IS_ERR(ek))
1208 return ERR_CAST(ek); 1201 return ERR_CAST(ek);
1209 1202
1210 exp = exp_get_by_name(clp, ek->ek_path.mnt, ek->ek_path.dentry, reqp); 1203 exp = exp_get_by_name(clp, &ek->ek_path, reqp);
1211 cache_put(&ek->h, &svc_expkey_cache); 1204 cache_put(&ek->h, &svc_expkey_cache);
1212 1205
1213 if (IS_ERR(exp)) 1206 if (IS_ERR(exp))
@@ -1247,8 +1240,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
1247 * use exp_get_by_name() or exp_find(). 1240 * use exp_get_by_name() or exp_find().
1248 */ 1241 */
1249struct svc_export * 1242struct svc_export *
1250rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt, 1243rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
1251 struct dentry *dentry)
1252{ 1244{
1253 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 1245 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
1254 1246
@@ -1256,8 +1248,7 @@ rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt,
1256 goto gss; 1248 goto gss;
1257 1249
1258 /* First try the auth_unix client: */ 1250 /* First try the auth_unix client: */
1259 exp = exp_get_by_name(rqstp->rq_client, mnt, dentry, 1251 exp = exp_get_by_name(rqstp->rq_client, path, &rqstp->rq_chandle);
1260 &rqstp->rq_chandle);
1261 if (PTR_ERR(exp) == -ENOENT) 1252 if (PTR_ERR(exp) == -ENOENT)
1262 goto gss; 1253 goto gss;
1263 if (IS_ERR(exp)) 1254 if (IS_ERR(exp))
@@ -1269,8 +1260,7 @@ gss:
1269 /* Otherwise, try falling back on gss client */ 1260 /* Otherwise, try falling back on gss client */
1270 if (rqstp->rq_gssclient == NULL) 1261 if (rqstp->rq_gssclient == NULL)
1271 return exp; 1262 return exp;
1272 gssexp = exp_get_by_name(rqstp->rq_gssclient, mnt, dentry, 1263 gssexp = exp_get_by_name(rqstp->rq_gssclient, path, &rqstp->rq_chandle);
1273 &rqstp->rq_chandle);
1274 if (PTR_ERR(gssexp) == -ENOENT) 1264 if (PTR_ERR(gssexp) == -ENOENT)
1275 return exp; 1265 return exp;
1276 if (!IS_ERR(exp)) 1266 if (!IS_ERR(exp))
@@ -1309,23 +1299,19 @@ gss:
1309} 1299}
1310 1300
1311struct svc_export * 1301struct svc_export *
1312rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, 1302rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
1313 struct dentry *dentry)
1314{ 1303{
1315 struct svc_export *exp; 1304 struct dentry *saved = dget(path->dentry);
1316 1305 struct svc_export *exp = rqst_exp_get_by_name(rqstp, path);
1317 dget(dentry); 1306
1318 exp = rqst_exp_get_by_name(rqstp, mnt, dentry); 1307 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
1319 1308 struct dentry *parent = dget_parent(path->dentry);
1320 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { 1309 dput(path->dentry);
1321 struct dentry *parent; 1310 path->dentry = parent;
1322 1311 exp = rqst_exp_get_by_name(rqstp, path);
1323 parent = dget_parent(dentry);
1324 dput(dentry);
1325 dentry = parent;
1326 exp = rqst_exp_get_by_name(rqstp, mnt, dentry);
1327 } 1312 }
1328 dput(dentry); 1313 dput(path->dentry);
1314 path->dentry = saved;
1329 return exp; 1315 return exp;
1330} 1316}
1331 1317
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index bd584bcf1d9f..99f835753596 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -101,36 +101,35 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
101{ 101{
102 struct svc_export *exp = *expp, *exp2 = NULL; 102 struct svc_export *exp = *expp, *exp2 = NULL;
103 struct dentry *dentry = *dpp; 103 struct dentry *dentry = *dpp;
104 struct vfsmount *mnt = mntget(exp->ex_path.mnt); 104 struct path path = {.mnt = mntget(exp->ex_path.mnt),
105 struct dentry *mounts = dget(dentry); 105 .dentry = dget(dentry)};
106 int err = 0; 106 int err = 0;
107 107
108 while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)); 108 while (d_mountpoint(path.dentry) && follow_down(&path))
109 ;
109 110
110 exp2 = rqst_exp_get_by_name(rqstp, mnt, mounts); 111 exp2 = rqst_exp_get_by_name(rqstp, &path);
111 if (IS_ERR(exp2)) { 112 if (IS_ERR(exp2)) {
112 if (PTR_ERR(exp2) != -ENOENT) 113 if (PTR_ERR(exp2) != -ENOENT)
113 err = PTR_ERR(exp2); 114 err = PTR_ERR(exp2);
114 dput(mounts); 115 path_put(&path);
115 mntput(mnt);
116 goto out; 116 goto out;
117 } 117 }
118 if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { 118 if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) {
119 /* successfully crossed mount point */ 119 /* successfully crossed mount point */
120 /* 120 /*
121 * This is subtle: dentry is *not* under mnt at this point. 121 * This is subtle: path.dentry is *not* on path.mnt
122 * The only reason we are safe is that original mnt is pinned 122 * at this point. The only reason we are safe is that
123 * down by exp, so we should dput before putting exp. 123 * original mnt is pinned down by exp, so we should
124 * put path *before* putting exp
124 */ 125 */
125 dput(dentry); 126 *dpp = path.dentry;
126 *dpp = mounts; 127 path.dentry = dentry;
127 exp_put(exp);
128 *expp = exp2; 128 *expp = exp2;
129 } else { 129 exp2 = exp;
130 exp_put(exp2);
131 dput(mounts);
132 } 130 }
133 mntput(mnt); 131 path_put(&path);
132 exp_put(exp2);
134out: 133out:
135 return err; 134 return err;
136} 135}
@@ -169,28 +168,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
169 /* checking mountpoint crossing is very different when stepping up */ 168 /* checking mountpoint crossing is very different when stepping up */
170 struct svc_export *exp2 = NULL; 169 struct svc_export *exp2 = NULL;
171 struct dentry *dp; 170 struct dentry *dp;
172 struct vfsmount *mnt = mntget(exp->ex_path.mnt); 171 struct path path = {.mnt = mntget(exp->ex_path.mnt),
173 dentry = dget(dparent); 172 .dentry = dget(dparent)};
174 while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) 173
174 while (path.dentry == path.mnt->mnt_root &&
175 follow_up(&path))
175 ; 176 ;
176 dp = dget_parent(dentry); 177 dp = dget_parent(path.dentry);
177 dput(dentry); 178 dput(path.dentry);
178 dentry = dp; 179 path.dentry = dp;
179 180
180 exp2 = rqst_exp_parent(rqstp, mnt, dentry); 181 exp2 = rqst_exp_parent(rqstp, &path);
181 if (PTR_ERR(exp2) == -ENOENT) { 182 if (PTR_ERR(exp2) == -ENOENT) {
182 dput(dentry);
183 dentry = dget(dparent); 183 dentry = dget(dparent);
184 } else if (IS_ERR(exp2)) { 184 } else if (IS_ERR(exp2)) {
185 host_err = PTR_ERR(exp2); 185 host_err = PTR_ERR(exp2);
186 dput(dentry); 186 path_put(&path);
187 mntput(mnt);
188 goto out_nfserr; 187 goto out_nfserr;
189 } else { 188 } else {
189 dentry = dget(path.dentry);
190 exp_put(exp); 190 exp_put(exp);
191 exp = exp2; 191 exp = exp2;
192 } 192 }
193 mntput(mnt); 193 path_put(&path);
194 } 194 }
195 } else { 195 } else {
196 fh_lock(fhp); 196 fh_lock(fhp);
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index 300f1cdfa862..cadd36b14d07 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -864,11 +864,11 @@ int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
864 case NILFS_CHECKPOINT: 864 case NILFS_CHECKPOINT:
865 /* 865 /*
866 * Check for protecting existing snapshot mounts: 866 * Check for protecting existing snapshot mounts:
867 * bd_mount_sem is used to make this operation atomic and 867 * ns_mount_mutex is used to make this operation atomic and
868 * exclusive with a new mount job. Though it doesn't cover 868 * exclusive with a new mount job. Though it doesn't cover
869 * umount, it's enough for the purpose. 869 * umount, it's enough for the purpose.
870 */ 870 */
871 down(&nilfs->ns_bdev->bd_mount_sem); 871 mutex_lock(&nilfs->ns_mount_mutex);
872 if (nilfs_checkpoint_is_mounted(nilfs, cno, 1)) { 872 if (nilfs_checkpoint_is_mounted(nilfs, cno, 1)) {
873 /* Current implementation does not have to protect 873 /* Current implementation does not have to protect
874 plain read-only mounts since they are exclusive 874 plain read-only mounts since they are exclusive
@@ -877,7 +877,7 @@ int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
877 ret = -EBUSY; 877 ret = -EBUSY;
878 } else 878 } else
879 ret = nilfs_cpfile_clear_snapshot(cpfile, cno); 879 ret = nilfs_cpfile_clear_snapshot(cpfile, cno);
880 up(&nilfs->ns_bdev->bd_mount_sem); 880 mutex_unlock(&nilfs->ns_mount_mutex);
881 return ret; 881 return ret;
882 case NILFS_SNAPSHOT: 882 case NILFS_SNAPSHOT:
883 return nilfs_cpfile_set_snapshot(cpfile, cno); 883 return nilfs_cpfile_set_snapshot(cpfile, cno);
diff --git a/fs/nilfs2/sb.h b/fs/nilfs2/sb.h
index adccd4fc654e..0776ccc2504a 100644
--- a/fs/nilfs2/sb.h
+++ b/fs/nilfs2/sb.h
@@ -60,6 +60,7 @@ struct nilfs_sb_info {
60 struct super_block *s_super; /* reverse pointer to super_block */ 60 struct super_block *s_super; /* reverse pointer to super_block */
61 struct the_nilfs *s_nilfs; 61 struct the_nilfs *s_nilfs;
62 struct list_head s_list; /* list head for nilfs->ns_supers */ 62 struct list_head s_list; /* list head for nilfs->ns_supers */
63 atomic_t s_count; /* reference count */
63 64
64 /* Segment constructor */ 65 /* Segment constructor */
65 struct list_head s_dirty_files; /* dirty files list */ 66 struct list_head s_dirty_files; /* dirty files list */
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 6989b03e97ab..1777a3467bd2 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -65,9 +65,8 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
65 "(NILFS)"); 65 "(NILFS)");
66MODULE_LICENSE("GPL"); 66MODULE_LICENSE("GPL");
67 67
68static void nilfs_write_super(struct super_block *sb);
68static int nilfs_remount(struct super_block *sb, int *flags, char *data); 69static int nilfs_remount(struct super_block *sb, int *flags, char *data);
69static int test_exclusive_mount(struct file_system_type *fs_type,
70 struct block_device *bdev, int flags);
71 70
72/** 71/**
73 * nilfs_error() - report failure condition on a filesystem 72 * nilfs_error() - report failure condition on a filesystem
@@ -315,6 +314,11 @@ static void nilfs_put_super(struct super_block *sb)
315 struct nilfs_sb_info *sbi = NILFS_SB(sb); 314 struct nilfs_sb_info *sbi = NILFS_SB(sb);
316 struct the_nilfs *nilfs = sbi->s_nilfs; 315 struct the_nilfs *nilfs = sbi->s_nilfs;
317 316
317 lock_kernel();
318
319 if (sb->s_dirt)
320 nilfs_write_super(sb);
321
318 nilfs_detach_segment_constructor(sbi); 322 nilfs_detach_segment_constructor(sbi);
319 323
320 if (!(sb->s_flags & MS_RDONLY)) { 324 if (!(sb->s_flags & MS_RDONLY)) {
@@ -323,12 +327,18 @@ static void nilfs_put_super(struct super_block *sb)
323 nilfs_commit_super(sbi, 1); 327 nilfs_commit_super(sbi, 1);
324 up_write(&nilfs->ns_sem); 328 up_write(&nilfs->ns_sem);
325 } 329 }
330 down_write(&nilfs->ns_super_sem);
331 if (nilfs->ns_current == sbi)
332 nilfs->ns_current = NULL;
333 up_write(&nilfs->ns_super_sem);
326 334
327 nilfs_detach_checkpoint(sbi); 335 nilfs_detach_checkpoint(sbi);
328 put_nilfs(sbi->s_nilfs); 336 put_nilfs(sbi->s_nilfs);
329 sbi->s_super = NULL; 337 sbi->s_super = NULL;
330 sb->s_fs_info = NULL; 338 sb->s_fs_info = NULL;
331 kfree(sbi); 339 nilfs_put_sbinfo(sbi);
340
341 unlock_kernel();
332} 342}
333 343
334/** 344/**
@@ -383,6 +393,8 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
383{ 393{
384 int err = 0; 394 int err = 0;
385 395
396 nilfs_write_super(sb);
397
386 /* This function is called when super block should be written back */ 398 /* This function is called when super block should be written back */
387 if (wait) 399 if (wait)
388 err = nilfs_construct_segment(sb); 400 err = nilfs_construct_segment(sb);
@@ -396,9 +408,9 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
396 struct buffer_head *bh_cp; 408 struct buffer_head *bh_cp;
397 int err; 409 int err;
398 410
399 down_write(&nilfs->ns_sem); 411 down_write(&nilfs->ns_super_sem);
400 list_add(&sbi->s_list, &nilfs->ns_supers); 412 list_add(&sbi->s_list, &nilfs->ns_supers);
401 up_write(&nilfs->ns_sem); 413 up_write(&nilfs->ns_super_sem);
402 414
403 sbi->s_ifile = nilfs_mdt_new( 415 sbi->s_ifile = nilfs_mdt_new(
404 nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP); 416 nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP);
@@ -436,9 +448,9 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
436 nilfs_mdt_destroy(sbi->s_ifile); 448 nilfs_mdt_destroy(sbi->s_ifile);
437 sbi->s_ifile = NULL; 449 sbi->s_ifile = NULL;
438 450
439 down_write(&nilfs->ns_sem); 451 down_write(&nilfs->ns_super_sem);
440 list_del_init(&sbi->s_list); 452 list_del_init(&sbi->s_list);
441 up_write(&nilfs->ns_sem); 453 up_write(&nilfs->ns_super_sem);
442 454
443 return err; 455 return err;
444} 456}
@@ -450,9 +462,9 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
450 nilfs_mdt_clear(sbi->s_ifile); 462 nilfs_mdt_clear(sbi->s_ifile);
451 nilfs_mdt_destroy(sbi->s_ifile); 463 nilfs_mdt_destroy(sbi->s_ifile);
452 sbi->s_ifile = NULL; 464 sbi->s_ifile = NULL;
453 down_write(&nilfs->ns_sem); 465 down_write(&nilfs->ns_super_sem);
454 list_del_init(&sbi->s_list); 466 list_del_init(&sbi->s_list);
455 up_write(&nilfs->ns_sem); 467 up_write(&nilfs->ns_super_sem);
456} 468}
457 469
458static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi) 470static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi)
@@ -752,7 +764,7 @@ int nilfs_store_magic_and_option(struct super_block *sb,
752 * @silent: silent mode flag 764 * @silent: silent mode flag
753 * @nilfs: the_nilfs struct 765 * @nilfs: the_nilfs struct
754 * 766 *
755 * This function is called exclusively by bd_mount_mutex. 767 * This function is called exclusively by nilfs->ns_mount_mutex.
756 * So, the recovery process is protected from other simultaneous mounts. 768 * So, the recovery process is protected from other simultaneous mounts.
757 */ 769 */
758static int 770static int
@@ -773,6 +785,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
773 get_nilfs(nilfs); 785 get_nilfs(nilfs);
774 sbi->s_nilfs = nilfs; 786 sbi->s_nilfs = nilfs;
775 sbi->s_super = sb; 787 sbi->s_super = sb;
788 atomic_set(&sbi->s_count, 1);
776 789
777 err = init_nilfs(nilfs, sbi, (char *)data); 790 err = init_nilfs(nilfs, sbi, (char *)data);
778 if (err) 791 if (err)
@@ -870,6 +883,11 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
870 goto failed_root; 883 goto failed_root;
871 } 884 }
872 885
886 down_write(&nilfs->ns_super_sem);
887 if (!nilfs_test_opt(sbi, SNAPSHOT))
888 nilfs->ns_current = sbi;
889 up_write(&nilfs->ns_super_sem);
890
873 return 0; 891 return 0;
874 892
875 failed_root: 893 failed_root:
@@ -885,7 +903,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
885 failed_sbi: 903 failed_sbi:
886 put_nilfs(nilfs); 904 put_nilfs(nilfs);
887 sb->s_fs_info = NULL; 905 sb->s_fs_info = NULL;
888 kfree(sbi); 906 nilfs_put_sbinfo(sbi);
889 return err; 907 return err;
890} 908}
891 909
@@ -898,6 +916,9 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
898 struct nilfs_mount_options old_opts; 916 struct nilfs_mount_options old_opts;
899 int err; 917 int err;
900 918
919 lock_kernel();
920
921 down_write(&nilfs->ns_super_sem);
901 old_sb_flags = sb->s_flags; 922 old_sb_flags = sb->s_flags;
902 old_opts.mount_opt = sbi->s_mount_opt; 923 old_opts.mount_opt = sbi->s_mount_opt;
903 old_opts.snapshot_cno = sbi->s_snapshot_cno; 924 old_opts.snapshot_cno = sbi->s_snapshot_cno;
@@ -945,14 +966,12 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
945 * store the current valid flag. (It may have been changed 966 * store the current valid flag. (It may have been changed
946 * by fsck since we originally mounted the partition.) 967 * by fsck since we originally mounted the partition.)
947 */ 968 */
948 down(&sb->s_bdev->bd_mount_sem); 969 if (nilfs->ns_current && nilfs->ns_current != sbi) {
949 /* Check existing RW-mount */
950 if (test_exclusive_mount(sb->s_type, sb->s_bdev, 0)) {
951 printk(KERN_WARNING "NILFS (device %s): couldn't " 970 printk(KERN_WARNING "NILFS (device %s): couldn't "
952 "remount because a RW-mount exists.\n", 971 "remount because an RW-mount exists.\n",
953 sb->s_id); 972 sb->s_id);
954 err = -EBUSY; 973 err = -EBUSY;
955 goto rw_remount_failed; 974 goto restore_opts;
956 } 975 }
957 if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) { 976 if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) {
958 printk(KERN_WARNING "NILFS (device %s): couldn't " 977 printk(KERN_WARNING "NILFS (device %s): couldn't "
@@ -960,7 +979,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
960 "the latest one.\n", 979 "the latest one.\n",
961 sb->s_id); 980 sb->s_id);
962 err = -EINVAL; 981 err = -EINVAL;
963 goto rw_remount_failed; 982 goto restore_opts;
964 } 983 }
965 sb->s_flags &= ~MS_RDONLY; 984 sb->s_flags &= ~MS_RDONLY;
966 nilfs_clear_opt(sbi, SNAPSHOT); 985 nilfs_clear_opt(sbi, SNAPSHOT);
@@ -968,28 +987,31 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
968 987
969 err = nilfs_attach_segment_constructor(sbi); 988 err = nilfs_attach_segment_constructor(sbi);
970 if (err) 989 if (err)
971 goto rw_remount_failed; 990 goto restore_opts;
972 991
973 down_write(&nilfs->ns_sem); 992 down_write(&nilfs->ns_sem);
974 nilfs_setup_super(sbi); 993 nilfs_setup_super(sbi);
975 up_write(&nilfs->ns_sem); 994 up_write(&nilfs->ns_sem);
976 995
977 up(&sb->s_bdev->bd_mount_sem); 996 nilfs->ns_current = sbi;
978 } 997 }
979 out: 998 out:
999 up_write(&nilfs->ns_super_sem);
1000 unlock_kernel();
980 return 0; 1001 return 0;
981 1002
982 rw_remount_failed:
983 up(&sb->s_bdev->bd_mount_sem);
984 restore_opts: 1003 restore_opts:
985 sb->s_flags = old_sb_flags; 1004 sb->s_flags = old_sb_flags;
986 sbi->s_mount_opt = old_opts.mount_opt; 1005 sbi->s_mount_opt = old_opts.mount_opt;
987 sbi->s_snapshot_cno = old_opts.snapshot_cno; 1006 sbi->s_snapshot_cno = old_opts.snapshot_cno;
1007 up_write(&nilfs->ns_super_sem);
1008 unlock_kernel();
988 return err; 1009 return err;
989} 1010}
990 1011
991struct nilfs_super_data { 1012struct nilfs_super_data {
992 struct block_device *bdev; 1013 struct block_device *bdev;
1014 struct nilfs_sb_info *sbi;
993 __u64 cno; 1015 __u64 cno;
994 int flags; 1016 int flags;
995}; 1017};
@@ -1048,33 +1070,7 @@ static int nilfs_test_bdev_super(struct super_block *s, void *data)
1048{ 1070{
1049 struct nilfs_super_data *sd = data; 1071 struct nilfs_super_data *sd = data;
1050 1072
1051 return s->s_bdev == sd->bdev; 1073 return sd->sbi && s->s_fs_info == (void *)sd->sbi;
1052}
1053
1054static int nilfs_test_bdev_super2(struct super_block *s, void *data)
1055{
1056 struct nilfs_super_data *sd = data;
1057 int ret;
1058
1059 if (s->s_bdev != sd->bdev)
1060 return 0;
1061
1062 if (!((s->s_flags | sd->flags) & MS_RDONLY))
1063 return 1; /* Reuse an old R/W-mode super_block */
1064
1065 if (s->s_flags & sd->flags & MS_RDONLY) {
1066 if (down_read_trylock(&s->s_umount)) {
1067 ret = s->s_root &&
1068 (sd->cno == NILFS_SB(s)->s_snapshot_cno);
1069 up_read(&s->s_umount);
1070 /*
1071 * This path is locked with sb_lock by sget().
1072 * So, drop_super() causes deadlock.
1073 */
1074 return ret;
1075 }
1076 }
1077 return 0;
1078} 1074}
1079 1075
1080static int 1076static int
@@ -1082,8 +1078,8 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1082 const char *dev_name, void *data, struct vfsmount *mnt) 1078 const char *dev_name, void *data, struct vfsmount *mnt)
1083{ 1079{
1084 struct nilfs_super_data sd; 1080 struct nilfs_super_data sd;
1085 struct super_block *s, *s2; 1081 struct super_block *s;
1086 struct the_nilfs *nilfs = NULL; 1082 struct the_nilfs *nilfs;
1087 int err, need_to_close = 1; 1083 int err, need_to_close = 1;
1088 1084
1089 sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type); 1085 sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type);
@@ -1095,7 +1091,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1095 * much more information than normal filesystems to identify mount 1091 * much more information than normal filesystems to identify mount
1096 * instance. For snapshot mounts, not only a mount type (ro-mount 1092 * instance. For snapshot mounts, not only a mount type (ro-mount
1097 * or rw-mount) but also a checkpoint number is required. 1093 * or rw-mount) but also a checkpoint number is required.
1098 * The results are passed in sget() using nilfs_super_data.
1099 */ 1094 */
1100 sd.cno = 0; 1095 sd.cno = 0;
1101 sd.flags = flags; 1096 sd.flags = flags;
@@ -1104,64 +1099,59 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1104 goto failed; 1099 goto failed;
1105 } 1100 }
1106 1101
1107 /* 1102 nilfs = find_or_create_nilfs(sd.bdev);
1108 * once the super is inserted into the list by sget, s_umount 1103 if (!nilfs) {
1109 * will protect the lockfs code from trying to start a snapshot 1104 err = -ENOMEM;
1110 * while we are mounting 1105 goto failed;
1111 */
1112 down(&sd.bdev->bd_mount_sem);
1113 if (!sd.cno &&
1114 (err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) {
1115 err = (err < 0) ? : -EBUSY;
1116 goto failed_unlock;
1117 } 1106 }
1118 1107
1119 /* 1108 mutex_lock(&nilfs->ns_mount_mutex);
1120 * Phase-1: search any existent instance and get the_nilfs
1121 */
1122 s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
1123 if (IS_ERR(s))
1124 goto error_s;
1125
1126 if (!s->s_root) {
1127 err = -ENOMEM;
1128 nilfs = alloc_nilfs(sd.bdev);
1129 if (!nilfs)
1130 goto cancel_new;
1131 } else {
1132 struct nilfs_sb_info *sbi = NILFS_SB(s);
1133 1109
1110 if (!sd.cno) {
1134 /* 1111 /*
1135 * s_umount protects super_block from unmount process; 1112 * Check if an exclusive mount exists or not.
1136 * It covers pointers of nilfs_sb_info and the_nilfs. 1113 * Snapshot mounts coexist with a current mount
1114 * (i.e. rw-mount or ro-mount), whereas rw-mount and
1115 * ro-mount are mutually exclusive.
1137 */ 1116 */
1138 nilfs = sbi->s_nilfs; 1117 down_read(&nilfs->ns_super_sem);
1139 get_nilfs(nilfs); 1118 if (nilfs->ns_current &&
1140 up_write(&s->s_umount); 1119 ((nilfs->ns_current->s_super->s_flags ^ flags)
1120 & MS_RDONLY)) {
1121 up_read(&nilfs->ns_super_sem);
1122 err = -EBUSY;
1123 goto failed_unlock;
1124 }
1125 up_read(&nilfs->ns_super_sem);
1126 }
1141 1127
1142 /* 1128 /*
1143 * Phase-2: search specified snapshot or R/W mode super_block 1129 * Find existing nilfs_sb_info struct
1144 */ 1130 */
1145 if (!sd.cno) 1131 sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno);
1146 /* trying to get the latest checkpoint. */
1147 sd.cno = nilfs_last_cno(nilfs);
1148 1132
1149 s2 = sget(fs_type, nilfs_test_bdev_super2, 1133 if (!sd.cno)
1150 nilfs_set_bdev_super, &sd); 1134 /* trying to get the latest checkpoint. */
1151 deactivate_super(s); 1135 sd.cno = nilfs_last_cno(nilfs);
1152 /* 1136
1153 * Although deactivate_super() invokes close_bdev_exclusive() at 1137 /*
1154 * kill_block_super(). Here, s is an existent mount; we need 1138 * Get super block instance holding the nilfs_sb_info struct.
1155 * one more close_bdev_exclusive() call. 1139 * A new instance is allocated if no existing mount is present or
1156 */ 1140 * existing instance has been unmounted.
1157 s = s2; 1141 */
1158 if (IS_ERR(s)) 1142 s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
1159 goto error_s; 1143 if (sd.sbi)
1144 nilfs_put_sbinfo(sd.sbi);
1145
1146 if (IS_ERR(s)) {
1147 err = PTR_ERR(s);
1148 goto failed_unlock;
1160 } 1149 }
1161 1150
1162 if (!s->s_root) { 1151 if (!s->s_root) {
1163 char b[BDEVNAME_SIZE]; 1152 char b[BDEVNAME_SIZE];
1164 1153
1154 /* New superblock instance created */
1165 s->s_flags = flags; 1155 s->s_flags = flags;
1166 strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); 1156 strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
1167 sb_set_blocksize(s, block_size(sd.bdev)); 1157 sb_set_blocksize(s, block_size(sd.bdev));
@@ -1172,26 +1162,18 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1172 1162
1173 s->s_flags |= MS_ACTIVE; 1163 s->s_flags |= MS_ACTIVE;
1174 need_to_close = 0; 1164 need_to_close = 0;
1175 } else if (!(s->s_flags & MS_RDONLY)) {
1176 err = -EBUSY;
1177 } 1165 }
1178 1166
1179 up(&sd.bdev->bd_mount_sem); 1167 mutex_unlock(&nilfs->ns_mount_mutex);
1180 put_nilfs(nilfs); 1168 put_nilfs(nilfs);
1181 if (need_to_close) 1169 if (need_to_close)
1182 close_bdev_exclusive(sd.bdev, flags); 1170 close_bdev_exclusive(sd.bdev, flags);
1183 simple_set_mnt(mnt, s); 1171 simple_set_mnt(mnt, s);
1184 return 0; 1172 return 0;
1185 1173
1186 error_s:
1187 up(&sd.bdev->bd_mount_sem);
1188 if (nilfs)
1189 put_nilfs(nilfs);
1190 close_bdev_exclusive(sd.bdev, flags);
1191 return PTR_ERR(s);
1192
1193 failed_unlock: 1174 failed_unlock:
1194 up(&sd.bdev->bd_mount_sem); 1175 mutex_unlock(&nilfs->ns_mount_mutex);
1176 put_nilfs(nilfs);
1195 failed: 1177 failed:
1196 close_bdev_exclusive(sd.bdev, flags); 1178 close_bdev_exclusive(sd.bdev, flags);
1197 1179
@@ -1199,70 +1181,18 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1199 1181
1200 cancel_new: 1182 cancel_new:
1201 /* Abandoning the newly allocated superblock */ 1183 /* Abandoning the newly allocated superblock */
1202 up(&sd.bdev->bd_mount_sem); 1184 mutex_unlock(&nilfs->ns_mount_mutex);
1203 if (nilfs) 1185 put_nilfs(nilfs);
1204 put_nilfs(nilfs);
1205 up_write(&s->s_umount); 1186 up_write(&s->s_umount);
1206 deactivate_super(s); 1187 deactivate_super(s);
1207 /* 1188 /*
1208 * deactivate_super() invokes close_bdev_exclusive(). 1189 * deactivate_super() invokes close_bdev_exclusive().
1209 * We must finish all post-cleaning before this call; 1190 * We must finish all post-cleaning before this call;
1210 * put_nilfs() and unlocking bd_mount_sem need the block device. 1191 * put_nilfs() needs the block device.
1211 */ 1192 */
1212 return err; 1193 return err;
1213} 1194}
1214 1195
1215static int nilfs_test_bdev_super3(struct super_block *s, void *data)
1216{
1217 struct nilfs_super_data *sd = data;
1218 int ret;
1219
1220 if (s->s_bdev != sd->bdev)
1221 return 0;
1222 if (down_read_trylock(&s->s_umount)) {
1223 ret = (s->s_flags & MS_RDONLY) && s->s_root &&
1224 nilfs_test_opt(NILFS_SB(s), SNAPSHOT);
1225 up_read(&s->s_umount);
1226 if (ret)
1227 return 0; /* ignore snapshot mounts */
1228 }
1229 return !((sd->flags ^ s->s_flags) & MS_RDONLY);
1230}
1231
1232static int __false_bdev_super(struct super_block *s, void *data)
1233{
1234#if 0 /* XXX: workaround for lock debug. This is not good idea */
1235 up_write(&s->s_umount);
1236#endif
1237 return -EFAULT;
1238}
1239
1240/**
1241 * test_exclusive_mount - check whether an exclusive RW/RO mount exists or not.
1242 * fs_type: filesystem type
1243 * bdev: block device
1244 * flag: 0 (check rw-mount) or MS_RDONLY (check ro-mount)
1245 * res: pointer to an integer to store result
1246 *
1247 * This function must be called within a section protected by bd_mount_mutex.
1248 */
1249static int test_exclusive_mount(struct file_system_type *fs_type,
1250 struct block_device *bdev, int flags)
1251{
1252 struct super_block *s;
1253 struct nilfs_super_data sd = { .flags = flags, .bdev = bdev };
1254
1255 s = sget(fs_type, nilfs_test_bdev_super3, __false_bdev_super, &sd);
1256 if (IS_ERR(s)) {
1257 if (PTR_ERR(s) != -EFAULT)
1258 return PTR_ERR(s);
1259 return 0; /* Not found */
1260 }
1261 up_write(&s->s_umount);
1262 deactivate_super(s);
1263 return 1; /* Found */
1264}
1265
1266struct file_system_type nilfs_fs_type = { 1196struct file_system_type nilfs_fs_type = {
1267 .owner = THIS_MODULE, 1197 .owner = THIS_MODULE,
1268 .name = "nilfs2", 1198 .name = "nilfs2",
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index a91f15b8673c..e4e5c78bcc93 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -35,6 +35,10 @@
35#include "seglist.h" 35#include "seglist.h"
36#include "segbuf.h" 36#include "segbuf.h"
37 37
38
39static LIST_HEAD(nilfs_objects);
40static DEFINE_SPINLOCK(nilfs_lock);
41
38void nilfs_set_last_segment(struct the_nilfs *nilfs, 42void nilfs_set_last_segment(struct the_nilfs *nilfs,
39 sector_t start_blocknr, u64 seq, __u64 cno) 43 sector_t start_blocknr, u64 seq, __u64 cno)
40{ 44{
@@ -55,7 +59,7 @@ void nilfs_set_last_segment(struct the_nilfs *nilfs,
55 * Return Value: On success, pointer to the_nilfs is returned. 59 * Return Value: On success, pointer to the_nilfs is returned.
56 * On error, NULL is returned. 60 * On error, NULL is returned.
57 */ 61 */
58struct the_nilfs *alloc_nilfs(struct block_device *bdev) 62static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
59{ 63{
60 struct the_nilfs *nilfs; 64 struct the_nilfs *nilfs;
61 65
@@ -68,7 +72,10 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
68 atomic_set(&nilfs->ns_writer_refcount, -1); 72 atomic_set(&nilfs->ns_writer_refcount, -1);
69 atomic_set(&nilfs->ns_ndirtyblks, 0); 73 atomic_set(&nilfs->ns_ndirtyblks, 0);
70 init_rwsem(&nilfs->ns_sem); 74 init_rwsem(&nilfs->ns_sem);
75 init_rwsem(&nilfs->ns_super_sem);
76 mutex_init(&nilfs->ns_mount_mutex);
71 mutex_init(&nilfs->ns_writer_mutex); 77 mutex_init(&nilfs->ns_writer_mutex);
78 INIT_LIST_HEAD(&nilfs->ns_list);
72 INIT_LIST_HEAD(&nilfs->ns_supers); 79 INIT_LIST_HEAD(&nilfs->ns_supers);
73 spin_lock_init(&nilfs->ns_last_segment_lock); 80 spin_lock_init(&nilfs->ns_last_segment_lock);
74 nilfs->ns_gc_inodes_h = NULL; 81 nilfs->ns_gc_inodes_h = NULL;
@@ -78,6 +85,45 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
78} 85}
79 86
80/** 87/**
88 * find_or_create_nilfs - find or create nilfs object
89 * @bdev: block device to which the_nilfs is related
90 *
91 * find_nilfs() looks up an existent nilfs object created on the
92 * device and gets the reference count of the object. If no nilfs object
93 * is found on the device, a new nilfs object is allocated.
94 *
95 * Return Value: On success, pointer to the nilfs object is returned.
96 * On error, NULL is returned.
97 */
98struct the_nilfs *find_or_create_nilfs(struct block_device *bdev)
99{
100 struct the_nilfs *nilfs, *new = NULL;
101
102 retry:
103 spin_lock(&nilfs_lock);
104 list_for_each_entry(nilfs, &nilfs_objects, ns_list) {
105 if (nilfs->ns_bdev == bdev) {
106 get_nilfs(nilfs);
107 spin_unlock(&nilfs_lock);
108 if (new)
109 put_nilfs(new);
110 return nilfs; /* existing object */
111 }
112 }
113 if (new) {
114 list_add_tail(&new->ns_list, &nilfs_objects);
115 spin_unlock(&nilfs_lock);
116 return new; /* new object */
117 }
118 spin_unlock(&nilfs_lock);
119
120 new = alloc_nilfs(bdev);
121 if (new)
122 goto retry;
123 return NULL; /* insufficient memory */
124}
125
126/**
81 * put_nilfs - release a reference to the_nilfs 127 * put_nilfs - release a reference to the_nilfs
82 * @nilfs: the_nilfs structure to be released 128 * @nilfs: the_nilfs structure to be released
83 * 129 *
@@ -86,13 +132,20 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
86 */ 132 */
87void put_nilfs(struct the_nilfs *nilfs) 133void put_nilfs(struct the_nilfs *nilfs)
88{ 134{
89 if (!atomic_dec_and_test(&nilfs->ns_count)) 135 spin_lock(&nilfs_lock);
136 if (!atomic_dec_and_test(&nilfs->ns_count)) {
137 spin_unlock(&nilfs_lock);
90 return; 138 return;
139 }
140 list_del_init(&nilfs->ns_list);
141 spin_unlock(&nilfs_lock);
142
91 /* 143 /*
92 * Increment of ns_count never occur below because the caller 144 * Increment of ns_count never occurs below because the caller
93 * of get_nilfs() holds at least one reference to the_nilfs. 145 * of get_nilfs() holds at least one reference to the_nilfs.
94 * Thus its exclusion control is not required here. 146 * Thus its exclusion control is not required here.
95 */ 147 */
148
96 might_sleep(); 149 might_sleep();
97 if (nilfs_loaded(nilfs)) { 150 if (nilfs_loaded(nilfs)) {
98 nilfs_mdt_clear(nilfs->ns_sufile); 151 nilfs_mdt_clear(nilfs->ns_sufile);
@@ -613,13 +666,63 @@ int nilfs_near_disk_full(struct the_nilfs *nilfs)
613 return ret; 666 return ret;
614} 667}
615 668
669/**
670 * nilfs_find_sbinfo - find existing nilfs_sb_info structure
671 * @nilfs: nilfs object
672 * @rw_mount: mount type (non-zero value for read/write mount)
673 * @cno: checkpoint number (zero for read-only mount)
674 *
675 * nilfs_find_sbinfo() returns the nilfs_sb_info structure which
676 * @rw_mount and @cno (in case of snapshots) matched. If no instance
677 * was found, NULL is returned. Although the super block instance can
678 * be unmounted after this function returns, the nilfs_sb_info struct
679 * is kept on memory until nilfs_put_sbinfo() is called.
680 */
681struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *nilfs,
682 int rw_mount, __u64 cno)
683{
684 struct nilfs_sb_info *sbi;
685
686 down_read(&nilfs->ns_super_sem);
687 /*
688 * The SNAPSHOT flag and sb->s_flags are supposed to be
689 * protected with nilfs->ns_super_sem.
690 */
691 sbi = nilfs->ns_current;
692 if (rw_mount) {
693 if (sbi && !(sbi->s_super->s_flags & MS_RDONLY))
694 goto found; /* read/write mount */
695 else
696 goto out;
697 } else if (cno == 0) {
698 if (sbi && (sbi->s_super->s_flags & MS_RDONLY))
699 goto found; /* read-only mount */
700 else
701 goto out;
702 }
703
704 list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
705 if (nilfs_test_opt(sbi, SNAPSHOT) &&
706 sbi->s_snapshot_cno == cno)
707 goto found; /* snapshot mount */
708 }
709 out:
710 up_read(&nilfs->ns_super_sem);
711 return NULL;
712
713 found:
714 atomic_inc(&sbi->s_count);
715 up_read(&nilfs->ns_super_sem);
716 return sbi;
717}
718
616int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno, 719int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
617 int snapshot_mount) 720 int snapshot_mount)
618{ 721{
619 struct nilfs_sb_info *sbi; 722 struct nilfs_sb_info *sbi;
620 int ret = 0; 723 int ret = 0;
621 724
622 down_read(&nilfs->ns_sem); 725 down_read(&nilfs->ns_super_sem);
623 if (cno == 0 || cno > nilfs->ns_cno) 726 if (cno == 0 || cno > nilfs->ns_cno)
624 goto out_unlock; 727 goto out_unlock;
625 728
@@ -636,6 +739,6 @@ int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
636 ret++; 739 ret++;
637 740
638 out_unlock: 741 out_unlock:
639 up_read(&nilfs->ns_sem); 742 up_read(&nilfs->ns_super_sem);
640 return ret; 743 return ret;
641} 744}
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 30fe58778d05..e8adbffc626f 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -43,12 +43,16 @@ enum {
43 * struct the_nilfs - struct to supervise multiple nilfs mount points 43 * struct the_nilfs - struct to supervise multiple nilfs mount points
44 * @ns_flags: flags 44 * @ns_flags: flags
45 * @ns_count: reference count 45 * @ns_count: reference count
46 * @ns_list: list head for nilfs_list
46 * @ns_bdev: block device 47 * @ns_bdev: block device
47 * @ns_bdi: backing dev info 48 * @ns_bdi: backing dev info
48 * @ns_writer: back pointer to writable nilfs_sb_info 49 * @ns_writer: back pointer to writable nilfs_sb_info
49 * @ns_sem: semaphore for shared states 50 * @ns_sem: semaphore for shared states
51 * @ns_super_sem: semaphore for global operations across super block instances
52 * @ns_mount_mutex: mutex protecting mount process of nilfs
50 * @ns_writer_mutex: mutex protecting ns_writer attach/detach 53 * @ns_writer_mutex: mutex protecting ns_writer attach/detach
51 * @ns_writer_refcount: number of referrers on ns_writer 54 * @ns_writer_refcount: number of referrers on ns_writer
55 * @ns_current: back pointer to current mount
52 * @ns_sbh: buffer heads of on-disk super blocks 56 * @ns_sbh: buffer heads of on-disk super blocks
53 * @ns_sbp: pointers to super block data 57 * @ns_sbp: pointers to super block data
54 * @ns_sbwtime: previous write time of super blocks 58 * @ns_sbwtime: previous write time of super blocks
@@ -88,15 +92,24 @@ enum {
88struct the_nilfs { 92struct the_nilfs {
89 unsigned long ns_flags; 93 unsigned long ns_flags;
90 atomic_t ns_count; 94 atomic_t ns_count;
95 struct list_head ns_list;
91 96
92 struct block_device *ns_bdev; 97 struct block_device *ns_bdev;
93 struct backing_dev_info *ns_bdi; 98 struct backing_dev_info *ns_bdi;
94 struct nilfs_sb_info *ns_writer; 99 struct nilfs_sb_info *ns_writer;
95 struct rw_semaphore ns_sem; 100 struct rw_semaphore ns_sem;
101 struct rw_semaphore ns_super_sem;
102 struct mutex ns_mount_mutex;
96 struct mutex ns_writer_mutex; 103 struct mutex ns_writer_mutex;
97 atomic_t ns_writer_refcount; 104 atomic_t ns_writer_refcount;
98 105
99 /* 106 /*
107 * components protected by ns_super_sem
108 */
109 struct nilfs_sb_info *ns_current;
110 struct list_head ns_supers;
111
112 /*
100 * used for 113 * used for
101 * - loading the latest checkpoint exclusively. 114 * - loading the latest checkpoint exclusively.
102 * - allocating a new full segment. 115 * - allocating a new full segment.
@@ -108,7 +121,6 @@ struct the_nilfs {
108 time_t ns_sbwtime[2]; 121 time_t ns_sbwtime[2];
109 unsigned ns_sbsize; 122 unsigned ns_sbsize;
110 unsigned ns_mount_state; 123 unsigned ns_mount_state;
111 struct list_head ns_supers;
112 124
113 /* 125 /*
114 * Following fields are dedicated to a writable FS-instance. 126 * Following fields are dedicated to a writable FS-instance.
@@ -191,11 +203,12 @@ THE_NILFS_FNS(DISCONTINUED, discontinued)
191#define NILFS_ALTSB_FREQ 60 /* spare superblock */ 203#define NILFS_ALTSB_FREQ 60 /* spare superblock */
192 204
193void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); 205void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
194struct the_nilfs *alloc_nilfs(struct block_device *); 206struct the_nilfs *find_or_create_nilfs(struct block_device *);
195void put_nilfs(struct the_nilfs *); 207void put_nilfs(struct the_nilfs *);
196int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *); 208int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *);
197int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *); 209int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
198int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); 210int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
211struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64);
199int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int); 212int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
200int nilfs_near_disk_full(struct the_nilfs *); 213int nilfs_near_disk_full(struct the_nilfs *);
201void nilfs_fall_back_super_block(struct the_nilfs *); 214void nilfs_fall_back_super_block(struct the_nilfs *);
@@ -238,6 +251,12 @@ nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
238 mutex_unlock(&nilfs->ns_writer_mutex); 251 mutex_unlock(&nilfs->ns_writer_mutex);
239} 252}
240 253
254static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
255{
256 if (!atomic_dec_and_test(&sbi->s_count))
257 kfree(sbi);
258}
259
241static inline void 260static inline void
242nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum, 261nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
243 sector_t *seg_start, sector_t *seg_end) 262 sector_t *seg_start, sector_t *seg_end)
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 6aa7c4713536..abaaa1cbf8de 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -443,6 +443,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
443 ntfs_volume *vol = NTFS_SB(sb); 443 ntfs_volume *vol = NTFS_SB(sb);
444 444
445 ntfs_debug("Entering with remount options string: %s", opt); 445 ntfs_debug("Entering with remount options string: %s", opt);
446
447 lock_kernel();
446#ifndef NTFS_RW 448#ifndef NTFS_RW
447 /* For read-only compiled driver, enforce read-only flag. */ 449 /* For read-only compiled driver, enforce read-only flag. */
448 *flags |= MS_RDONLY; 450 *flags |= MS_RDONLY;
@@ -466,15 +468,18 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
466 if (NVolErrors(vol)) { 468 if (NVolErrors(vol)) {
467 ntfs_error(sb, "Volume has errors and is read-only%s", 469 ntfs_error(sb, "Volume has errors and is read-only%s",
468 es); 470 es);
471 unlock_kernel();
469 return -EROFS; 472 return -EROFS;
470 } 473 }
471 if (vol->vol_flags & VOLUME_IS_DIRTY) { 474 if (vol->vol_flags & VOLUME_IS_DIRTY) {
472 ntfs_error(sb, "Volume is dirty and read-only%s", es); 475 ntfs_error(sb, "Volume is dirty and read-only%s", es);
476 unlock_kernel();
473 return -EROFS; 477 return -EROFS;
474 } 478 }
475 if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) { 479 if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
476 ntfs_error(sb, "Volume has been modified by chkdsk " 480 ntfs_error(sb, "Volume has been modified by chkdsk "
477 "and is read-only%s", es); 481 "and is read-only%s", es);
482 unlock_kernel();
478 return -EROFS; 483 return -EROFS;
479 } 484 }
480 if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { 485 if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
@@ -482,11 +487,13 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
482 "(0x%x) and is read-only%s", 487 "(0x%x) and is read-only%s",
483 (unsigned)le16_to_cpu(vol->vol_flags), 488 (unsigned)le16_to_cpu(vol->vol_flags),
484 es); 489 es);
490 unlock_kernel();
485 return -EROFS; 491 return -EROFS;
486 } 492 }
487 if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { 493 if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
488 ntfs_error(sb, "Failed to set dirty bit in volume " 494 ntfs_error(sb, "Failed to set dirty bit in volume "
489 "information flags%s", es); 495 "information flags%s", es);
496 unlock_kernel();
490 return -EROFS; 497 return -EROFS;
491 } 498 }
492#if 0 499#if 0
@@ -506,18 +513,21 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
506 ntfs_error(sb, "Failed to empty journal $LogFile%s", 513 ntfs_error(sb, "Failed to empty journal $LogFile%s",
507 es); 514 es);
508 NVolSetErrors(vol); 515 NVolSetErrors(vol);
516 unlock_kernel();
509 return -EROFS; 517 return -EROFS;
510 } 518 }
511 if (!ntfs_mark_quotas_out_of_date(vol)) { 519 if (!ntfs_mark_quotas_out_of_date(vol)) {
512 ntfs_error(sb, "Failed to mark quotas out of date%s", 520 ntfs_error(sb, "Failed to mark quotas out of date%s",
513 es); 521 es);
514 NVolSetErrors(vol); 522 NVolSetErrors(vol);
523 unlock_kernel();
515 return -EROFS; 524 return -EROFS;
516 } 525 }
517 if (!ntfs_stamp_usnjrnl(vol)) { 526 if (!ntfs_stamp_usnjrnl(vol)) {
518 ntfs_error(sb, "Failed to stamp transation log " 527 ntfs_error(sb, "Failed to stamp transation log "
519 "($UsnJrnl)%s", es); 528 "($UsnJrnl)%s", es);
520 NVolSetErrors(vol); 529 NVolSetErrors(vol);
530 unlock_kernel();
521 return -EROFS; 531 return -EROFS;
522 } 532 }
523 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { 533 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
@@ -533,8 +543,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
533 543
534 // TODO: Deal with *flags. 544 // TODO: Deal with *flags.
535 545
536 if (!parse_options(vol, opt)) 546 if (!parse_options(vol, opt)) {
547 unlock_kernel();
537 return -EINVAL; 548 return -EINVAL;
549 }
550 unlock_kernel();
538 ntfs_debug("Done."); 551 ntfs_debug("Done.");
539 return 0; 552 return 0;
540} 553}
@@ -2246,6 +2259,9 @@ static void ntfs_put_super(struct super_block *sb)
2246 ntfs_volume *vol = NTFS_SB(sb); 2259 ntfs_volume *vol = NTFS_SB(sb);
2247 2260
2248 ntfs_debug("Entering."); 2261 ntfs_debug("Entering.");
2262
2263 lock_kernel();
2264
2249#ifdef NTFS_RW 2265#ifdef NTFS_RW
2250 /* 2266 /*
2251 * Commit all inodes while they are still open in case some of them 2267 * Commit all inodes while they are still open in case some of them
@@ -2373,39 +2389,12 @@ static void ntfs_put_super(struct super_block *sb)
2373 vol->mftmirr_ino = NULL; 2389 vol->mftmirr_ino = NULL;
2374 } 2390 }
2375 /* 2391 /*
2376 * If any dirty inodes are left, throw away all mft data page cache 2392 * We should have no dirty inodes left, due to
2377 * pages to allow a clean umount. This should never happen any more 2393 * mft.c::ntfs_mft_writepage() cleaning all the dirty pages as
2378 * due to mft.c::ntfs_mft_writepage() cleaning all the dirty pages as 2394 * the underlying mft records are written out and cleaned.
2379 * the underlying mft records are written out and cleaned. If it does,
2380 * happen anyway, we want to know...
2381 */ 2395 */
2382 ntfs_commit_inode(vol->mft_ino); 2396 ntfs_commit_inode(vol->mft_ino);
2383 write_inode_now(vol->mft_ino, 1); 2397 write_inode_now(vol->mft_ino, 1);
2384 if (sb_has_dirty_inodes(sb)) {
2385 const char *s1, *s2;
2386
2387 mutex_lock(&vol->mft_ino->i_mutex);
2388 truncate_inode_pages(vol->mft_ino->i_mapping, 0);
2389 mutex_unlock(&vol->mft_ino->i_mutex);
2390 write_inode_now(vol->mft_ino, 1);
2391 if (sb_has_dirty_inodes(sb)) {
2392 static const char *_s1 = "inodes";
2393 static const char *_s2 = "";
2394 s1 = _s1;
2395 s2 = _s2;
2396 } else {
2397 static const char *_s1 = "mft pages";
2398 static const char *_s2 = "They have been thrown "
2399 "away. ";
2400 s1 = _s1;
2401 s2 = _s2;
2402 }
2403 ntfs_error(sb, "Dirty %s found at umount time. %sYou should "
2404 "run chkdsk. Please email "
2405 "linux-ntfs-dev@lists.sourceforge.net and say "
2406 "that you saw this message. Thank you.", s1,
2407 s2);
2408 }
2409#endif /* NTFS_RW */ 2398#endif /* NTFS_RW */
2410 2399
2411 iput(vol->mft_ino); 2400 iput(vol->mft_ino);
@@ -2444,7 +2433,8 @@ static void ntfs_put_super(struct super_block *sb)
2444 } 2433 }
2445 sb->s_fs_info = NULL; 2434 sb->s_fs_info = NULL;
2446 kfree(vol); 2435 kfree(vol);
2447 return; 2436
2437 unlock_kernel();
2448} 2438}
2449 2439
2450/** 2440/**
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 5c6163f55039..201b40a441fe 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -42,6 +42,7 @@
42#include <linux/mount.h> 42#include <linux/mount.h>
43#include <linux/seq_file.h> 43#include <linux/seq_file.h>
44#include <linux/quotaops.h> 44#include <linux/quotaops.h>
45#include <linux/smp_lock.h>
45 46
46#define MLOG_MASK_PREFIX ML_SUPER 47#define MLOG_MASK_PREFIX ML_SUPER
47#include <cluster/masklog.h> 48#include <cluster/masklog.h>
@@ -126,7 +127,6 @@ static int ocfs2_get_sector(struct super_block *sb,
126 struct buffer_head **bh, 127 struct buffer_head **bh,
127 int block, 128 int block,
128 int sect_size); 129 int sect_size);
129static void ocfs2_write_super(struct super_block *sb);
130static struct inode *ocfs2_alloc_inode(struct super_block *sb); 130static struct inode *ocfs2_alloc_inode(struct super_block *sb);
131static void ocfs2_destroy_inode(struct inode *inode); 131static void ocfs2_destroy_inode(struct inode *inode);
132static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend); 132static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend);
@@ -141,7 +141,6 @@ static const struct super_operations ocfs2_sops = {
141 .clear_inode = ocfs2_clear_inode, 141 .clear_inode = ocfs2_clear_inode,
142 .delete_inode = ocfs2_delete_inode, 142 .delete_inode = ocfs2_delete_inode,
143 .sync_fs = ocfs2_sync_fs, 143 .sync_fs = ocfs2_sync_fs,
144 .write_super = ocfs2_write_super,
145 .put_super = ocfs2_put_super, 144 .put_super = ocfs2_put_super,
146 .remount_fs = ocfs2_remount, 145 .remount_fs = ocfs2_remount,
147 .show_options = ocfs2_show_options, 146 .show_options = ocfs2_show_options,
@@ -365,24 +364,12 @@ static struct file_operations ocfs2_osb_debug_fops = {
365 .llseek = generic_file_llseek, 364 .llseek = generic_file_llseek,
366}; 365};
367 366
368/*
369 * write_super and sync_fs ripped right out of ext3.
370 */
371static void ocfs2_write_super(struct super_block *sb)
372{
373 if (mutex_trylock(&sb->s_lock) != 0)
374 BUG();
375 sb->s_dirt = 0;
376}
377
378static int ocfs2_sync_fs(struct super_block *sb, int wait) 367static int ocfs2_sync_fs(struct super_block *sb, int wait)
379{ 368{
380 int status; 369 int status;
381 tid_t target; 370 tid_t target;
382 struct ocfs2_super *osb = OCFS2_SB(sb); 371 struct ocfs2_super *osb = OCFS2_SB(sb);
383 372
384 sb->s_dirt = 0;
385
386 if (ocfs2_is_hard_readonly(osb)) 373 if (ocfs2_is_hard_readonly(osb))
387 return -EROFS; 374 return -EROFS;
388 375
@@ -595,6 +582,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
595 struct mount_options parsed_options; 582 struct mount_options parsed_options;
596 struct ocfs2_super *osb = OCFS2_SB(sb); 583 struct ocfs2_super *osb = OCFS2_SB(sb);
597 584
585 lock_kernel();
586
598 if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) { 587 if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
599 ret = -EINVAL; 588 ret = -EINVAL;
600 goto out; 589 goto out;
@@ -698,6 +687,7 @@ unlock_osb:
698 ocfs2_set_journal_params(osb); 687 ocfs2_set_journal_params(osb);
699 } 688 }
700out: 689out:
690 unlock_kernel();
701 return ret; 691 return ret;
702} 692}
703 693
@@ -1550,9 +1540,13 @@ static void ocfs2_put_super(struct super_block *sb)
1550{ 1540{
1551 mlog_entry("(0x%p)\n", sb); 1541 mlog_entry("(0x%p)\n", sb);
1552 1542
1543 lock_kernel();
1544
1553 ocfs2_sync_blockdev(sb); 1545 ocfs2_sync_blockdev(sb);
1554 ocfs2_dismount_volume(sb, 0); 1546 ocfs2_dismount_volume(sb, 0);
1555 1547
1548 unlock_kernel();
1549
1556 mlog_exit_void(); 1550 mlog_exit_void();
1557} 1551}
1558 1552
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 834b2331f6b3..d17e774eaf45 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -11,21 +11,6 @@
11#include <linux/mpage.h> 11#include <linux/mpage.h>
12#include "omfs.h" 12#include "omfs.h"
13 13
14static int omfs_sync_file(struct file *file, struct dentry *dentry,
15 int datasync)
16{
17 struct inode *inode = dentry->d_inode;
18 int err;
19
20 err = sync_mapping_buffers(inode->i_mapping);
21 if (!(inode->i_state & I_DIRTY))
22 return err;
23 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
24 return err;
25 err |= omfs_sync_inode(inode);
26 return err ? -EIO : 0;
27}
28
29static u32 omfs_max_extents(struct omfs_sb_info *sbi, int offset) 14static u32 omfs_max_extents(struct omfs_sb_info *sbi, int offset)
30{ 15{
31 return (sbi->s_sys_blocksize - offset - 16 return (sbi->s_sys_blocksize - offset -
@@ -344,7 +329,7 @@ struct file_operations omfs_file_operations = {
344 .aio_read = generic_file_aio_read, 329 .aio_read = generic_file_aio_read,
345 .aio_write = generic_file_aio_write, 330 .aio_write = generic_file_aio_write,
346 .mmap = generic_file_mmap, 331 .mmap = generic_file_mmap,
347 .fsync = omfs_sync_file, 332 .fsync = simple_fsync,
348 .splice_read = generic_file_splice_read, 333 .splice_read = generic_file_splice_read,
349}; 334};
350 335
diff --git a/fs/open.c b/fs/open.c
index bdfbf03615a4..7200e23d9258 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -612,7 +612,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
612 612
613 audit_inode(NULL, dentry); 613 audit_inode(NULL, dentry);
614 614
615 err = mnt_want_write(file->f_path.mnt); 615 err = mnt_want_write_file(file);
616 if (err) 616 if (err)
617 goto out_putf; 617 goto out_putf;
618 mutex_lock(&inode->i_mutex); 618 mutex_lock(&inode->i_mutex);
@@ -761,7 +761,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
761 if (!file) 761 if (!file)
762 goto out; 762 goto out;
763 763
764 error = mnt_want_write(file->f_path.mnt); 764 error = mnt_want_write_file(file);
765 if (error) 765 if (error)
766 goto out_fput; 766 goto out_fput;
767 dentry = file->f_path.dentry; 767 dentry = file->f_path.dentry;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index f6db9618a888..753ca37002c8 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -92,3 +92,28 @@ struct pde_opener {
92 struct list_head lh; 92 struct list_head lh;
93}; 93};
94void pde_users_dec(struct proc_dir_entry *pde); 94void pde_users_dec(struct proc_dir_entry *pde);
95
96extern spinlock_t proc_subdir_lock;
97
98struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *);
99int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
100unsigned long task_vsize(struct mm_struct *);
101int task_statm(struct mm_struct *, int *, int *, int *, int *);
102void task_mem(struct seq_file *, struct mm_struct *);
103
104struct proc_dir_entry *de_get(struct proc_dir_entry *de);
105void de_put(struct proc_dir_entry *de);
106
107extern struct vfsmount *proc_mnt;
108int proc_fill_super(struct super_block *);
109struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
110
111/*
112 * These are generic /proc routines that use the internal
113 * "struct proc_dir_entry" tree to traverse the filesystem.
114 *
115 * The /proc root directory has extended versions to take care
116 * of the /proc/<pid> subdirectories.
117 */
118int proc_readdir(struct file *, void *, filldir_t);
119struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index de2bba5a3440..fc6c3025befd 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -11,6 +11,7 @@
11#include <linux/string.h> 11#include <linux/string.h>
12#include <asm/prom.h> 12#include <asm/prom.h>
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14#include "internal.h"
14 15
15#ifndef HAVE_ARCH_DEVTREE_FIXUPS 16#ifndef HAVE_ARCH_DEVTREE_FIXUPS
16static inline void set_node_proc_entry(struct device_node *np, 17static inline void set_node_proc_entry(struct device_node *np,
diff --git a/fs/qnx4/Makefile b/fs/qnx4/Makefile
index 502d7fe98bab..e4d408cc5473 100644
--- a/fs/qnx4/Makefile
+++ b/fs/qnx4/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_QNX4FS_FS) += qnx4.o 5obj-$(CONFIG_QNX4FS_FS) += qnx4.o
6 6
7qnx4-objs := inode.o dir.o namei.o file.o bitmap.o truncate.o fsync.o 7qnx4-objs := inode.o dir.o namei.o file.o bitmap.o truncate.o
diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c
index 8425cf6e9624..e1cd061a25f7 100644
--- a/fs/qnx4/bitmap.c
+++ b/fs/qnx4/bitmap.c
@@ -13,14 +13,9 @@
13 * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) . 13 * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) .
14 */ 14 */
15 15
16#include <linux/time.h>
17#include <linux/fs.h>
18#include <linux/qnx4_fs.h>
19#include <linux/stat.h>
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/buffer_head.h> 16#include <linux/buffer_head.h>
23#include <linux/bitops.h> 17#include <linux/bitops.h>
18#include "qnx4.h"
24 19
25#if 0 20#if 0
26int qnx4_new_block(struct super_block *sb) 21int qnx4_new_block(struct super_block *sb)
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c
index ea9ffefb48ad..003c68f3238b 100644
--- a/fs/qnx4/dir.c
+++ b/fs/qnx4/dir.c
@@ -11,14 +11,9 @@
11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support. 11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support.
12 */ 12 */
13 13
14#include <linux/string.h>
15#include <linux/errno.h>
16#include <linux/fs.h>
17#include <linux/qnx4_fs.h>
18#include <linux/stat.h>
19#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
20#include <linux/buffer_head.h> 15#include <linux/buffer_head.h>
21 16#include "qnx4.h"
22 17
23static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) 18static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
24{ 19{
@@ -84,7 +79,7 @@ const struct file_operations qnx4_dir_operations =
84{ 79{
85 .read = generic_read_dir, 80 .read = generic_read_dir,
86 .readdir = qnx4_readdir, 81 .readdir = qnx4_readdir,
87 .fsync = file_fsync, 82 .fsync = simple_fsync,
88}; 83};
89 84
90const struct inode_operations qnx4_dir_inode_operations = 85const struct inode_operations qnx4_dir_inode_operations =
diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c
index 867f42b02035..09b170ac936c 100644
--- a/fs/qnx4/file.c
+++ b/fs/qnx4/file.c
@@ -12,8 +12,7 @@
12 * 27-06-1998 by Frank Denis : file overwriting. 12 * 27-06-1998 by Frank Denis : file overwriting.
13 */ 13 */
14 14
15#include <linux/fs.h> 15#include "qnx4.h"
16#include <linux/qnx4_fs.h>
17 16
18/* 17/*
19 * We have mostly NULL's here: the current defaults are ok for 18 * We have mostly NULL's here: the current defaults are ok for
@@ -29,7 +28,7 @@ const struct file_operations qnx4_file_operations =
29#ifdef CONFIG_QNX4FS_RW 28#ifdef CONFIG_QNX4FS_RW
30 .write = do_sync_write, 29 .write = do_sync_write,
31 .aio_write = generic_file_aio_write, 30 .aio_write = generic_file_aio_write,
32 .fsync = qnx4_sync_file, 31 .fsync = simple_fsync,
33#endif 32#endif
34}; 33};
35 34
diff --git a/fs/qnx4/fsync.c b/fs/qnx4/fsync.c
deleted file mode 100644
index aa3b19544bee..000000000000
--- a/fs/qnx4/fsync.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 * QNX4 file system, Linux implementation.
3 *
4 * Version : 0.1
5 *
6 * Using parts of the xiafs filesystem.
7 *
8 * History :
9 *
10 * 24-03-1998 by Richard Frowijn : first release.
11 */
12
13#include <linux/errno.h>
14#include <linux/time.h>
15#include <linux/stat.h>
16#include <linux/fcntl.h>
17#include <linux/smp_lock.h>
18#include <linux/buffer_head.h>
19
20#include <linux/fs.h>
21#include <linux/qnx4_fs.h>
22
23#include <asm/system.h>
24
25/*
26 * The functions for qnx4 fs file synchronization.
27 */
28
29#ifdef CONFIG_QNX4FS_RW
30
31static int sync_block(struct inode *inode, unsigned short *block, int wait)
32{
33 struct buffer_head *bh;
34 unsigned short tmp;
35
36 if (!*block)
37 return 0;
38 tmp = *block;
39 bh = sb_find_get_block(inode->i_sb, *block);
40 if (!bh)
41 return 0;
42 if (*block != tmp) {
43 brelse(bh);
44 return 1;
45 }
46 if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
47 brelse(bh);
48 return -1;
49 }
50 if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
51 brelse(bh);
52 return 0;
53 }
54 ll_rw_block(WRITE, 1, &bh);
55 atomic_dec(&bh->b_count);
56 return 0;
57}
58
59#ifdef WTF
60static int sync_iblock(struct inode *inode, unsigned short *iblock,
61 struct buffer_head **bh, int wait)
62{
63 int rc;
64 unsigned short tmp;
65
66 *bh = NULL;
67 tmp = *iblock;
68 if (!tmp)
69 return 0;
70 rc = sync_block(inode, iblock, wait);
71 if (rc)
72 return rc;
73 *bh = sb_bread(inode->i_sb, tmp);
74 if (tmp != *iblock) {
75 brelse(*bh);
76 *bh = NULL;
77 return 1;
78 }
79 if (!*bh)
80 return -1;
81 return 0;
82}
83#endif
84
85static int sync_direct(struct inode *inode, int wait)
86{
87 int i;
88 int rc, err = 0;
89
90 for (i = 0; i < 7; i++) {
91 rc = sync_block(inode,
92 (unsigned short *) qnx4_raw_inode(inode)->di_first_xtnt.xtnt_blk + i, wait);
93 if (rc > 0)
94 break;
95 if (rc)
96 err = rc;
97 }
98 return err;
99}
100
101#ifdef WTF
102static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
103{
104 int i;
105 struct buffer_head *ind_bh;
106 int rc, err = 0;
107
108 rc = sync_iblock(inode, iblock, &ind_bh, wait);
109 if (rc || !ind_bh)
110 return rc;
111
112 for (i = 0; i < 512; i++) {
113 rc = sync_block(inode,
114 ((unsigned short *) ind_bh->b_data) + i,
115 wait);
116 if (rc > 0)
117 break;
118 if (rc)
119 err = rc;
120 }
121 brelse(ind_bh);
122 return err;
123}
124
125static int sync_dindirect(struct inode *inode, unsigned short *diblock,
126 int wait)
127{
128 int i;
129 struct buffer_head *dind_bh;
130 int rc, err = 0;
131
132 rc = sync_iblock(inode, diblock, &dind_bh, wait);
133 if (rc || !dind_bh)
134 return rc;
135
136 for (i = 0; i < 512; i++) {
137 rc = sync_indirect(inode,
138 ((unsigned short *) dind_bh->b_data) + i,
139 wait);
140 if (rc > 0)
141 break;
142 if (rc)
143 err = rc;
144 }
145 brelse(dind_bh);
146 return err;
147}
148#endif
149
150int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused)
151{
152 struct inode *inode = dentry->d_inode;
153 int wait, err = 0;
154
155 (void) file;
156 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
157 S_ISLNK(inode->i_mode)))
158 return -EINVAL;
159
160 lock_kernel();
161 for (wait = 0; wait <= 1; wait++) {
162 err |= sync_direct(inode, wait);
163 }
164 err |= qnx4_sync_inode(inode);
165 unlock_kernel();
166 return (err < 0) ? -EIO : 0;
167}
168
169#endif
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index fe1f0f31d11c..681df5fcd161 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -13,19 +13,15 @@
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/string.h>
18#include <linux/errno.h>
19#include <linux/slab.h>
20#include <linux/fs.h>
21#include <linux/qnx4_fs.h>
22#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/slab.h>
23#include <linux/highuid.h> 18#include <linux/highuid.h>
24#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
25#include <linux/pagemap.h> 20#include <linux/pagemap.h>
26#include <linux/buffer_head.h> 21#include <linux/buffer_head.h>
27#include <linux/vfs.h> 22#include <linux/writeback.h>
28#include <asm/uaccess.h> 23#include <linux/statfs.h>
24#include "qnx4.h"
29 25
30#define QNX4_VERSION 4 26#define QNX4_VERSION 4
31#define QNX4_BMNAME ".bitmap" 27#define QNX4_BMNAME ".bitmap"
@@ -34,31 +30,6 @@ static const struct super_operations qnx4_sops;
34 30
35#ifdef CONFIG_QNX4FS_RW 31#ifdef CONFIG_QNX4FS_RW
36 32
37int qnx4_sync_inode(struct inode *inode)
38{
39 int err = 0;
40# if 0
41 struct buffer_head *bh;
42
43 bh = qnx4_update_inode(inode);
44 if (bh && buffer_dirty(bh))
45 {
46 sync_dirty_buffer(bh);
47 if (buffer_req(bh) && !buffer_uptodate(bh))
48 {
49 printk ("IO error syncing qnx4 inode [%s:%08lx]\n",
50 inode->i_sb->s_id, inode->i_ino);
51 err = -1;
52 }
53 brelse (bh);
54 } else if (!bh) {
55 err = -1;
56 }
57# endif
58
59 return err;
60}
61
62static void qnx4_delete_inode(struct inode *inode) 33static void qnx4_delete_inode(struct inode *inode)
63{ 34{
64 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino)); 35 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
@@ -70,15 +41,7 @@ static void qnx4_delete_inode(struct inode *inode)
70 unlock_kernel(); 41 unlock_kernel();
71} 42}
72 43
73static void qnx4_write_super(struct super_block *sb) 44static int qnx4_write_inode(struct inode *inode, int do_sync)
74{
75 lock_kernel();
76 QNX4DEBUG(("qnx4: write_super\n"));
77 sb->s_dirt = 0;
78 unlock_kernel();
79}
80
81static int qnx4_write_inode(struct inode *inode, int unused)
82{ 45{
83 struct qnx4_inode_entry *raw_inode; 46 struct qnx4_inode_entry *raw_inode;
84 int block, ino; 47 int block, ino;
@@ -115,6 +78,16 @@ static int qnx4_write_inode(struct inode *inode, int unused)
115 raw_inode->di_ctime = cpu_to_le32(inode->i_ctime.tv_sec); 78 raw_inode->di_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
116 raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks); 79 raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks);
117 mark_buffer_dirty(bh); 80 mark_buffer_dirty(bh);
81 if (do_sync) {
82 sync_dirty_buffer(bh);
83 if (buffer_req(bh) && !buffer_uptodate(bh)) {
84 printk("qnx4: IO error syncing inode [%s:%08x]\n",
85 inode->i_sb->s_id, ino);
86 brelse(bh);
87 unlock_kernel();
88 return -EIO;
89 }
90 }
118 brelse(bh); 91 brelse(bh);
119 unlock_kernel(); 92 unlock_kernel();
120 return 0; 93 return 0;
@@ -138,7 +111,6 @@ static const struct super_operations qnx4_sops =
138#ifdef CONFIG_QNX4FS_RW 111#ifdef CONFIG_QNX4FS_RW
139 .write_inode = qnx4_write_inode, 112 .write_inode = qnx4_write_inode,
140 .delete_inode = qnx4_delete_inode, 113 .delete_inode = qnx4_delete_inode,
141 .write_super = qnx4_write_super,
142#endif 114#endif
143}; 115};
144 116
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index 775eed3a4085..5972ed214937 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -12,16 +12,9 @@
12 * 04-07-1998 by Frank Denis : first step for rmdir/unlink. 12 * 04-07-1998 by Frank Denis : first step for rmdir/unlink.
13 */ 13 */
14 14
15#include <linux/time.h>
16#include <linux/fs.h>
17#include <linux/qnx4_fs.h>
18#include <linux/kernel.h>
19#include <linux/string.h>
20#include <linux/stat.h>
21#include <linux/fcntl.h>
22#include <linux/errno.h>
23#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
24#include <linux/buffer_head.h> 16#include <linux/buffer_head.h>
17#include "qnx4.h"
25 18
26 19
27/* 20/*
@@ -187,7 +180,7 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry)
187 de->di_status = 0; 180 de->di_status = 0;
188 memset(de->di_fname, 0, sizeof de->di_fname); 181 memset(de->di_fname, 0, sizeof de->di_fname);
189 de->di_mode = 0; 182 de->di_mode = 0;
190 mark_buffer_dirty(bh); 183 mark_buffer_dirty_inode(bh, dir);
191 clear_nlink(inode); 184 clear_nlink(inode);
192 mark_inode_dirty(inode); 185 mark_inode_dirty(inode);
193 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 186 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
@@ -232,7 +225,7 @@ int qnx4_unlink(struct inode *dir, struct dentry *dentry)
232 de->di_status = 0; 225 de->di_status = 0;
233 memset(de->di_fname, 0, sizeof de->di_fname); 226 memset(de->di_fname, 0, sizeof de->di_fname);
234 de->di_mode = 0; 227 de->di_mode = 0;
235 mark_buffer_dirty(bh); 228 mark_buffer_dirty_inode(bh, dir);
236 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 229 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
237 mark_inode_dirty(dir); 230 mark_inode_dirty(dir);
238 inode->i_ctime = dir->i_ctime; 231 inode->i_ctime = dir->i_ctime;
diff --git a/fs/qnx4/qnx4.h b/fs/qnx4/qnx4.h
new file mode 100644
index 000000000000..9efc089454f6
--- /dev/null
+++ b/fs/qnx4/qnx4.h
@@ -0,0 +1,57 @@
1#include <linux/fs.h>
2#include <linux/qnx4_fs.h>
3
4#define QNX4_DEBUG 0
5
6#if QNX4_DEBUG
7#define QNX4DEBUG(X) printk X
8#else
9#define QNX4DEBUG(X) (void) 0
10#endif
11
12struct qnx4_sb_info {
13 struct buffer_head *sb_buf; /* superblock buffer */
14 struct qnx4_super_block *sb; /* our superblock */
15 unsigned int Version; /* may be useful */
16 struct qnx4_inode_entry *BitMap; /* useful */
17};
18
19struct qnx4_inode_info {
20 struct qnx4_inode_entry raw;
21 loff_t mmu_private;
22 struct inode vfs_inode;
23};
24
25extern struct inode *qnx4_iget(struct super_block *, unsigned long);
26extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd);
27extern unsigned long qnx4_count_free_blocks(struct super_block *sb);
28extern unsigned long qnx4_block_map(struct inode *inode, long iblock);
29
30extern struct buffer_head *qnx4_bread(struct inode *, int, int);
31
32extern const struct inode_operations qnx4_file_inode_operations;
33extern const struct inode_operations qnx4_dir_inode_operations;
34extern const struct file_operations qnx4_file_operations;
35extern const struct file_operations qnx4_dir_operations;
36extern int qnx4_is_free(struct super_block *sb, long block);
37extern int qnx4_set_bitmap(struct super_block *sb, long block, int busy);
38extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode, struct nameidata *nd);
39extern void qnx4_truncate(struct inode *inode);
40extern void qnx4_free_inode(struct inode *inode);
41extern int qnx4_unlink(struct inode *dir, struct dentry *dentry);
42extern int qnx4_rmdir(struct inode *dir, struct dentry *dentry);
43
44static inline struct qnx4_sb_info *qnx4_sb(struct super_block *sb)
45{
46 return sb->s_fs_info;
47}
48
49static inline struct qnx4_inode_info *qnx4_i(struct inode *inode)
50{
51 return container_of(inode, struct qnx4_inode_info, vfs_inode);
52}
53
54static inline struct qnx4_inode_entry *qnx4_raw_inode(struct inode *inode)
55{
56 return &qnx4_i(inode)->raw;
57}
diff --git a/fs/qnx4/truncate.c b/fs/qnx4/truncate.c
index 6437c1c3d1dd..d94d9ee241fe 100644
--- a/fs/qnx4/truncate.c
+++ b/fs/qnx4/truncate.c
@@ -10,12 +10,8 @@
10 * 30-06-1998 by Frank DENIS : ugly filler. 10 * 30-06-1998 by Frank DENIS : ugly filler.
11 */ 11 */
12 12
13#include <linux/types.h>
14#include <linux/errno.h>
15#include <linux/fs.h>
16#include <linux/qnx4_fs.h>
17#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
18#include <asm/uaccess.h> 14#include "qnx4.h"
19 15
20#ifdef CONFIG_QNX4FS_RW 16#ifdef CONFIG_QNX4FS_RW
21 17
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index b7f5a468f076..95c5b42384b2 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -159,10 +159,14 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd,
159 return error; 159 return error;
160} 160}
161 161
162static void quota_sync_sb(struct super_block *sb, int type) 162#ifdef CONFIG_QUOTA
163void sync_quota_sb(struct super_block *sb, int type)
163{ 164{
164 int cnt; 165 int cnt;
165 166
167 if (!sb->s_qcop->quota_sync)
168 return;
169
166 sb->s_qcop->quota_sync(sb, type); 170 sb->s_qcop->quota_sync(sb, type);
167 171
168 if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE) 172 if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
@@ -191,17 +195,13 @@ static void quota_sync_sb(struct super_block *sb, int type)
191 } 195 }
192 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); 196 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
193} 197}
198#endif
194 199
195void sync_dquots(struct super_block *sb, int type) 200static void sync_dquots(int type)
196{ 201{
202 struct super_block *sb;
197 int cnt; 203 int cnt;
198 204
199 if (sb) {
200 if (sb->s_qcop->quota_sync)
201 quota_sync_sb(sb, type);
202 return;
203 }
204
205 spin_lock(&sb_lock); 205 spin_lock(&sb_lock);
206restart: 206restart:
207 list_for_each_entry(sb, &super_blocks, s_list) { 207 list_for_each_entry(sb, &super_blocks, s_list) {
@@ -222,8 +222,8 @@ restart:
222 sb->s_count++; 222 sb->s_count++;
223 spin_unlock(&sb_lock); 223 spin_unlock(&sb_lock);
224 down_read(&sb->s_umount); 224 down_read(&sb->s_umount);
225 if (sb->s_root && sb->s_qcop->quota_sync) 225 if (sb->s_root)
226 quota_sync_sb(sb, type); 226 sync_quota_sb(sb, type);
227 up_read(&sb->s_umount); 227 up_read(&sb->s_umount);
228 spin_lock(&sb_lock); 228 spin_lock(&sb_lock);
229 if (__put_super_and_need_restart(sb)) 229 if (__put_super_and_need_restart(sb))
@@ -301,7 +301,10 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
301 return sb->s_qcop->set_dqblk(sb, type, id, &idq); 301 return sb->s_qcop->set_dqblk(sb, type, id, &idq);
302 } 302 }
303 case Q_SYNC: 303 case Q_SYNC:
304 sync_dquots(sb, type); 304 if (sb)
305 sync_quota_sb(sb, type);
306 else
307 sync_dquots(type);
305 return 0; 308 return 0;
306 309
307 case Q_XQUOTAON: 310 case Q_XQUOTAON:
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 45ee3d357c70..6d2668fdc384 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -44,13 +44,11 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
44static inline bool is_privroot_deh(struct dentry *dir, 44static inline bool is_privroot_deh(struct dentry *dir,
45 struct reiserfs_de_head *deh) 45 struct reiserfs_de_head *deh)
46{ 46{
47 int ret = 0;
48#ifdef CONFIG_REISERFS_FS_XATTR
49 struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; 47 struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root;
50 ret = (dir == dir->d_parent && privroot->d_inode && 48 if (reiserfs_expose_privroot(dir->d_sb))
51 deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); 49 return 0;
52#endif 50 return (dir == dir->d_parent && privroot->d_inode &&
53 return ret; 51 deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid);
54} 52}
55 53
56int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, 54int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 3567fb9e3fb1..2969773cfc22 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -28,6 +28,7 @@
28#include <linux/mount.h> 28#include <linux/mount.h>
29#include <linux/namei.h> 29#include <linux/namei.h>
30#include <linux/crc32.h> 30#include <linux/crc32.h>
31#include <linux/smp_lock.h>
31 32
32struct file_system_type reiserfs_fs_type; 33struct file_system_type reiserfs_fs_type;
33 34
@@ -64,18 +65,15 @@ static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf);
64 65
65static int reiserfs_sync_fs(struct super_block *s, int wait) 66static int reiserfs_sync_fs(struct super_block *s, int wait)
66{ 67{
67 if (!(s->s_flags & MS_RDONLY)) { 68 struct reiserfs_transaction_handle th;
68 struct reiserfs_transaction_handle th; 69
69 reiserfs_write_lock(s); 70 reiserfs_write_lock(s);
70 if (!journal_begin(&th, s, 1)) 71 if (!journal_begin(&th, s, 1))
71 if (!journal_end_sync(&th, s, 1)) 72 if (!journal_end_sync(&th, s, 1))
72 reiserfs_flush_old_commits(s); 73 reiserfs_flush_old_commits(s);
73 s->s_dirt = 0; /* Even if it's not true. 74 s->s_dirt = 0; /* Even if it's not true.
74 * We'll loop forever in sync_supers otherwise */ 75 * We'll loop forever in sync_supers otherwise */
75 reiserfs_write_unlock(s); 76 reiserfs_write_unlock(s);
76 } else {
77 s->s_dirt = 0;
78 }
79 return 0; 77 return 0;
80} 78}
81 79
@@ -468,6 +466,11 @@ static void reiserfs_put_super(struct super_block *s)
468 struct reiserfs_transaction_handle th; 466 struct reiserfs_transaction_handle th;
469 th.t_trans_id = 0; 467 th.t_trans_id = 0;
470 468
469 lock_kernel();
470
471 if (s->s_dirt)
472 reiserfs_write_super(s);
473
471 /* change file system state to current state if it was mounted with read-write permissions */ 474 /* change file system state to current state if it was mounted with read-write permissions */
472 if (!(s->s_flags & MS_RDONLY)) { 475 if (!(s->s_flags & MS_RDONLY)) {
473 if (!journal_begin(&th, s, 10)) { 476 if (!journal_begin(&th, s, 10)) {
@@ -500,7 +503,7 @@ static void reiserfs_put_super(struct super_block *s)
500 kfree(s->s_fs_info); 503 kfree(s->s_fs_info);
501 s->s_fs_info = NULL; 504 s->s_fs_info = NULL;
502 505
503 return; 506 unlock_kernel();
504} 507}
505 508
506static struct kmem_cache *reiserfs_inode_cachep; 509static struct kmem_cache *reiserfs_inode_cachep;
@@ -898,6 +901,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
898 {"conv",.setmask = 1 << REISERFS_CONVERT}, 901 {"conv",.setmask = 1 << REISERFS_CONVERT},
899 {"attrs",.setmask = 1 << REISERFS_ATTRS}, 902 {"attrs",.setmask = 1 << REISERFS_ATTRS},
900 {"noattrs",.clrmask = 1 << REISERFS_ATTRS}, 903 {"noattrs",.clrmask = 1 << REISERFS_ATTRS},
904 {"expose_privroot", .setmask = 1 << REISERFS_EXPOSE_PRIVROOT},
901#ifdef CONFIG_REISERFS_FS_XATTR 905#ifdef CONFIG_REISERFS_FS_XATTR
902 {"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER}, 906 {"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER},
903 {"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER}, 907 {"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},
@@ -1193,6 +1197,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1193 memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names)); 1197 memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names));
1194#endif 1198#endif
1195 1199
1200 lock_kernel();
1196 rs = SB_DISK_SUPER_BLOCK(s); 1201 rs = SB_DISK_SUPER_BLOCK(s);
1197 1202
1198 if (!reiserfs_parse_options 1203 if (!reiserfs_parse_options
@@ -1315,10 +1320,12 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1315 1320
1316out_ok: 1321out_ok:
1317 replace_mount_options(s, new_opts); 1322 replace_mount_options(s, new_opts);
1323 unlock_kernel();
1318 return 0; 1324 return 0;
1319 1325
1320out_err: 1326out_err:
1321 kfree(new_opts); 1327 kfree(new_opts);
1328 unlock_kernel();
1322 return err; 1329 return err;
1323} 1330}
1324 1331
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 8e7deb0e6964..f3d47d856848 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -981,7 +981,8 @@ int reiserfs_lookup_privroot(struct super_block *s)
981 strlen(PRIVROOT_NAME)); 981 strlen(PRIVROOT_NAME));
982 if (!IS_ERR(dentry)) { 982 if (!IS_ERR(dentry)) {
983 REISERFS_SB(s)->priv_root = dentry; 983 REISERFS_SB(s)->priv_root = dentry;
984 s->s_root->d_op = &xattr_lookup_poison_ops; 984 if (!reiserfs_expose_privroot(s))
985 s->s_root->d_op = &xattr_lookup_poison_ops;
985 if (dentry->d_inode) 986 if (dentry->d_inode)
986 dentry->d_inode->i_flags |= S_PRIVATE; 987 dentry->d_inode->i_flags |= S_PRIVATE;
987 } else 988 } else
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index fc27fbfc5397..1402d2d54f52 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -474,6 +474,8 @@ smb_put_super(struct super_block *sb)
474{ 474{
475 struct smb_sb_info *server = SMB_SB(sb); 475 struct smb_sb_info *server = SMB_SB(sb);
476 476
477 lock_kernel();
478
477 smb_lock_server(server); 479 smb_lock_server(server);
478 server->state = CONN_INVALID; 480 server->state = CONN_INVALID;
479 smbiod_unregister_server(server); 481 smbiod_unregister_server(server);
@@ -489,6 +491,8 @@ smb_put_super(struct super_block *sb)
489 smb_unlock_server(server); 491 smb_unlock_server(server);
490 put_pid(server->conn_pid); 492 put_pid(server->conn_pid);
491 kfree(server); 493 kfree(server);
494
495 unlock_kernel();
492} 496}
493 497
494static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) 498static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 0adc624c956f..3b52770f46ff 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -338,6 +338,8 @@ static int squashfs_remount(struct super_block *sb, int *flags, char *data)
338 338
339static void squashfs_put_super(struct super_block *sb) 339static void squashfs_put_super(struct super_block *sb)
340{ 340{
341 lock_kernel();
342
341 if (sb->s_fs_info) { 343 if (sb->s_fs_info) {
342 struct squashfs_sb_info *sbi = sb->s_fs_info; 344 struct squashfs_sb_info *sbi = sb->s_fs_info;
343 squashfs_cache_delete(sbi->block_cache); 345 squashfs_cache_delete(sbi->block_cache);
@@ -350,6 +352,8 @@ static void squashfs_put_super(struct super_block *sb)
350 kfree(sb->s_fs_info); 352 kfree(sb->s_fs_info);
351 sb->s_fs_info = NULL; 353 sb->s_fs_info = NULL;
352 } 354 }
355
356 unlock_kernel();
353} 357}
354 358
355 359
diff --git a/fs/super.c b/fs/super.c
index 1943fdf655fa..83b47416d006 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -28,7 +28,6 @@
28#include <linux/blkdev.h> 28#include <linux/blkdev.h>
29#include <linux/quotaops.h> 29#include <linux/quotaops.h>
30#include <linux/namei.h> 30#include <linux/namei.h>
31#include <linux/buffer_head.h> /* for fsync_super() */
32#include <linux/mount.h> 31#include <linux/mount.h>
33#include <linux/security.h> 32#include <linux/security.h>
34#include <linux/syscalls.h> 33#include <linux/syscalls.h>
@@ -38,7 +37,6 @@
38#include <linux/kobject.h> 37#include <linux/kobject.h>
39#include <linux/mutex.h> 38#include <linux/mutex.h>
40#include <linux/file.h> 39#include <linux/file.h>
41#include <linux/async.h>
42#include <asm/uaccess.h> 40#include <asm/uaccess.h>
43#include "internal.h" 41#include "internal.h"
44 42
@@ -72,7 +70,6 @@ static struct super_block *alloc_super(struct file_system_type *type)
72 INIT_HLIST_HEAD(&s->s_anon); 70 INIT_HLIST_HEAD(&s->s_anon);
73 INIT_LIST_HEAD(&s->s_inodes); 71 INIT_LIST_HEAD(&s->s_inodes);
74 INIT_LIST_HEAD(&s->s_dentry_lru); 72 INIT_LIST_HEAD(&s->s_dentry_lru);
75 INIT_LIST_HEAD(&s->s_async_list);
76 init_rwsem(&s->s_umount); 73 init_rwsem(&s->s_umount);
77 mutex_init(&s->s_lock); 74 mutex_init(&s->s_lock);
78 lockdep_set_class(&s->s_umount, &type->s_umount_key); 75 lockdep_set_class(&s->s_umount, &type->s_umount_key);
@@ -285,38 +282,6 @@ void unlock_super(struct super_block * sb)
285EXPORT_SYMBOL(lock_super); 282EXPORT_SYMBOL(lock_super);
286EXPORT_SYMBOL(unlock_super); 283EXPORT_SYMBOL(unlock_super);
287 284
288/*
289 * Write out and wait upon all dirty data associated with this
290 * superblock. Filesystem data as well as the underlying block
291 * device. Takes the superblock lock. Requires a second blkdev
292 * flush by the caller to complete the operation.
293 */
294void __fsync_super(struct super_block *sb)
295{
296 sync_inodes_sb(sb, 0);
297 vfs_dq_sync(sb);
298 lock_super(sb);
299 if (sb->s_dirt && sb->s_op->write_super)
300 sb->s_op->write_super(sb);
301 unlock_super(sb);
302 if (sb->s_op->sync_fs)
303 sb->s_op->sync_fs(sb, 1);
304 sync_blockdev(sb->s_bdev);
305 sync_inodes_sb(sb, 1);
306}
307
308/*
309 * Write out and wait upon all dirty data associated with this
310 * superblock. Filesystem data as well as the underlying block
311 * device. Takes the superblock lock.
312 */
313int fsync_super(struct super_block *sb)
314{
315 __fsync_super(sb);
316 return sync_blockdev(sb->s_bdev);
317}
318EXPORT_SYMBOL_GPL(fsync_super);
319
320/** 285/**
321 * generic_shutdown_super - common helper for ->kill_sb() 286 * generic_shutdown_super - common helper for ->kill_sb()
322 * @sb: superblock to kill 287 * @sb: superblock to kill
@@ -338,21 +303,13 @@ void generic_shutdown_super(struct super_block *sb)
338 303
339 if (sb->s_root) { 304 if (sb->s_root) {
340 shrink_dcache_for_umount(sb); 305 shrink_dcache_for_umount(sb);
341 fsync_super(sb); 306 sync_filesystem(sb);
342 lock_super(sb); 307 get_fs_excl();
343 sb->s_flags &= ~MS_ACTIVE; 308 sb->s_flags &= ~MS_ACTIVE;
344 309
345 /*
346 * wait for asynchronous fs operations to finish before going further
347 */
348 async_synchronize_full_domain(&sb->s_async_list);
349
350 /* bad name - it should be evict_inodes() */ 310 /* bad name - it should be evict_inodes() */
351 invalidate_inodes(sb); 311 invalidate_inodes(sb);
352 lock_kernel();
353 312
354 if (sop->write_super && sb->s_dirt)
355 sop->write_super(sb);
356 if (sop->put_super) 313 if (sop->put_super)
357 sop->put_super(sb); 314 sop->put_super(sb);
358 315
@@ -362,9 +319,7 @@ void generic_shutdown_super(struct super_block *sb)
362 "Self-destruct in 5 seconds. Have a nice day...\n", 319 "Self-destruct in 5 seconds. Have a nice day...\n",
363 sb->s_id); 320 sb->s_id);
364 } 321 }
365 322 put_fs_excl();
366 unlock_kernel();
367 unlock_super(sb);
368 } 323 }
369 spin_lock(&sb_lock); 324 spin_lock(&sb_lock);
370 /* should be initialized for __put_super_and_need_restart() */ 325 /* should be initialized for __put_super_and_need_restart() */
@@ -441,16 +396,14 @@ void drop_super(struct super_block *sb)
441 396
442EXPORT_SYMBOL(drop_super); 397EXPORT_SYMBOL(drop_super);
443 398
444static inline void write_super(struct super_block *sb) 399/**
445{ 400 * sync_supers - helper for periodic superblock writeback
446 lock_super(sb); 401 *
447 if (sb->s_root && sb->s_dirt) 402 * Call the write_super method if present on all dirty superblocks in
448 if (sb->s_op->write_super) 403 * the system. This is for the periodic writeback used by most older
449 sb->s_op->write_super(sb); 404 * filesystems. For data integrity superblock writeback use
450 unlock_super(sb); 405 * sync_filesystems() instead.
451} 406 *
452
453/*
454 * Note: check the dirty flag before waiting, so we don't 407 * Note: check the dirty flag before waiting, so we don't
455 * hold up the sync while mounting a device. (The newly 408 * hold up the sync while mounting a device. (The newly
456 * mounted device won't need syncing.) 409 * mounted device won't need syncing.)
@@ -462,12 +415,15 @@ void sync_supers(void)
462 spin_lock(&sb_lock); 415 spin_lock(&sb_lock);
463restart: 416restart:
464 list_for_each_entry(sb, &super_blocks, s_list) { 417 list_for_each_entry(sb, &super_blocks, s_list) {
465 if (sb->s_dirt) { 418 if (sb->s_op->write_super && sb->s_dirt) {
466 sb->s_count++; 419 sb->s_count++;
467 spin_unlock(&sb_lock); 420 spin_unlock(&sb_lock);
421
468 down_read(&sb->s_umount); 422 down_read(&sb->s_umount);
469 write_super(sb); 423 if (sb->s_root && sb->s_dirt)
424 sb->s_op->write_super(sb);
470 up_read(&sb->s_umount); 425 up_read(&sb->s_umount);
426
471 spin_lock(&sb_lock); 427 spin_lock(&sb_lock);
472 if (__put_super_and_need_restart(sb)) 428 if (__put_super_and_need_restart(sb))
473 goto restart; 429 goto restart;
@@ -476,60 +432,6 @@ restart:
476 spin_unlock(&sb_lock); 432 spin_unlock(&sb_lock);
477} 433}
478 434
479/*
480 * Call the ->sync_fs super_op against all filesystems which are r/w and
481 * which implement it.
482 *
483 * This operation is careful to avoid the livelock which could easily happen
484 * if two or more filesystems are being continuously dirtied. s_need_sync_fs
485 * is used only here. We set it against all filesystems and then clear it as
486 * we sync them. So redirtied filesystems are skipped.
487 *
488 * But if process A is currently running sync_filesystems and then process B
489 * calls sync_filesystems as well, process B will set all the s_need_sync_fs
490 * flags again, which will cause process A to resync everything. Fix that with
491 * a local mutex.
492 *
493 * (Fabian) Avoid sync_fs with clean fs & wait mode 0
494 */
495void sync_filesystems(int wait)
496{
497 struct super_block *sb;
498 static DEFINE_MUTEX(mutex);
499
500 mutex_lock(&mutex); /* Could be down_interruptible */
501 spin_lock(&sb_lock);
502 list_for_each_entry(sb, &super_blocks, s_list) {
503 if (!sb->s_op->sync_fs)
504 continue;
505 if (sb->s_flags & MS_RDONLY)
506 continue;
507 sb->s_need_sync_fs = 1;
508 }
509
510restart:
511 list_for_each_entry(sb, &super_blocks, s_list) {
512 if (!sb->s_need_sync_fs)
513 continue;
514 sb->s_need_sync_fs = 0;
515 if (sb->s_flags & MS_RDONLY)
516 continue; /* hm. Was remounted r/o meanwhile */
517 sb->s_count++;
518 spin_unlock(&sb_lock);
519 down_read(&sb->s_umount);
520 async_synchronize_full_domain(&sb->s_async_list);
521 if (sb->s_root && (wait || sb->s_dirt))
522 sb->s_op->sync_fs(sb, wait);
523 up_read(&sb->s_umount);
524 /* restart only when sb is no longer on the list */
525 spin_lock(&sb_lock);
526 if (__put_super_and_need_restart(sb))
527 goto restart;
528 }
529 spin_unlock(&sb_lock);
530 mutex_unlock(&mutex);
531}
532
533/** 435/**
534 * get_super - get the superblock of a device 436 * get_super - get the superblock of a device
535 * @bdev: device to get the superblock for 437 * @bdev: device to get the superblock for
@@ -616,45 +518,6 @@ out:
616} 518}
617 519
618/** 520/**
619 * mark_files_ro - mark all files read-only
620 * @sb: superblock in question
621 *
622 * All files are marked read-only. We don't care about pending
623 * delete files so this should be used in 'force' mode only.
624 */
625
626static void mark_files_ro(struct super_block *sb)
627{
628 struct file *f;
629
630retry:
631 file_list_lock();
632 list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
633 struct vfsmount *mnt;
634 if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
635 continue;
636 if (!file_count(f))
637 continue;
638 if (!(f->f_mode & FMODE_WRITE))
639 continue;
640 f->f_mode &= ~FMODE_WRITE;
641 if (file_check_writeable(f) != 0)
642 continue;
643 file_release_write(f);
644 mnt = mntget(f->f_path.mnt);
645 file_list_unlock();
646 /*
647 * This can sleep, so we can't hold
648 * the file_list_lock() spinlock.
649 */
650 mnt_drop_write(mnt);
651 mntput(mnt);
652 goto retry;
653 }
654 file_list_unlock();
655}
656
657/**
658 * do_remount_sb - asks filesystem to change mount options. 521 * do_remount_sb - asks filesystem to change mount options.
659 * @sb: superblock in question 522 * @sb: superblock in question
660 * @flags: numeric part of options 523 * @flags: numeric part of options
@@ -675,27 +538,31 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
675 if (flags & MS_RDONLY) 538 if (flags & MS_RDONLY)
676 acct_auto_close(sb); 539 acct_auto_close(sb);
677 shrink_dcache_sb(sb); 540 shrink_dcache_sb(sb);
678 fsync_super(sb); 541 sync_filesystem(sb);
679 542
680 /* If we are remounting RDONLY and current sb is read/write, 543 /* If we are remounting RDONLY and current sb is read/write,
681 make sure there are no rw files opened */ 544 make sure there are no rw files opened */
682 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) { 545 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) {
683 if (force) 546 if (force)
684 mark_files_ro(sb); 547 mark_files_ro(sb);
685 else if (!fs_may_remount_ro(sb)) 548 else if (!fs_may_remount_ro(sb)) {
549 unlock_kernel();
686 return -EBUSY; 550 return -EBUSY;
551 }
687 retval = vfs_dq_off(sb, 1); 552 retval = vfs_dq_off(sb, 1);
688 if (retval < 0 && retval != -ENOSYS) 553 if (retval < 0 && retval != -ENOSYS) {
554 unlock_kernel();
689 return -EBUSY; 555 return -EBUSY;
556 }
690 } 557 }
691 remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); 558 remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
692 559
693 if (sb->s_op->remount_fs) { 560 if (sb->s_op->remount_fs) {
694 lock_super(sb);
695 retval = sb->s_op->remount_fs(sb, &flags, data); 561 retval = sb->s_op->remount_fs(sb, &flags, data);
696 unlock_super(sb); 562 if (retval) {
697 if (retval) 563 unlock_kernel();
698 return retval; 564 return retval;
565 }
699 } 566 }
700 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); 567 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
701 if (remount_rw) 568 if (remount_rw)
@@ -711,18 +578,17 @@ static void do_emergency_remount(struct work_struct *work)
711 list_for_each_entry(sb, &super_blocks, s_list) { 578 list_for_each_entry(sb, &super_blocks, s_list) {
712 sb->s_count++; 579 sb->s_count++;
713 spin_unlock(&sb_lock); 580 spin_unlock(&sb_lock);
714 down_read(&sb->s_umount); 581 down_write(&sb->s_umount);
715 if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) { 582 if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) {
716 /* 583 /*
717 * ->remount_fs needs lock_kernel(). 584 * ->remount_fs needs lock_kernel().
718 * 585 *
719 * What lock protects sb->s_flags?? 586 * What lock protects sb->s_flags??
720 */ 587 */
721 lock_kernel();
722 do_remount_sb(sb, MS_RDONLY, NULL, 1); 588 do_remount_sb(sb, MS_RDONLY, NULL, 1);
723 unlock_kernel();
724 } 589 }
725 drop_super(sb); 590 up_write(&sb->s_umount);
591 put_super(sb);
726 spin_lock(&sb_lock); 592 spin_lock(&sb_lock);
727 } 593 }
728 spin_unlock(&sb_lock); 594 spin_unlock(&sb_lock);
diff --git a/fs/sync.c b/fs/sync.c
index 7abc65fbf21d..dd200025af85 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -13,38 +13,123 @@
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/quotaops.h> 14#include <linux/quotaops.h>
15#include <linux/buffer_head.h> 15#include <linux/buffer_head.h>
16#include "internal.h"
16 17
17#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ 18#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
18 SYNC_FILE_RANGE_WAIT_AFTER) 19 SYNC_FILE_RANGE_WAIT_AFTER)
19 20
20/* 21/*
21 * sync everything. Start out by waking pdflush, because that writes back 22 * Do the filesystem syncing work. For simple filesystems sync_inodes_sb(sb, 0)
22 * all queues in parallel. 23 * just dirties buffers with inodes so we have to submit IO for these buffers
24 * via __sync_blockdev(). This also speeds up the wait == 1 case since in that
25 * case write_inode() functions do sync_dirty_buffer() and thus effectively
26 * write one block at a time.
23 */ 27 */
24static void do_sync(unsigned long wait) 28static int __sync_filesystem(struct super_block *sb, int wait)
25{ 29{
26 wakeup_pdflush(0); 30 /* Avoid doing twice syncing and cache pruning for quota sync */
27 sync_inodes(0); /* All mappings, inodes and their blockdevs */
28 vfs_dq_sync(NULL);
29 sync_supers(); /* Write the superblocks */
30 sync_filesystems(0); /* Start syncing the filesystems */
31 sync_filesystems(wait); /* Waitingly sync the filesystems */
32 sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */
33 if (!wait) 31 if (!wait)
34 printk("Emergency Sync complete\n"); 32 writeout_quota_sb(sb, -1);
35 if (unlikely(laptop_mode)) 33 else
36 laptop_sync_completion(); 34 sync_quota_sb(sb, -1);
35 sync_inodes_sb(sb, wait);
36 if (sb->s_op->sync_fs)
37 sb->s_op->sync_fs(sb, wait);
38 return __sync_blockdev(sb->s_bdev, wait);
39}
40
41/*
42 * Write out and wait upon all dirty data associated with this
43 * superblock. Filesystem data as well as the underlying block
44 * device. Takes the superblock lock.
45 */
46int sync_filesystem(struct super_block *sb)
47{
48 int ret;
49
50 /*
51 * We need to be protected against the filesystem going from
52 * r/o to r/w or vice versa.
53 */
54 WARN_ON(!rwsem_is_locked(&sb->s_umount));
55
56 /*
57 * No point in syncing out anything if the filesystem is read-only.
58 */
59 if (sb->s_flags & MS_RDONLY)
60 return 0;
61
62 ret = __sync_filesystem(sb, 0);
63 if (ret < 0)
64 return ret;
65 return __sync_filesystem(sb, 1);
66}
67EXPORT_SYMBOL_GPL(sync_filesystem);
68
69/*
70 * Sync all the data for all the filesystems (called by sys_sync() and
71 * emergency sync)
72 *
73 * This operation is careful to avoid the livelock which could easily happen
74 * if two or more filesystems are being continuously dirtied. s_need_sync
75 * is used only here. We set it against all filesystems and then clear it as
76 * we sync them. So redirtied filesystems are skipped.
77 *
78 * But if process A is currently running sync_filesystems and then process B
79 * calls sync_filesystems as well, process B will set all the s_need_sync
80 * flags again, which will cause process A to resync everything. Fix that with
81 * a local mutex.
82 */
83static void sync_filesystems(int wait)
84{
85 struct super_block *sb;
86 static DEFINE_MUTEX(mutex);
87
88 mutex_lock(&mutex); /* Could be down_interruptible */
89 spin_lock(&sb_lock);
90 list_for_each_entry(sb, &super_blocks, s_list)
91 sb->s_need_sync = 1;
92
93restart:
94 list_for_each_entry(sb, &super_blocks, s_list) {
95 if (!sb->s_need_sync)
96 continue;
97 sb->s_need_sync = 0;
98 sb->s_count++;
99 spin_unlock(&sb_lock);
100
101 down_read(&sb->s_umount);
102 if (!(sb->s_flags & MS_RDONLY) && sb->s_root)
103 __sync_filesystem(sb, wait);
104 up_read(&sb->s_umount);
105
106 /* restart only when sb is no longer on the list */
107 spin_lock(&sb_lock);
108 if (__put_super_and_need_restart(sb))
109 goto restart;
110 }
111 spin_unlock(&sb_lock);
112 mutex_unlock(&mutex);
37} 113}
38 114
39SYSCALL_DEFINE0(sync) 115SYSCALL_DEFINE0(sync)
40{ 116{
41 do_sync(1); 117 sync_filesystems(0);
118 sync_filesystems(1);
119 if (unlikely(laptop_mode))
120 laptop_sync_completion();
42 return 0; 121 return 0;
43} 122}
44 123
45static void do_sync_work(struct work_struct *work) 124static void do_sync_work(struct work_struct *work)
46{ 125{
47 do_sync(0); 126 /*
127 * Sync twice to reduce the possibility we skipped some inodes / pages
128 * because they were temporarily locked
129 */
130 sync_filesystems(0);
131 sync_filesystems(0);
132 printk("Emergency Sync complete\n");
48 kfree(work); 133 kfree(work);
49} 134}
50 135
@@ -75,10 +160,8 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
75 160
76 /* sync the superblock to buffers */ 161 /* sync the superblock to buffers */
77 sb = inode->i_sb; 162 sb = inode->i_sb;
78 lock_super(sb);
79 if (sb->s_dirt && sb->s_op->write_super) 163 if (sb->s_dirt && sb->s_op->write_super)
80 sb->s_op->write_super(sb); 164 sb->s_op->write_super(sb);
81 unlock_super(sb);
82 165
83 /* .. finally sync the buffers to disk */ 166 /* .. finally sync the buffers to disk */
84 err = sync_blockdev(sb->s_bdev); 167 err = sync_blockdev(sb->s_bdev);
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 56f655254bfe..c7798079e644 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -24,7 +24,7 @@ static int sysv_readdir(struct file *, void *, filldir_t);
24const struct file_operations sysv_dir_operations = { 24const struct file_operations sysv_dir_operations = {
25 .read = generic_read_dir, 25 .read = generic_read_dir,
26 .readdir = sysv_readdir, 26 .readdir = sysv_readdir,
27 .fsync = sysv_sync_file, 27 .fsync = simple_fsync,
28}; 28};
29 29
30static inline void dir_put_page(struct page *page) 30static inline void dir_put_page(struct page *page)
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index 589be21d884e..96340c01f4a7 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -26,7 +26,7 @@ const struct file_operations sysv_file_operations = {
26 .write = do_sync_write, 26 .write = do_sync_write,
27 .aio_write = generic_file_aio_write, 27 .aio_write = generic_file_aio_write,
28 .mmap = generic_file_mmap, 28 .mmap = generic_file_mmap,
29 .fsync = sysv_sync_file, 29 .fsync = simple_fsync,
30 .splice_read = generic_file_splice_read, 30 .splice_read = generic_file_splice_read,
31}; 31};
32 32
@@ -34,18 +34,3 @@ const struct inode_operations sysv_file_inode_operations = {
34 .truncate = sysv_truncate, 34 .truncate = sysv_truncate,
35 .getattr = sysv_getattr, 35 .getattr = sysv_getattr,
36}; 36};
37
38int sysv_sync_file(struct file * file, struct dentry *dentry, int datasync)
39{
40 struct inode *inode = dentry->d_inode;
41 int err;
42
43 err = sync_mapping_buffers(inode->i_mapping);
44 if (!(inode->i_state & I_DIRTY))
45 return err;
46 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
47 return err;
48
49 err |= sysv_sync_inode(inode);
50 return err ? -EIO : 0;
51}
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index da20b48d350f..479923456a54 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -31,15 +31,13 @@
31#include <asm/byteorder.h> 31#include <asm/byteorder.h>
32#include "sysv.h" 32#include "sysv.h"
33 33
34/* This is only called on sync() and umount(), when s_dirt=1. */ 34static int sysv_sync_fs(struct super_block *sb, int wait)
35static void sysv_write_super(struct super_block *sb)
36{ 35{
37 struct sysv_sb_info *sbi = SYSV_SB(sb); 36 struct sysv_sb_info *sbi = SYSV_SB(sb);
38 unsigned long time = get_seconds(), old_time; 37 unsigned long time = get_seconds(), old_time;
39 38
39 lock_super(sb);
40 lock_kernel(); 40 lock_kernel();
41 if (sb->s_flags & MS_RDONLY)
42 goto clean;
43 41
44 /* 42 /*
45 * If we are going to write out the super block, 43 * If we are going to write out the super block,
@@ -53,18 +51,30 @@ static void sysv_write_super(struct super_block *sb)
53 *sbi->s_sb_time = cpu_to_fs32(sbi, time); 51 *sbi->s_sb_time = cpu_to_fs32(sbi, time);
54 mark_buffer_dirty(sbi->s_bh2); 52 mark_buffer_dirty(sbi->s_bh2);
55 } 53 }
56clean: 54
57 sb->s_dirt = 0;
58 unlock_kernel(); 55 unlock_kernel();
56 unlock_super(sb);
57
58 return 0;
59}
60
61static void sysv_write_super(struct super_block *sb)
62{
63 if (!(sb->s_flags & MS_RDONLY))
64 sysv_sync_fs(sb, 1);
65 else
66 sb->s_dirt = 0;
59} 67}
60 68
61static int sysv_remount(struct super_block *sb, int *flags, char *data) 69static int sysv_remount(struct super_block *sb, int *flags, char *data)
62{ 70{
63 struct sysv_sb_info *sbi = SYSV_SB(sb); 71 struct sysv_sb_info *sbi = SYSV_SB(sb);
72 lock_super(sb);
64 if (sbi->s_forced_ro) 73 if (sbi->s_forced_ro)
65 *flags |= MS_RDONLY; 74 *flags |= MS_RDONLY;
66 if (!(*flags & MS_RDONLY)) 75 if (!(*flags & MS_RDONLY))
67 sb->s_dirt = 1; 76 sb->s_dirt = 1;
77 unlock_super(sb);
68 return 0; 78 return 0;
69} 79}
70 80
@@ -72,6 +82,11 @@ static void sysv_put_super(struct super_block *sb)
72{ 82{
73 struct sysv_sb_info *sbi = SYSV_SB(sb); 83 struct sysv_sb_info *sbi = SYSV_SB(sb);
74 84
85 lock_kernel();
86
87 if (sb->s_dirt)
88 sysv_write_super(sb);
89
75 if (!(sb->s_flags & MS_RDONLY)) { 90 if (!(sb->s_flags & MS_RDONLY)) {
76 /* XXX ext2 also updates the state here */ 91 /* XXX ext2 also updates the state here */
77 mark_buffer_dirty(sbi->s_bh1); 92 mark_buffer_dirty(sbi->s_bh1);
@@ -84,6 +99,8 @@ static void sysv_put_super(struct super_block *sb)
84 brelse(sbi->s_bh2); 99 brelse(sbi->s_bh2);
85 100
86 kfree(sbi); 101 kfree(sbi);
102
103 unlock_kernel();
87} 104}
88 105
89static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) 106static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -236,7 +253,7 @@ bad_inode:
236 return ERR_PTR(-EIO); 253 return ERR_PTR(-EIO);
237} 254}
238 255
239static struct buffer_head * sysv_update_inode(struct inode * inode) 256int sysv_write_inode(struct inode *inode, int wait)
240{ 257{
241 struct super_block * sb = inode->i_sb; 258 struct super_block * sb = inode->i_sb;
242 struct sysv_sb_info * sbi = SYSV_SB(sb); 259 struct sysv_sb_info * sbi = SYSV_SB(sb);
@@ -244,19 +261,21 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
244 struct sysv_inode * raw_inode; 261 struct sysv_inode * raw_inode;
245 struct sysv_inode_info * si; 262 struct sysv_inode_info * si;
246 unsigned int ino, block; 263 unsigned int ino, block;
264 int err = 0;
247 265
248 ino = inode->i_ino; 266 ino = inode->i_ino;
249 if (!ino || ino > sbi->s_ninodes) { 267 if (!ino || ino > sbi->s_ninodes) {
250 printk("Bad inode number on dev %s: %d is out of range\n", 268 printk("Bad inode number on dev %s: %d is out of range\n",
251 inode->i_sb->s_id, ino); 269 inode->i_sb->s_id, ino);
252 return NULL; 270 return -EIO;
253 } 271 }
254 raw_inode = sysv_raw_inode(sb, ino, &bh); 272 raw_inode = sysv_raw_inode(sb, ino, &bh);
255 if (!raw_inode) { 273 if (!raw_inode) {
256 printk("unable to read i-node block\n"); 274 printk("unable to read i-node block\n");
257 return NULL; 275 return -EIO;
258 } 276 }
259 277
278 lock_kernel();
260 raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); 279 raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode);
261 raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); 280 raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid));
262 raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); 281 raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid));
@@ -272,38 +291,23 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
272 for (block = 0; block < 10+1+1+1; block++) 291 for (block = 0; block < 10+1+1+1; block++)
273 write3byte(sbi, (u8 *)&si->i_data[block], 292 write3byte(sbi, (u8 *)&si->i_data[block],
274 &raw_inode->i_data[3*block]); 293 &raw_inode->i_data[3*block]);
294 unlock_kernel();
275 mark_buffer_dirty(bh); 295 mark_buffer_dirty(bh);
276 return bh; 296 if (wait) {
277} 297 sync_dirty_buffer(bh);
278 298 if (buffer_req(bh) && !buffer_uptodate(bh)) {
279int sysv_write_inode(struct inode * inode, int wait) 299 printk ("IO error syncing sysv inode [%s:%08x]\n",
280{ 300 sb->s_id, ino);
281 struct buffer_head *bh; 301 err = -EIO;
282 lock_kernel(); 302 }
283 bh = sysv_update_inode(inode); 303 }
284 brelse(bh); 304 brelse(bh);
285 unlock_kernel();
286 return 0; 305 return 0;
287} 306}
288 307
289int sysv_sync_inode(struct inode * inode) 308int sysv_sync_inode(struct inode *inode)
290{ 309{
291 int err = 0; 310 return sysv_write_inode(inode, 1);
292 struct buffer_head *bh;
293
294 bh = sysv_update_inode(inode);
295 if (bh && buffer_dirty(bh)) {
296 sync_dirty_buffer(bh);
297 if (buffer_req(bh) && !buffer_uptodate(bh)) {
298 printk ("IO error syncing sysv inode [%s:%08lx]\n",
299 inode->i_sb->s_id, inode->i_ino);
300 err = -1;
301 }
302 }
303 else if (!bh)
304 err = -1;
305 brelse (bh);
306 return err;
307} 311}
308 312
309static void sysv_delete_inode(struct inode *inode) 313static void sysv_delete_inode(struct inode *inode)
@@ -347,6 +351,7 @@ const struct super_operations sysv_sops = {
347 .delete_inode = sysv_delete_inode, 351 .delete_inode = sysv_delete_inode,
348 .put_super = sysv_put_super, 352 .put_super = sysv_put_super,
349 .write_super = sysv_write_super, 353 .write_super = sysv_write_super,
354 .sync_fs = sysv_sync_fs,
350 .remount_fs = sysv_remount, 355 .remount_fs = sysv_remount,
351 .statfs = sysv_statfs, 356 .statfs = sysv_statfs,
352}; 357};
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 5784a318c883..53786eb5cf60 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -144,7 +144,6 @@ extern int __sysv_write_begin(struct file *file, struct address_space *mapping,
144extern struct inode *sysv_iget(struct super_block *, unsigned int); 144extern struct inode *sysv_iget(struct super_block *, unsigned int);
145extern int sysv_write_inode(struct inode *, int); 145extern int sysv_write_inode(struct inode *, int);
146extern int sysv_sync_inode(struct inode *); 146extern int sysv_sync_inode(struct inode *);
147extern int sysv_sync_file(struct file *, struct dentry *, int);
148extern void sysv_set_inode(struct inode *, dev_t); 147extern void sysv_set_inode(struct inode *, dev_t);
149extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); 148extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
150extern int sysv_init_icache(void); 149extern int sysv_init_icache(void);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index e9f7a754c4f7..3589eab02a2f 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,7 @@
36#include <linux/mount.h> 36#include <linux/mount.h>
37#include <linux/math64.h> 37#include <linux/math64.h>
38#include <linux/writeback.h> 38#include <linux/writeback.h>
39#include <linux/smp_lock.h>
39#include "ubifs.h" 40#include "ubifs.h"
40 41
41/* 42/*
@@ -447,9 +448,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
447 if (!wait) 448 if (!wait)
448 return 0; 449 return 0;
449 450
450 if (sb->s_flags & MS_RDONLY)
451 return 0;
452
453 /* 451 /*
454 * VFS calls '->sync_fs()' before synchronizing all dirty inodes and 452 * VFS calls '->sync_fs()' before synchronizing all dirty inodes and
455 * pages, so synchronize them first, then commit the journal. Strictly 453 * pages, so synchronize them first, then commit the journal. Strictly
@@ -1687,6 +1685,9 @@ static void ubifs_put_super(struct super_block *sb)
1687 1685
1688 ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num, 1686 ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num,
1689 c->vi.vol_id); 1687 c->vi.vol_id);
1688
1689 lock_kernel();
1690
1690 /* 1691 /*
1691 * The following asserts are only valid if there has not been a failure 1692 * The following asserts are only valid if there has not been a failure
1692 * of the media. For example, there will be dirty inodes if we failed 1693 * of the media. For example, there will be dirty inodes if we failed
@@ -1753,6 +1754,8 @@ static void ubifs_put_super(struct super_block *sb)
1753 ubi_close_volume(c->ubi); 1754 ubi_close_volume(c->ubi);
1754 mutex_unlock(&c->umount_mutex); 1755 mutex_unlock(&c->umount_mutex);
1755 kfree(c); 1756 kfree(c);
1757
1758 unlock_kernel();
1756} 1759}
1757 1760
1758static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) 1761static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -1768,17 +1771,22 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
1768 return err; 1771 return err;
1769 } 1772 }
1770 1773
1774 lock_kernel();
1771 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { 1775 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
1772 if (c->ro_media) { 1776 if (c->ro_media) {
1773 ubifs_msg("cannot re-mount due to prior errors"); 1777 ubifs_msg("cannot re-mount due to prior errors");
1778 unlock_kernel();
1774 return -EROFS; 1779 return -EROFS;
1775 } 1780 }
1776 err = ubifs_remount_rw(c); 1781 err = ubifs_remount_rw(c);
1777 if (err) 1782 if (err) {
1783 unlock_kernel();
1778 return err; 1784 return err;
1785 }
1779 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { 1786 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
1780 if (c->ro_media) { 1787 if (c->ro_media) {
1781 ubifs_msg("cannot re-mount due to prior errors"); 1788 ubifs_msg("cannot re-mount due to prior errors");
1789 unlock_kernel();
1782 return -EROFS; 1790 return -EROFS;
1783 } 1791 }
1784 ubifs_remount_ro(c); 1792 ubifs_remount_ro(c);
@@ -1793,6 +1801,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
1793 } 1801 }
1794 1802
1795 ubifs_assert(c->lst.taken_empty_lebs > 0); 1803 ubifs_assert(c->lst.taken_empty_lebs > 0);
1804 unlock_kernel();
1796 return 0; 1805 return 0;
1797} 1806}
1798 1807
diff --git a/fs/udf/Makefile b/fs/udf/Makefile
index 0d4503f7446d..eb880f66c23a 100644
--- a/fs/udf/Makefile
+++ b/fs/udf/Makefile
@@ -5,5 +5,5 @@
5obj-$(CONFIG_UDF_FS) += udf.o 5obj-$(CONFIG_UDF_FS) += udf.o
6 6
7udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \ 7udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \
8 partition.o super.o truncate.o symlink.o fsync.o \ 8 partition.o super.o truncate.o symlink.o \
9 directory.o misc.o udftime.o unicode.o 9 directory.o misc.o udftime.o unicode.o
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 2efd4d5291b6..61d9a76a3a69 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -210,5 +210,5 @@ const struct file_operations udf_dir_operations = {
210 .read = generic_read_dir, 210 .read = generic_read_dir,
211 .readdir = udf_readdir, 211 .readdir = udf_readdir,
212 .ioctl = udf_ioctl, 212 .ioctl = udf_ioctl,
213 .fsync = udf_fsync_file, 213 .fsync = simple_fsync,
214}; 214};
diff --git a/fs/udf/file.c b/fs/udf/file.c
index eb91f3b70320..7464305382b5 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -209,7 +209,7 @@ const struct file_operations udf_file_operations = {
209 .write = do_sync_write, 209 .write = do_sync_write,
210 .aio_write = udf_file_aio_write, 210 .aio_write = udf_file_aio_write,
211 .release = udf_release_file, 211 .release = udf_release_file,
212 .fsync = udf_fsync_file, 212 .fsync = simple_fsync,
213 .splice_read = generic_file_splice_read, 213 .splice_read = generic_file_splice_read,
214 .llseek = generic_file_llseek, 214 .llseek = generic_file_llseek,
215}; 215};
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c
deleted file mode 100644
index b2c472b733b8..000000000000
--- a/fs/udf/fsync.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * fsync.c
3 *
4 * PURPOSE
5 * Fsync handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * COPYRIGHT
8 * This file is distributed under the terms of the GNU General Public
9 * License (GPL). Copies of the GPL can be obtained from:
10 * ftp://prep.ai.mit.edu/pub/gnu/GPL
11 * Each contributing author retains all rights to their own work.
12 *
13 * (C) 1999-2001 Ben Fennema
14 * (C) 1999-2000 Stelias Computing Inc
15 *
16 * HISTORY
17 *
18 * 05/22/99 blf Created.
19 */
20
21#include "udfdecl.h"
22
23#include <linux/fs.h>
24
25static int udf_fsync_inode(struct inode *, int);
26
27/*
28 * File may be NULL when we are called. Perhaps we shouldn't
29 * even pass file to fsync ?
30 */
31
32int udf_fsync_file(struct file *file, struct dentry *dentry, int datasync)
33{
34 struct inode *inode = dentry->d_inode;
35
36 return udf_fsync_inode(inode, datasync);
37}
38
39static int udf_fsync_inode(struct inode *inode, int datasync)
40{
41 int err;
42
43 err = sync_mapping_buffers(inode->i_mapping);
44 if (!(inode->i_state & I_DIRTY))
45 return err;
46 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
47 return err;
48
49 err |= udf_sync_inode(inode);
50
51 return err ? -EIO : 0;
52}
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 0ba44107d8f1..6832135159b6 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -568,6 +568,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
568 if (!udf_parse_options(options, &uopt, true)) 568 if (!udf_parse_options(options, &uopt, true))
569 return -EINVAL; 569 return -EINVAL;
570 570
571 lock_kernel();
571 sbi->s_flags = uopt.flags; 572 sbi->s_flags = uopt.flags;
572 sbi->s_uid = uopt.uid; 573 sbi->s_uid = uopt.uid;
573 sbi->s_gid = uopt.gid; 574 sbi->s_gid = uopt.gid;
@@ -581,13 +582,16 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
581 *flags |= MS_RDONLY; 582 *flags |= MS_RDONLY;
582 } 583 }
583 584
584 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 585 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
586 unlock_kernel();
585 return 0; 587 return 0;
588 }
586 if (*flags & MS_RDONLY) 589 if (*flags & MS_RDONLY)
587 udf_close_lvid(sb); 590 udf_close_lvid(sb);
588 else 591 else
589 udf_open_lvid(sb); 592 udf_open_lvid(sb);
590 593
594 unlock_kernel();
591 return 0; 595 return 0;
592} 596}
593 597
@@ -2062,6 +2066,9 @@ static void udf_put_super(struct super_block *sb)
2062 struct udf_sb_info *sbi; 2066 struct udf_sb_info *sbi;
2063 2067
2064 sbi = UDF_SB(sb); 2068 sbi = UDF_SB(sb);
2069
2070 lock_kernel();
2071
2065 if (sbi->s_vat_inode) 2072 if (sbi->s_vat_inode)
2066 iput(sbi->s_vat_inode); 2073 iput(sbi->s_vat_inode);
2067 if (sbi->s_partitions) 2074 if (sbi->s_partitions)
@@ -2077,6 +2084,8 @@ static void udf_put_super(struct super_block *sb)
2077 kfree(sbi->s_partmaps); 2084 kfree(sbi->s_partmaps);
2078 kfree(sb->s_fs_info); 2085 kfree(sb->s_fs_info);
2079 sb->s_fs_info = NULL; 2086 sb->s_fs_info = NULL;
2087
2088 unlock_kernel();
2080} 2089}
2081 2090
2082static int udf_sync_fs(struct super_block *sb, int wait) 2091static int udf_sync_fs(struct super_block *sb, int wait)
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index cac51b77a5d1..8d46f4294ee7 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -223,9 +223,6 @@ extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t,
223extern int udf_new_block(struct super_block *, struct inode *, uint16_t, 223extern int udf_new_block(struct super_block *, struct inode *, uint16_t,
224 uint32_t, int *); 224 uint32_t, int *);
225 225
226/* fsync.c */
227extern int udf_fsync_file(struct file *, struct dentry *, int);
228
229/* directory.c */ 226/* directory.c */
230extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *, 227extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *,
231 struct udf_fileident_bh *, 228 struct udf_fileident_bh *,
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 6321b797061b..6f671f1ac271 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -666,6 +666,6 @@ not_empty:
666const struct file_operations ufs_dir_operations = { 666const struct file_operations ufs_dir_operations = {
667 .read = generic_read_dir, 667 .read = generic_read_dir,
668 .readdir = ufs_readdir, 668 .readdir = ufs_readdir,
669 .fsync = ufs_sync_file, 669 .fsync = simple_fsync,
670 .llseek = generic_file_llseek, 670 .llseek = generic_file_llseek,
671}; 671};
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 2bd3a1615714..73655c61240a 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -24,31 +24,10 @@
24 */ 24 */
25 25
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
28 27
29#include "ufs_fs.h" 28#include "ufs_fs.h"
30#include "ufs.h" 29#include "ufs.h"
31 30
32
33int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
34{
35 struct inode *inode = dentry->d_inode;
36 int err;
37 int ret;
38
39 ret = sync_mapping_buffers(inode->i_mapping);
40 if (!(inode->i_state & I_DIRTY))
41 return ret;
42 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
43 return ret;
44
45 err = ufs_sync_inode(inode);
46 if (ret == 0)
47 ret = err;
48 return ret;
49}
50
51
52/* 31/*
53 * We have mostly NULL's here: the current defaults are ok for 32 * We have mostly NULL's here: the current defaults are ok for
54 * the ufs filesystem. 33 * the ufs filesystem.
@@ -62,6 +41,6 @@ const struct file_operations ufs_file_operations = {
62 .aio_write = generic_file_aio_write, 41 .aio_write = generic_file_aio_write,
63 .mmap = generic_file_mmap, 42 .mmap = generic_file_mmap,
64 .open = generic_file_open, 43 .open = generic_file_open,
65 .fsync = ufs_sync_file, 44 .fsync = simple_fsync,
66 .splice_read = generic_file_splice_read, 45 .splice_read = generic_file_splice_read,
67}; 46};
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 60359291761f..5faed7954d0a 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -263,6 +263,7 @@ void ufs_panic (struct super_block * sb, const char * function,
263 struct ufs_super_block_first * usb1; 263 struct ufs_super_block_first * usb1;
264 va_list args; 264 va_list args;
265 265
266 lock_kernel();
266 uspi = UFS_SB(sb)->s_uspi; 267 uspi = UFS_SB(sb)->s_uspi;
267 usb1 = ubh_get_usb_first(uspi); 268 usb1 = ubh_get_usb_first(uspi);
268 269
@@ -594,6 +595,9 @@ static void ufs_put_super_internal(struct super_block *sb)
594 595
595 596
596 UFSD("ENTER\n"); 597 UFSD("ENTER\n");
598
599 lock_kernel();
600
597 ufs_put_cstotal(sb); 601 ufs_put_cstotal(sb);
598 size = uspi->s_cssize; 602 size = uspi->s_cssize;
599 blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; 603 blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -621,6 +625,9 @@ static void ufs_put_super_internal(struct super_block *sb)
621 brelse (sbi->s_ucg[i]); 625 brelse (sbi->s_ucg[i]);
622 kfree (sbi->s_ucg); 626 kfree (sbi->s_ucg);
623 kfree (base); 627 kfree (base);
628
629 unlock_kernel();
630
624 UFSD("EXIT\n"); 631 UFSD("EXIT\n");
625} 632}
626 633
@@ -1118,32 +1125,45 @@ failed_nomem:
1118 return -ENOMEM; 1125 return -ENOMEM;
1119} 1126}
1120 1127
1121static void ufs_write_super(struct super_block *sb) 1128static int ufs_sync_fs(struct super_block *sb, int wait)
1122{ 1129{
1123 struct ufs_sb_private_info * uspi; 1130 struct ufs_sb_private_info * uspi;
1124 struct ufs_super_block_first * usb1; 1131 struct ufs_super_block_first * usb1;
1125 struct ufs_super_block_third * usb3; 1132 struct ufs_super_block_third * usb3;
1126 unsigned flags; 1133 unsigned flags;
1127 1134
1135 lock_super(sb);
1128 lock_kernel(); 1136 lock_kernel();
1137
1129 UFSD("ENTER\n"); 1138 UFSD("ENTER\n");
1139
1130 flags = UFS_SB(sb)->s_flags; 1140 flags = UFS_SB(sb)->s_flags;
1131 uspi = UFS_SB(sb)->s_uspi; 1141 uspi = UFS_SB(sb)->s_uspi;
1132 usb1 = ubh_get_usb_first(uspi); 1142 usb1 = ubh_get_usb_first(uspi);
1133 usb3 = ubh_get_usb_third(uspi); 1143 usb3 = ubh_get_usb_third(uspi);
1134 1144
1135 if (!(sb->s_flags & MS_RDONLY)) { 1145 usb1->fs_time = cpu_to_fs32(sb, get_seconds());
1136 usb1->fs_time = cpu_to_fs32(sb, get_seconds()); 1146 if ((flags & UFS_ST_MASK) == UFS_ST_SUN ||
1137 if ((flags & UFS_ST_MASK) == UFS_ST_SUN 1147 (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
1138 || (flags & UFS_ST_MASK) == UFS_ST_SUNOS 1148 (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
1139 || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 1149 ufs_set_fs_state(sb, usb1, usb3,
1140 ufs_set_fs_state(sb, usb1, usb3, 1150 UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
1141 UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); 1151 ufs_put_cstotal(sb);
1142 ufs_put_cstotal(sb);
1143 }
1144 sb->s_dirt = 0; 1152 sb->s_dirt = 0;
1153
1145 UFSD("EXIT\n"); 1154 UFSD("EXIT\n");
1146 unlock_kernel(); 1155 unlock_kernel();
1156 unlock_super(sb);
1157
1158 return 0;
1159}
1160
1161static void ufs_write_super(struct super_block *sb)
1162{
1163 if (!(sb->s_flags & MS_RDONLY))
1164 ufs_sync_fs(sb, 1);
1165 else
1166 sb->s_dirt = 0;
1147} 1167}
1148 1168
1149static void ufs_put_super(struct super_block *sb) 1169static void ufs_put_super(struct super_block *sb)
@@ -1152,6 +1172,9 @@ static void ufs_put_super(struct super_block *sb)
1152 1172
1153 UFSD("ENTER\n"); 1173 UFSD("ENTER\n");
1154 1174
1175 if (sb->s_dirt)
1176 ufs_write_super(sb);
1177
1155 if (!(sb->s_flags & MS_RDONLY)) 1178 if (!(sb->s_flags & MS_RDONLY))
1156 ufs_put_super_internal(sb); 1179 ufs_put_super_internal(sb);
1157 1180
@@ -1171,7 +1194,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1171 struct ufs_super_block_third * usb3; 1194 struct ufs_super_block_third * usb3;
1172 unsigned new_mount_opt, ufstype; 1195 unsigned new_mount_opt, ufstype;
1173 unsigned flags; 1196 unsigned flags;
1174 1197
1198 lock_kernel();
1199 lock_super(sb);
1175 uspi = UFS_SB(sb)->s_uspi; 1200 uspi = UFS_SB(sb)->s_uspi;
1176 flags = UFS_SB(sb)->s_flags; 1201 flags = UFS_SB(sb)->s_flags;
1177 usb1 = ubh_get_usb_first(uspi); 1202 usb1 = ubh_get_usb_first(uspi);
@@ -1184,17 +1209,24 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1184 ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE; 1209 ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
1185 new_mount_opt = 0; 1210 new_mount_opt = 0;
1186 ufs_set_opt (new_mount_opt, ONERROR_LOCK); 1211 ufs_set_opt (new_mount_opt, ONERROR_LOCK);
1187 if (!ufs_parse_options (data, &new_mount_opt)) 1212 if (!ufs_parse_options (data, &new_mount_opt)) {
1213 unlock_super(sb);
1214 unlock_kernel();
1188 return -EINVAL; 1215 return -EINVAL;
1216 }
1189 if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { 1217 if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
1190 new_mount_opt |= ufstype; 1218 new_mount_opt |= ufstype;
1191 } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { 1219 } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
1192 printk("ufstype can't be changed during remount\n"); 1220 printk("ufstype can't be changed during remount\n");
1221 unlock_super(sb);
1222 unlock_kernel();
1193 return -EINVAL; 1223 return -EINVAL;
1194 } 1224 }
1195 1225
1196 if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { 1226 if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
1197 UFS_SB(sb)->s_mount_opt = new_mount_opt; 1227 UFS_SB(sb)->s_mount_opt = new_mount_opt;
1228 unlock_super(sb);
1229 unlock_kernel();
1198 return 0; 1230 return 0;
1199 } 1231 }
1200 1232
@@ -1219,6 +1251,8 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1219#ifndef CONFIG_UFS_FS_WRITE 1251#ifndef CONFIG_UFS_FS_WRITE
1220 printk("ufs was compiled with read-only support, " 1252 printk("ufs was compiled with read-only support, "
1221 "can't be mounted as read-write\n"); 1253 "can't be mounted as read-write\n");
1254 unlock_super(sb);
1255 unlock_kernel();
1222 return -EINVAL; 1256 return -EINVAL;
1223#else 1257#else
1224 if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 1258 if (ufstype != UFS_MOUNT_UFSTYPE_SUN &&
@@ -1227,16 +1261,22 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1227 ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && 1261 ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
1228 ufstype != UFS_MOUNT_UFSTYPE_UFS2) { 1262 ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
1229 printk("this ufstype is read-only supported\n"); 1263 printk("this ufstype is read-only supported\n");
1264 unlock_super(sb);
1265 unlock_kernel();
1230 return -EINVAL; 1266 return -EINVAL;
1231 } 1267 }
1232 if (!ufs_read_cylinder_structures(sb)) { 1268 if (!ufs_read_cylinder_structures(sb)) {
1233 printk("failed during remounting\n"); 1269 printk("failed during remounting\n");
1270 unlock_super(sb);
1271 unlock_kernel();
1234 return -EPERM; 1272 return -EPERM;
1235 } 1273 }
1236 sb->s_flags &= ~MS_RDONLY; 1274 sb->s_flags &= ~MS_RDONLY;
1237#endif 1275#endif
1238 } 1276 }
1239 UFS_SB(sb)->s_mount_opt = new_mount_opt; 1277 UFS_SB(sb)->s_mount_opt = new_mount_opt;
1278 unlock_super(sb);
1279 unlock_kernel();
1240 return 0; 1280 return 0;
1241} 1281}
1242 1282
@@ -1352,6 +1392,7 @@ static const struct super_operations ufs_super_ops = {
1352 .delete_inode = ufs_delete_inode, 1392 .delete_inode = ufs_delete_inode,
1353 .put_super = ufs_put_super, 1393 .put_super = ufs_put_super,
1354 .write_super = ufs_write_super, 1394 .write_super = ufs_write_super,
1395 .sync_fs = ufs_sync_fs,
1355 .statfs = ufs_statfs, 1396 .statfs = ufs_statfs,
1356 .remount_fs = ufs_remount, 1397 .remount_fs = ufs_remount,
1357 .show_options = ufs_show_options, 1398 .show_options = ufs_show_options,
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index d0c4acd4f1f3..644e77e13599 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -99,7 +99,6 @@ extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
99extern const struct inode_operations ufs_file_inode_operations; 99extern const struct inode_operations ufs_file_inode_operations;
100extern const struct file_operations ufs_file_operations; 100extern const struct file_operations ufs_file_operations;
101extern const struct address_space_operations ufs_aops; 101extern const struct address_space_operations ufs_aops;
102extern int ufs_sync_file(struct file *, struct dentry *, int);
103 102
104/* ialloc.c */ 103/* ialloc.c */
105extern void ufs_free_inode (struct inode *inode); 104extern void ufs_free_inode (struct inode *inode);
diff --git a/fs/xattr.c b/fs/xattr.c
index d51b8f9db921..1c3d0af59ddf 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -297,7 +297,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
297 return error; 297 return error;
298 dentry = f->f_path.dentry; 298 dentry = f->f_path.dentry;
299 audit_inode(NULL, dentry); 299 audit_inode(NULL, dentry);
300 error = mnt_want_write(f->f_path.mnt); 300 error = mnt_want_write_file(f);
301 if (!error) { 301 if (!error) {
302 error = setxattr(dentry, name, value, size, flags); 302 error = setxattr(dentry, name, value, size, flags);
303 mnt_drop_write(f->f_path.mnt); 303 mnt_drop_write(f->f_path.mnt);
@@ -524,7 +524,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
524 return error; 524 return error;
525 dentry = f->f_path.dentry; 525 dentry = f->f_path.dentry;
526 audit_inode(NULL, dentry); 526 audit_inode(NULL, dentry);
527 error = mnt_want_write(f->f_path.mnt); 527 error = mnt_want_write_file(f);
528 if (!error) { 528 if (!error) {
529 error = removexattr(dentry, name); 529 error = removexattr(dentry, name);
530 mnt_drop_write(f->f_path.mnt); 530 mnt_drop_write(f->f_path.mnt);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index bb685269f832..08d6bd9a3947 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1104,15 +1104,6 @@ xfs_fs_put_super(
1104 kfree(mp); 1104 kfree(mp);
1105} 1105}
1106 1106
1107STATIC void
1108xfs_fs_write_super(
1109 struct super_block *sb)
1110{
1111 if (!(sb->s_flags & MS_RDONLY))
1112 xfs_sync_fsdata(XFS_M(sb), 0);
1113 sb->s_dirt = 0;
1114}
1115
1116STATIC int 1107STATIC int
1117xfs_fs_sync_super( 1108xfs_fs_sync_super(
1118 struct super_block *sb, 1109 struct super_block *sb,
@@ -1137,7 +1128,6 @@ xfs_fs_sync_super(
1137 error = xfs_quiesce_data(mp); 1128 error = xfs_quiesce_data(mp);
1138 else 1129 else
1139 error = xfs_sync_fsdata(mp, 0); 1130 error = xfs_sync_fsdata(mp, 0);
1140 sb->s_dirt = 0;
1141 1131
1142 if (unlikely(laptop_mode)) { 1132 if (unlikely(laptop_mode)) {
1143 int prev_sync_seq = mp->m_sync_seq; 1133 int prev_sync_seq = mp->m_sync_seq;
@@ -1443,7 +1433,6 @@ xfs_fs_fill_super(
1443 1433
1444 XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname); 1434 XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname);
1445 1435
1446 sb->s_dirt = 1;
1447 sb->s_magic = XFS_SB_MAGIC; 1436 sb->s_magic = XFS_SB_MAGIC;
1448 sb->s_blocksize = mp->m_sb.sb_blocksize; 1437 sb->s_blocksize = mp->m_sb.sb_blocksize;
1449 sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; 1438 sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
@@ -1533,7 +1522,6 @@ static struct super_operations xfs_super_operations = {
1533 .write_inode = xfs_fs_write_inode, 1522 .write_inode = xfs_fs_write_inode,
1534 .clear_inode = xfs_fs_clear_inode, 1523 .clear_inode = xfs_fs_clear_inode,
1535 .put_super = xfs_fs_put_super, 1524 .put_super = xfs_fs_put_super,
1536 .write_super = xfs_fs_write_super,
1537 .sync_fs = xfs_fs_sync_super, 1525 .sync_fs = xfs_fs_sync_super,
1538 .freeze_fs = xfs_fs_freeze, 1526 .freeze_fs = xfs_fs_freeze,
1539 .statfs = xfs_fs_statfs, 1527 .statfs = xfs_fs_statfs,
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 8570b826fedd..bcc39d358ad3 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -628,8 +628,6 @@ xfs_trans_apply_sb_deltas(
628 xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount), 628 xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount),
629 offsetof(xfs_dsb_t, sb_frextents) + 629 offsetof(xfs_dsb_t, sb_frextents) +
630 sizeof(sbp->sb_frextents) - 1); 630 sizeof(sbp->sb_frextents) - 1);
631
632 tp->t_mountp->m_super->s_dirt = 1;
633} 631}
634 632
635/* 633/*
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 3f0eaa397ef5..b3afd2219ad2 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -135,6 +135,7 @@ header-y += posix_types.h
135header-y += ppdev.h 135header-y += ppdev.h
136header-y += prctl.h 136header-y += prctl.h
137header-y += qnxtypes.h 137header-y += qnxtypes.h
138header-y += qnx4_fs.h
138header-y += radeonfb.h 139header-y += radeonfb.h
139header-y += raw.h 140header-y += raw.h
140header-y += resource.h 141header-y += resource.h
@@ -308,7 +309,6 @@ unifdef-y += poll.h
308unifdef-y += ppp_defs.h 309unifdef-y += ppp_defs.h
309unifdef-y += ppp-comp.h 310unifdef-y += ppp-comp.h
310unifdef-y += ptrace.h 311unifdef-y += ptrace.h
311unifdef-y += qnx4_fs.h
312unifdef-y += quota.h 312unifdef-y += quota.h
313unifdef-y += random.h 313unifdef-y += random.h
314unifdef-y += irqnr.h 314unifdef-y += irqnr.h
diff --git a/include/linux/cdev.h b/include/linux/cdev.h
index fb4591977b03..f389e319a454 100644
--- a/include/linux/cdev.h
+++ b/include/linux/cdev.h
@@ -28,6 +28,8 @@ int cdev_add(struct cdev *, dev_t, unsigned);
28 28
29void cdev_del(struct cdev *); 29void cdev_del(struct cdev *);
30 30
31int cdev_index(struct inode *inode);
32
31void cd_forget(struct inode *); 33void cd_forget(struct inode *);
32 34
33extern struct backing_dev_info directly_mappable_cdev_bdi; 35extern struct backing_dev_info directly_mappable_cdev_bdi;
diff --git a/include/linux/cramfs_fs.h b/include/linux/cramfs_fs.h
index 3be4e5a27d82..6fc2bed368b8 100644
--- a/include/linux/cramfs_fs.h
+++ b/include/linux/cramfs_fs.h
@@ -2,9 +2,8 @@
2#define __CRAMFS_H 2#define __CRAMFS_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/magic.h>
5 6
6#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
7#define CRAMFS_MAGIC_WEND 0x453dcd28 /* magic number with the wrong endianess */
8#define CRAMFS_SIGNATURE "Compressed ROMFS" 7#define CRAMFS_SIGNATURE "Compressed ROMFS"
9 8
10/* 9/*
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 97978004338d..30b93b2a01a4 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -353,6 +353,11 @@ static inline int d_unhashed(struct dentry *dentry)
353 return (dentry->d_flags & DCACHE_UNHASHED); 353 return (dentry->d_flags & DCACHE_UNHASHED);
354} 354}
355 355
356static inline int d_unlinked(struct dentry *dentry)
357{
358 return d_unhashed(dentry) && !IS_ROOT(dentry);
359}
360
356static inline struct dentry *dget_parent(struct dentry *dentry) 361static inline struct dentry *dget_parent(struct dentry *dentry)
357{ 362{
358 struct dentry *ret; 363 struct dentry *ret;
@@ -370,7 +375,7 @@ static inline int d_mountpoint(struct dentry *dentry)
370 return dentry->d_mounted; 375 return dentry->d_mounted;
371} 376}
372 377
373extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *); 378extern struct vfsmount *lookup_mnt(struct path *);
374extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); 379extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
375 380
376extern int sysctl_vfs_cache_pressure; 381extern int sysctl_vfs_cache_pressure;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 323b5ce474c1..ede84fa7da5d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -729,8 +729,8 @@ struct inode {
729 struct timespec i_atime; 729 struct timespec i_atime;
730 struct timespec i_mtime; 730 struct timespec i_mtime;
731 struct timespec i_ctime; 731 struct timespec i_ctime;
732 unsigned int i_blkbits;
733 blkcnt_t i_blocks; 732 blkcnt_t i_blocks;
733 unsigned int i_blkbits;
734 unsigned short i_bytes; 734 unsigned short i_bytes;
735 umode_t i_mode; 735 umode_t i_mode;
736 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ 736 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
@@ -751,7 +751,6 @@ struct inode {
751 struct block_device *i_bdev; 751 struct block_device *i_bdev;
752 struct cdev *i_cdev; 752 struct cdev *i_cdev;
753 }; 753 };
754 int i_cindex;
755 754
756 __u32 i_generation; 755 __u32 i_generation;
757 756
@@ -1321,7 +1320,7 @@ struct super_block {
1321 struct rw_semaphore s_umount; 1320 struct rw_semaphore s_umount;
1322 struct mutex s_lock; 1321 struct mutex s_lock;
1323 int s_count; 1322 int s_count;
1324 int s_need_sync_fs; 1323 int s_need_sync;
1325 atomic_t s_active; 1324 atomic_t s_active;
1326#ifdef CONFIG_SECURITY 1325#ifdef CONFIG_SECURITY
1327 void *s_security; 1326 void *s_security;
@@ -1372,11 +1371,6 @@ struct super_block {
1372 * generic_show_options() 1371 * generic_show_options()
1373 */ 1372 */
1374 char *s_options; 1373 char *s_options;
1375
1376 /*
1377 * storage for asynchronous operations
1378 */
1379 struct list_head s_async_list;
1380}; 1374};
1381 1375
1382extern struct timespec current_fs_time(struct super_block *sb); 1376extern struct timespec current_fs_time(struct super_block *sb);
@@ -1800,7 +1794,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
1800extern int may_umount_tree(struct vfsmount *); 1794extern int may_umount_tree(struct vfsmount *);
1801extern int may_umount(struct vfsmount *); 1795extern int may_umount(struct vfsmount *);
1802extern long do_mount(char *, char *, char *, unsigned long, void *); 1796extern long do_mount(char *, char *, char *, unsigned long, void *);
1803extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *); 1797extern struct vfsmount *collect_mounts(struct path *);
1804extern void drop_collected_mounts(struct vfsmount *); 1798extern void drop_collected_mounts(struct vfsmount *);
1805 1799
1806extern int vfs_statfs(struct dentry *, struct kstatfs *); 1800extern int vfs_statfs(struct dentry *, struct kstatfs *);
@@ -1947,8 +1941,6 @@ extern struct super_block *freeze_bdev(struct block_device *);
1947extern void emergency_thaw_all(void); 1941extern void emergency_thaw_all(void);
1948extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); 1942extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
1949extern int fsync_bdev(struct block_device *); 1943extern int fsync_bdev(struct block_device *);
1950extern int fsync_super(struct super_block *);
1951extern int fsync_no_super(struct block_device *);
1952#else 1944#else
1953static inline void bd_forget(struct inode *inode) {} 1945static inline void bd_forget(struct inode *inode) {}
1954static inline int sync_blockdev(struct block_device *bdev) { return 0; } 1946static inline int sync_blockdev(struct block_device *bdev) { return 0; }
@@ -1964,6 +1956,7 @@ static inline int thaw_bdev(struct block_device *bdev, struct super_block *sb)
1964 return 0; 1956 return 0;
1965} 1957}
1966#endif 1958#endif
1959extern int sync_filesystem(struct super_block *);
1967extern const struct file_operations def_blk_fops; 1960extern const struct file_operations def_blk_fops;
1968extern const struct file_operations def_chr_fops; 1961extern const struct file_operations def_chr_fops;
1969extern const struct file_operations bad_sock_fops; 1962extern const struct file_operations bad_sock_fops;
@@ -2082,12 +2075,8 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
2082 2075
2083extern int vfs_fsync(struct file *file, struct dentry *dentry, int datasync); 2076extern int vfs_fsync(struct file *file, struct dentry *dentry, int datasync);
2084extern void sync_supers(void); 2077extern void sync_supers(void);
2085extern void sync_filesystems(int wait);
2086extern void __fsync_super(struct super_block *sb);
2087extern void emergency_sync(void); 2078extern void emergency_sync(void);
2088extern void emergency_remount(void); 2079extern void emergency_remount(void);
2089extern int do_remount_sb(struct super_block *sb, int flags,
2090 void *data, int force);
2091#ifdef CONFIG_BLOCK 2080#ifdef CONFIG_BLOCK
2092extern sector_t bmap(struct inode *, sector_t); 2081extern sector_t bmap(struct inode *, sector_t);
2093#endif 2082#endif
@@ -2356,6 +2345,8 @@ extern void simple_release_fs(struct vfsmount **mount, int *count);
2356extern ssize_t simple_read_from_buffer(void __user *to, size_t count, 2345extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
2357 loff_t *ppos, const void *from, size_t available); 2346 loff_t *ppos, const void *from, size_t available);
2358 2347
2348extern int simple_fsync(struct file *, struct dentry *, int);
2349
2359#ifdef CONFIG_MIGRATION 2350#ifdef CONFIG_MIGRATION
2360extern int buffer_migrate_page(struct address_space *, 2351extern int buffer_migrate_page(struct address_space *,
2361 struct page *, struct page *); 2352 struct page *, struct page *);
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 927138cf3050..1923327b9869 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -6,6 +6,8 @@
6#define AFS_SUPER_MAGIC 0x5346414F 6#define AFS_SUPER_MAGIC 0x5346414F
7#define AUTOFS_SUPER_MAGIC 0x0187 7#define AUTOFS_SUPER_MAGIC 0x0187
8#define CODA_SUPER_MAGIC 0x73757245 8#define CODA_SUPER_MAGIC 0x73757245
9#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
10#define CRAMFS_MAGIC_WEND 0x453dcd28 /* magic number with the wrong endianess */
9#define DEBUGFS_MAGIC 0x64626720 11#define DEBUGFS_MAGIC 0x64626720
10#define SYSFS_MAGIC 0x62656572 12#define SYSFS_MAGIC 0x62656572
11#define SECURITYFS_MAGIC 0x73636673 13#define SECURITYFS_MAGIC 0x73636673
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 51f55f903aff..5d5275364867 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -30,7 +30,7 @@ struct mnt_namespace;
30#define MNT_STRICTATIME 0x80 30#define MNT_STRICTATIME 0x80
31 31
32#define MNT_SHRINKABLE 0x100 32#define MNT_SHRINKABLE 0x100
33#define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */ 33#define MNT_WRITE_HOLD 0x200
34 34
35#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */ 35#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
36#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */ 36#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
@@ -65,13 +65,22 @@ struct vfsmount {
65 int mnt_expiry_mark; /* true if marked for expiry */ 65 int mnt_expiry_mark; /* true if marked for expiry */
66 int mnt_pinned; 66 int mnt_pinned;
67 int mnt_ghosts; 67 int mnt_ghosts;
68 /* 68#ifdef CONFIG_SMP
69 * This value is not stable unless all of the mnt_writers[] spinlocks 69 int *mnt_writers;
70 * are held, and all mnt_writer[]s on this mount have 0 as their ->count 70#else
71 */ 71 int mnt_writers;
72 atomic_t __mnt_writers; 72#endif
73}; 73};
74 74
75static inline int *get_mnt_writers_ptr(struct vfsmount *mnt)
76{
77#ifdef CONFIG_SMP
78 return mnt->mnt_writers;
79#else
80 return &mnt->mnt_writers;
81#endif
82}
83
75static inline struct vfsmount *mntget(struct vfsmount *mnt) 84static inline struct vfsmount *mntget(struct vfsmount *mnt)
76{ 85{
77 if (mnt) 86 if (mnt)
@@ -79,7 +88,11 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt)
79 return mnt; 88 return mnt;
80} 89}
81 90
91struct file; /* forward dec */
92
82extern int mnt_want_write(struct vfsmount *mnt); 93extern int mnt_want_write(struct vfsmount *mnt);
94extern int mnt_want_write_file(struct file *file);
95extern int mnt_clone_write(struct vfsmount *mnt);
83extern void mnt_drop_write(struct vfsmount *mnt); 96extern void mnt_drop_write(struct vfsmount *mnt);
84extern void mntput_no_expire(struct vfsmount *mnt); 97extern void mntput_no_expire(struct vfsmount *mnt);
85extern void mnt_pin(struct vfsmount *mnt); 98extern void mnt_pin(struct vfsmount *mnt);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 518098fe63af..d870ae2faedc 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -18,6 +18,7 @@ enum { MAX_NESTED_LINKS = 8 };
18struct nameidata { 18struct nameidata {
19 struct path path; 19 struct path path;
20 struct qstr last; 20 struct qstr last;
21 struct path root;
21 unsigned int flags; 22 unsigned int flags;
22 int last_type; 23 int last_type;
23 unsigned depth; 24 unsigned depth;
@@ -77,8 +78,8 @@ extern void release_open_intent(struct nameidata *);
77extern struct dentry *lookup_one_len(const char *, struct dentry *, int); 78extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
78extern struct dentry *lookup_one_noperm(const char *, struct dentry *); 79extern struct dentry *lookup_one_noperm(const char *, struct dentry *);
79 80
80extern int follow_down(struct vfsmount **, struct dentry **); 81extern int follow_down(struct path *);
81extern int follow_up(struct vfsmount **, struct dentry **); 82extern int follow_up(struct path *);
82 83
83extern struct dentry *lock_rename(struct dentry *, struct dentry *); 84extern struct dentry *lock_rename(struct dentry *, struct dentry *);
84extern void unlock_rename(struct dentry *, struct dentry *); 85extern void unlock_rename(struct dentry *, struct dentry *);
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index bcd0201589f8..a6d9ef2bb34a 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -125,11 +125,9 @@ void nfsd_export_flush(void);
125void exp_readlock(void); 125void exp_readlock(void);
126void exp_readunlock(void); 126void exp_readunlock(void);
127struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, 127struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
128 struct vfsmount *, 128 struct path *);
129 struct dentry *);
130struct svc_export * rqst_exp_parent(struct svc_rqst *, 129struct svc_export * rqst_exp_parent(struct svc_rqst *,
131 struct vfsmount *mnt, 130 struct path *);
132 struct dentry *dentry);
133int exp_rootfh(struct auth_domain *, 131int exp_rootfh(struct auth_domain *,
134 char *path, struct knfsd_fh *, int maxsize); 132 char *path, struct knfsd_fh *, int maxsize);
135__be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); 133__be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *);
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index fbfa3d44d33d..e6e77d31c418 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -93,20 +93,9 @@ struct vmcore {
93 93
94#ifdef CONFIG_PROC_FS 94#ifdef CONFIG_PROC_FS
95 95
96extern spinlock_t proc_subdir_lock;
97
98extern void proc_root_init(void); 96extern void proc_root_init(void);
99 97
100void proc_flush_task(struct task_struct *task); 98void proc_flush_task(struct task_struct *task);
101struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *);
102int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
103unsigned long task_vsize(struct mm_struct *);
104int task_statm(struct mm_struct *, int *, int *, int *, int *);
105void task_mem(struct seq_file *, struct mm_struct *);
106void clear_refs_smap(struct mm_struct *mm);
107
108struct proc_dir_entry *de_get(struct proc_dir_entry *de);
109void de_put(struct proc_dir_entry *de);
110 99
111extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, 100extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
112 struct proc_dir_entry *parent); 101 struct proc_dir_entry *parent);
@@ -116,20 +105,7 @@ struct proc_dir_entry *proc_create_data(const char *name, mode_t mode,
116 void *data); 105 void *data);
117extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); 106extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
118 107
119extern struct vfsmount *proc_mnt;
120struct pid_namespace; 108struct pid_namespace;
121extern int proc_fill_super(struct super_block *);
122extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
123
124/*
125 * These are generic /proc routines that use the internal
126 * "struct proc_dir_entry" tree to traverse the filesystem.
127 *
128 * The /proc root directory has extended versions to take care
129 * of the /proc/<pid> subdirectories.
130 */
131extern int proc_readdir(struct file *, void *, filldir_t);
132extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
133 109
134extern int pid_ns_prepare_proc(struct pid_namespace *ns); 110extern int pid_ns_prepare_proc(struct pid_namespace *ns);
135extern void pid_ns_release_proc(struct pid_namespace *ns); 111extern void pid_ns_release_proc(struct pid_namespace *ns);
diff --git a/include/linux/qnx4_fs.h b/include/linux/qnx4_fs.h
index 787d19ea9f46..8b9aee1a9ce3 100644
--- a/include/linux/qnx4_fs.h
+++ b/include/linux/qnx4_fs.h
@@ -85,65 +85,4 @@ struct qnx4_super_block {
85 struct qnx4_inode_entry AltBoot; 85 struct qnx4_inode_entry AltBoot;
86}; 86};
87 87
88#ifdef __KERNEL__
89
90#define QNX4_DEBUG 0
91
92#if QNX4_DEBUG
93#define QNX4DEBUG(X) printk X
94#else
95#define QNX4DEBUG(X) (void) 0
96#endif
97
98struct qnx4_sb_info {
99 struct buffer_head *sb_buf; /* superblock buffer */
100 struct qnx4_super_block *sb; /* our superblock */
101 unsigned int Version; /* may be useful */
102 struct qnx4_inode_entry *BitMap; /* useful */
103};
104
105struct qnx4_inode_info {
106 struct qnx4_inode_entry raw;
107 loff_t mmu_private;
108 struct inode vfs_inode;
109};
110
111extern struct inode *qnx4_iget(struct super_block *, unsigned long);
112extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd);
113extern unsigned long qnx4_count_free_blocks(struct super_block *sb);
114extern unsigned long qnx4_block_map(struct inode *inode, long iblock);
115
116extern struct buffer_head *qnx4_bread(struct inode *, int, int);
117
118extern const struct inode_operations qnx4_file_inode_operations;
119extern const struct inode_operations qnx4_dir_inode_operations;
120extern const struct file_operations qnx4_file_operations;
121extern const struct file_operations qnx4_dir_operations;
122extern int qnx4_is_free(struct super_block *sb, long block);
123extern int qnx4_set_bitmap(struct super_block *sb, long block, int busy);
124extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode, struct nameidata *nd);
125extern void qnx4_truncate(struct inode *inode);
126extern void qnx4_free_inode(struct inode *inode);
127extern int qnx4_unlink(struct inode *dir, struct dentry *dentry);
128extern int qnx4_rmdir(struct inode *dir, struct dentry *dentry);
129extern int qnx4_sync_file(struct file *file, struct dentry *dentry, int);
130extern int qnx4_sync_inode(struct inode *inode);
131
132static inline struct qnx4_sb_info *qnx4_sb(struct super_block *sb)
133{
134 return sb->s_fs_info;
135}
136
137static inline struct qnx4_inode_info *qnx4_i(struct inode *inode)
138{
139 return container_of(inode, struct qnx4_inode_info, vfs_inode);
140}
141
142static inline struct qnx4_inode_entry *qnx4_raw_inode(struct inode *inode)
143{
144 return &qnx4_i(inode)->raw;
145}
146
147#endif /* __KERNEL__ */
148
149#endif 88#endif
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 36353d95c8db..7bc457593684 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -20,7 +20,12 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
20/* 20/*
21 * declaration of quota_function calls in kernel. 21 * declaration of quota_function calls in kernel.
22 */ 22 */
23void sync_dquots(struct super_block *sb, int type); 23void sync_quota_sb(struct super_block *sb, int type);
24static inline void writeout_quota_sb(struct super_block *sb, int type)
25{
26 if (sb->s_qcop->quota_sync)
27 sb->s_qcop->quota_sync(sb, type);
28}
24 29
25int dquot_initialize(struct inode *inode, int type); 30int dquot_initialize(struct inode *inode, int type);
26int dquot_drop(struct inode *inode); 31int dquot_drop(struct inode *inode);
@@ -253,12 +258,7 @@ static inline void vfs_dq_free_inode(struct inode *inode)
253 inode->i_sb->dq_op->free_inode(inode, 1); 258 inode->i_sb->dq_op->free_inode(inode, 1);
254} 259}
255 260
256/* The following two functions cannot be called inside a transaction */ 261/* Cannot be called inside a transaction */
257static inline void vfs_dq_sync(struct super_block *sb)
258{
259 sync_dquots(sb, -1);
260}
261
262static inline int vfs_dq_off(struct super_block *sb, int remount) 262static inline int vfs_dq_off(struct super_block *sb, int remount)
263{ 263{
264 int ret = -ENOSYS; 264 int ret = -ENOSYS;
@@ -334,7 +334,11 @@ static inline void vfs_dq_free_inode(struct inode *inode)
334{ 334{
335} 335}
336 336
337static inline void vfs_dq_sync(struct super_block *sb) 337static inline void sync_quota_sb(struct super_block *sb, int type)
338{
339}
340
341static inline void writeout_quota_sb(struct super_block *sb, int type)
338{ 342{
339} 343}
340 344
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 6473650c28f1..dab68bbed675 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -453,6 +453,7 @@ enum reiserfs_mount_options {
453 REISERFS_ATTRS, 453 REISERFS_ATTRS,
454 REISERFS_XATTRS_USER, 454 REISERFS_XATTRS_USER,
455 REISERFS_POSIXACL, 455 REISERFS_POSIXACL,
456 REISERFS_EXPOSE_PRIVROOT,
456 REISERFS_BARRIER_NONE, 457 REISERFS_BARRIER_NONE,
457 REISERFS_BARRIER_FLUSH, 458 REISERFS_BARRIER_FLUSH,
458 459
@@ -490,6 +491,7 @@ enum reiserfs_mount_options {
490#define reiserfs_data_writeback(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_WRITEBACK)) 491#define reiserfs_data_writeback(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_WRITEBACK))
491#define reiserfs_xattrs_user(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS_USER)) 492#define reiserfs_xattrs_user(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS_USER))
492#define reiserfs_posixacl(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_POSIXACL)) 493#define reiserfs_posixacl(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_POSIXACL))
494#define reiserfs_expose_privroot(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_EXPOSE_PRIVROOT))
493#define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s)) 495#define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s))
494#define reiserfs_barrier_none(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_NONE)) 496#define reiserfs_barrier_none(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_NONE))
495#define reiserfs_barrier_flush(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_FLUSH)) 497#define reiserfs_barrier_flush(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_FLUSH))
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 93445477f86a..3224820c8514 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -79,7 +79,6 @@ struct writeback_control {
79void writeback_inodes(struct writeback_control *wbc); 79void writeback_inodes(struct writeback_control *wbc);
80int inode_wait(void *); 80int inode_wait(void *);
81void sync_inodes_sb(struct super_block *, int wait); 81void sync_inodes_sb(struct super_block *, int wait);
82void sync_inodes(int wait);
83 82
84/* writeback.h requires fs.h; it, too, is not included from here. */ 83/* writeback.h requires fs.h; it, too, is not included from here. */
85static inline void wait_on_inode(struct inode *inode) 84static inline void wait_on_inode(struct inode *inode)
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 6e7351739a82..1f6396d76687 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -568,7 +568,7 @@ void audit_trim_trees(void)
568 if (err) 568 if (err)
569 goto skip_it; 569 goto skip_it;
570 570
571 root_mnt = collect_mounts(path.mnt, path.dentry); 571 root_mnt = collect_mounts(&path);
572 path_put(&path); 572 path_put(&path);
573 if (!root_mnt) 573 if (!root_mnt)
574 goto skip_it; 574 goto skip_it;
@@ -660,7 +660,7 @@ int audit_add_tree_rule(struct audit_krule *rule)
660 err = kern_path(tree->pathname, 0, &path); 660 err = kern_path(tree->pathname, 0, &path);
661 if (err) 661 if (err)
662 goto Err; 662 goto Err;
663 mnt = collect_mounts(path.mnt, path.dentry); 663 mnt = collect_mounts(&path);
664 path_put(&path); 664 path_put(&path);
665 if (!mnt) { 665 if (!mnt) {
666 err = -ENOMEM; 666 err = -ENOMEM;
@@ -720,7 +720,7 @@ int audit_tag_tree(char *old, char *new)
720 err = kern_path(new, 0, &path); 720 err = kern_path(new, 0, &path);
721 if (err) 721 if (err)
722 return err; 722 return err;
723 tagged = collect_mounts(path.mnt, path.dentry); 723 tagged = collect_mounts(&path);
724 path_put(&path); 724 path_put(&path);
725 if (!tagged) 725 if (!tagged)
726 return -ENOMEM; 726 return -ENOMEM;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index a7267bfd3765..3fb789f6df94 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -46,6 +46,7 @@
46#include <linux/cgroupstats.h> 46#include <linux/cgroupstats.h>
47#include <linux/hash.h> 47#include <linux/hash.h>
48#include <linux/namei.h> 48#include <linux/namei.h>
49#include <linux/smp_lock.h>
49 50
50#include <asm/atomic.h> 51#include <asm/atomic.h>
51 52
@@ -900,6 +901,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
900 struct cgroup *cgrp = &root->top_cgroup; 901 struct cgroup *cgrp = &root->top_cgroup;
901 struct cgroup_sb_opts opts; 902 struct cgroup_sb_opts opts;
902 903
904 lock_kernel();
903 mutex_lock(&cgrp->dentry->d_inode->i_mutex); 905 mutex_lock(&cgrp->dentry->d_inode->i_mutex);
904 mutex_lock(&cgroup_mutex); 906 mutex_lock(&cgroup_mutex);
905 907
@@ -927,6 +929,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
927 kfree(opts.release_agent); 929 kfree(opts.release_agent);
928 mutex_unlock(&cgroup_mutex); 930 mutex_unlock(&cgroup_mutex);
929 mutex_unlock(&cgrp->dentry->d_inode->i_mutex); 931 mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
932 unlock_kernel();
930 return ret; 933 return ret;
931} 934}
932 935