summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-05-10 10:49:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-05-10 10:49:08 -0700
commit93b49d45eb97574057ee03dfdd590c209f5132f8 (patch)
treed01e5af58331ab6a8c758e445aeb943cf803dfa9 /fs
parentf9f51cc0ce544224a8332a4c1733624fcbc70a32 (diff)
parentb0c4f3222c7406f0aee9d52b7d604a1d36108463 (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: (22 commits) Fix the race between capifs remount and node creation Fix races around the access to ->s_options switch ufs directories to ufs_sync_file() Switch open_exec() and sys_uselib() to do_open_filp() Make open_exec() and sys_uselib() use may_open(), instead of duplicating its parts Reduce path_lookup() abuses Make checkpatch.pl shut up on fs/inode.c NULL noise in fs/super.c:kill_bdev_super() romfs: cleanup romfs_fs.h ROMFS: romfs_dev_read() error ignored fs: dcache fix LRU ordering ocfs2: Use nd_set_link(). Fix deadlock in ipathfs ->get_sb() Fix a leak in failure exit in 9p ->get_sb() Convert obvious places to deactivate_locked_super() New helper: deactivate_locked_super() reiserfs: remove privroot hiding in lookup reiserfs: dont associate security.* with xattr files reiserfs: fixup xattr_root caching Always lookup priv_root on reiserfs mount and keep it ...
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_super.c12
-rw-r--r--fs/affs/super.c3
-rw-r--r--fs/afs/super.c7
-rw-r--r--fs/btrfs/super.c12
-rw-r--r--fs/cifs/cifsfs.c6
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/devpts/inode.c5
-rw-r--r--fs/ecryptfs/main.c5
-rw-r--r--fs/exec.c79
-rw-r--r--fs/fuse/inode.c3
-rw-r--r--fs/gfs2/ops_fstype.c8
-rw-r--r--fs/hpfs/super.c3
-rw-r--r--fs/inode.c81
-rw-r--r--fs/libfs.c3
-rw-r--r--fs/namei.c13
-rw-r--r--fs/namespace.c23
-rw-r--r--fs/nfs/super.c22
-rw-r--r--fs/ocfs2/symlink.c77
-rw-r--r--fs/open.c2
-rw-r--r--fs/proc/root.c3
-rw-r--r--fs/reiserfs/dir.c24
-rw-r--r--fs/reiserfs/namei.c17
-rw-r--r--fs/reiserfs/super.c9
-rw-r--r--fs/reiserfs/xattr.c181
-rw-r--r--fs/reiserfs/xattr_security.c12
-rw-r--r--fs/romfs/super.c3
-rw-r--r--fs/super.c48
-rw-r--r--fs/ubifs/super.c3
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/ufs/file.c2
-rw-r--r--fs/ufs/ufs.h2
31 files changed, 330 insertions, 342 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 5f8ab8adb5f5..ab5547ff29a1 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -37,6 +37,7 @@
#include <linux/mount.h>
#include <linux/idr.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
@@ -155,6 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
root = d_alloc_root(inode);
if (!root) {
+ iput(inode);
retval = -ENOMEM;
goto release_sb;
}
@@ -173,10 +175,7 @@ P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
return 0;
release_sb:
- if (sb) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
- }
+ deactivate_locked_super(sb);
free_stat:
kfree(st);
@@ -230,9 +229,12 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
static void
v9fs_umount_begin(struct super_block *sb)
{
- struct v9fs_session_info *v9ses = sb->s_fs_info;
+ struct v9fs_session_info *v9ses;
+ lock_kernel();
+ v9ses = sb->s_fs_info;
v9fs_session_cancel(v9ses);
+ unlock_kernel();
}
static const struct super_operations v9fs_super_ops = {
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 5ce695e707fe..63f5183f263b 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -507,8 +507,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
kfree(new_opts);
return -EINVAL;
}
- kfree(sb->s_options);
- sb->s_options = new_opts;
+ replace_mount_options(sb, new_opts);
sbi->s_flags = mount_flags;
sbi->s_mode = mode;
diff --git a/fs/afs/super.c b/fs/afs/super.c
index aee239a048cb..76828e5f8a39 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -405,21 +405,20 @@ static int afs_get_sb(struct file_system_type *fs_type,
sb->s_flags = flags;
ret = afs_fill_super(sb, &params);
if (ret < 0) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
goto error;
}
- sb->s_options = new_opts;
+ save_mount_options(sb, new_opts);
sb->s_flags |= MS_ACTIVE;
} else {
_debug("reuse");
- kfree(new_opts);
ASSERTCMP(sb->s_flags, &, MS_ACTIVE);
}
simple_set_mnt(mnt, sb);
afs_put_volume(params.volume);
afs_put_cell(params.cell);
+ kfree(new_opts);
_leave(" = 0 [%p]", sb);
return 0;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3536bdb2d7cb..6dfae5b28f59 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -502,8 +502,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -EBUSY;
goto error_close_devices;
}
@@ -517,8 +516,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
error = btrfs_fill_super(s, fs_devices, data,
flags & MS_SILENT ? 1 : 0);
if (error) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
goto error_free_subvol_name;
}
@@ -535,15 +533,13 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
mutex_unlock(&s->s_root->d_inode->i_mutex);
if (IS_ERR(root)) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = PTR_ERR(root);
goto error_free_subvol_name;
}
if (!root->d_inode) {
dput(root);
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -ENXIO;
goto error_free_subvol_name;
}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 0d6d8b573652..5e6d35804d73 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/smp_lock.h>
#include "cifsfs.h"
#include "cifspdu.h"
#define DECLARE_GLOBALS_HERE
@@ -530,6 +531,7 @@ static void cifs_umount_begin(struct super_block *sb)
if (tcon == NULL)
return;
+ lock_kernel();
read_lock(&cifs_tcp_ses_lock);
if (tcon->tc_count == 1)
tcon->tidStatus = CifsExiting;
@@ -548,6 +550,7 @@ static void cifs_umount_begin(struct super_block *sb)
}
/* BB FIXME - finish add checks for tidStatus BB */
+ unlock_kernel();
return;
}
@@ -599,8 +602,7 @@ cifs_get_sb(struct file_system_type *fs_type,
rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
if (rc) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
return rc;
}
sb->s_flags |= MS_ACTIVE;
diff --git a/fs/dcache.c b/fs/dcache.c
index 1fcffebfb44f..75659a6fd1f8 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -481,7 +481,7 @@ restart:
if ((flags & DCACHE_REFERENCED)
&& (dentry->d_flags & DCACHE_REFERENCED)) {
dentry->d_flags &= ~DCACHE_REFERENCED;
- list_move_tail(&dentry->d_lru, &referenced);
+ list_move(&dentry->d_lru, &referenced);
spin_unlock(&dentry->d_lock);
} else {
list_move_tail(&dentry->d_lru, &tmp);
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 63a4a59e4148..21165cf934ff 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -389,11 +389,10 @@ static int devpts_get_sb(struct file_system_type *fs_type,
return 0;
out_dput:
- dput(s->s_root);
+ dput(s->s_root); /* undo dget() in simple_set_mnt() */
out_undo_sget:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
return error;
}
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index ccabd5faa04d..9f0aa9883c28 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -614,9 +614,8 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
}
goto out;
out_abort:
- dput(sb->s_root);
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */
+ deactivate_locked_super(sb);
out:
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
index 639177b0eeac..895823d0149d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -105,40 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
SYSCALL_DEFINE1(uselib, const char __user *, library)
{
struct file *file;
- struct nameidata nd;
char *tmp = getname(library);
int error = PTR_ERR(tmp);
- if (!IS_ERR(tmp)) {
- error = path_lookup_open(AT_FDCWD, tmp,
- LOOKUP_FOLLOW, &nd,
- FMODE_READ|FMODE_EXEC);
- putname(tmp);
- }
- if (error)
+ if (IS_ERR(tmp))
+ goto out;
+
+ file = do_filp_open(AT_FDCWD, tmp,
+ O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+ MAY_READ | MAY_EXEC | MAY_OPEN);
+ putname(tmp);
+ error = PTR_ERR(file);
+ if (IS_ERR(file))
goto out;
error = -EINVAL;
- if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
+ if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
goto exit;
error = -EACCES;
- if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
- goto exit;
-
- error = inode_permission(nd.path.dentry->d_inode,
- MAY_READ | MAY_EXEC | MAY_OPEN);
- if (error)
- goto exit;
- error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
- if (error)
+ if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
goto exit;
- file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
- error = PTR_ERR(file);
- if (IS_ERR(file))
- goto out;
-
fsnotify_open(file->f_path.dentry);
error = -ENOEXEC;
@@ -160,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
}
read_unlock(&binfmt_lock);
}
+exit:
fput(file);
out:
return error;
-exit:
- release_open_intent(&nd);
- path_put(&nd.path);
- goto out;
}
#ifdef CONFIG_MMU
@@ -661,47 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
struct file *open_exec(const char *name)
{
- struct nameidata nd;
struct file *file;
int err;
- err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
- FMODE_READ|FMODE_EXEC);
- if (err)
+ file = do_filp_open(AT_FDCWD, name,
+ O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+ MAY_EXEC | MAY_OPEN);
+ if (IS_ERR(file))
goto out;
err = -EACCES;
- if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
- goto out_path_put;
-
- if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
- goto out_path_put;
-
- err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
- if (err)
- goto out_path_put;
- err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
- if (err)
- goto out_path_put;
+ if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
+ goto exit;
- file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
- if (IS_ERR(file))
- return file;
+ if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ goto exit;
fsnotify_open(file->f_path.dentry);
err = deny_write_access(file);
- if (err) {
- fput(file);
- goto out;
- }
+ if (err)
+ goto exit;
+out:
return file;
- out_path_put:
- release_open_intent(&nd);
- path_put(&nd.path);
- out:
+exit:
+ fput(file);
return ERR_PTR(err);
}
EXPORT_SYMBOL(open_exec);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 459b73dd45e1..d1bc4d33ccbc 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -19,6 +19,7 @@
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/exportfs.h>
+#include <linux/smp_lock.h>
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -259,7 +260,9 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
static void fuse_umount_begin(struct super_block *sb)
{
+ lock_kernel();
fuse_abort_conn(get_fuse_conn_super(sb));
+ unlock_kernel();
}
static void fuse_send_destroy(struct fuse_conn *fc)
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 650a730707b7..1ff9473ea753 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1282,21 +1282,21 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
static struct super_block *get_gfs2_sb(const char *dev_name)
{
struct super_block *sb;
- struct nameidata nd;
+ struct path path;
int error;
- error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
+ error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
if (error) {
printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
dev_name, error);
return NULL;
}
- sb = nd.path.dentry->d_inode->i_sb;
+ sb = path.dentry->d_inode->i_sb;
if (sb && (sb->s_type == &gfs2_fs_type))
atomic_inc(&sb->s_active);
else
sb = NULL;
- path_put(&nd.path);
+ path_put(&path);
return sb;
}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index fecf402d7b8a..fc77965be841 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -423,8 +423,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
if (!(*flags & MS_RDONLY)) mark_dirty(s);
- kfree(s->s_options);
- s->s_options = new_opts;
+ replace_mount_options(s, new_opts);
return 0;
diff --git a/fs/inode.c b/fs/inode.c
index 6ad14a1cd8c9..0571983755dc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -99,7 +99,7 @@ static DEFINE_MUTEX(iprune_mutex);
*/
struct inodes_stat_t inodes_stat;
-static struct kmem_cache * inode_cachep __read_mostly;
+static struct kmem_cache *inode_cachep __read_mostly;
static void wake_up_inode(struct inode *inode)
{
@@ -124,7 +124,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
static struct inode_operations empty_iops;
static const struct file_operations empty_fops;
- struct address_space * const mapping = &inode->i_data;
+ struct address_space *const mapping = &inode->i_data;
inode->i_sb = sb;
inode->i_blkbits = sb->s_blocksize_bits;
@@ -216,7 +216,7 @@ static struct inode *alloc_inode(struct super_block *sb)
return NULL;
}
-void destroy_inode(struct inode *inode)
+void destroy_inode(struct inode *inode)
{
BUG_ON(inode_has_buffers(inode));
security_inode_free(inode);
@@ -252,12 +252,11 @@ void inode_init_once(struct inode *inode)
mutex_init(&inode->inotify_mutex);
#endif
}
-
EXPORT_SYMBOL(inode_init_once);
static void init_once(void *foo)
{
- struct inode * inode = (struct inode *) foo;
+ struct inode *inode = (struct inode *) foo;
inode_init_once(inode);
}
@@ -265,7 +264,7 @@ static void init_once(void *foo)
/*
* inode_lock must be held
*/
-void __iget(struct inode * inode)
+void __iget(struct inode *inode)
{
if (atomic_read(&inode->i_count)) {
atomic_inc(&inode->i_count);
@@ -289,7 +288,7 @@ void clear_inode(struct inode *inode)
{
might_sleep();
invalidate_inode_buffers(inode);
-
+
BUG_ON(inode->i_data.nrpages);
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
@@ -303,7 +302,6 @@ void clear_inode(struct inode *inode)
cd_forget(inode);
inode->i_state = I_CLEAR;
}
-
EXPORT_SYMBOL(clear_inode);
/*
@@ -351,8 +349,8 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
next = head->next;
for (;;) {
- struct list_head * tmp = next;
- struct inode * inode;
+ struct list_head *tmp = next;
+ struct inode *inode;
/*
* We can reschedule here without worrying about the list's
@@ -391,7 +389,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
* fails because there are busy inodes then a non zero value is returned.
* If the discard is successful all the inodes have been discarded.
*/
-int invalidate_inodes(struct super_block * sb)
+int invalidate_inodes(struct super_block *sb)
{
int busy;
LIST_HEAD(throw_away);
@@ -407,7 +405,6 @@ int invalidate_inodes(struct super_block * sb)
return busy;
}
-
EXPORT_SYMBOL(invalidate_inodes);
static int can_unuse(struct inode *inode)
@@ -504,7 +501,7 @@ static int shrink_icache_memory(int nr, gfp_t gfp_mask)
* Nasty deadlock avoidance. We may hold various FS locks,
* and we don't want to recurse into the FS that called us
* in clear_inode() and friends..
- */
+ */
if (!(gfp_mask & __GFP_FS))
return -1;
prune_icache(nr);
@@ -524,10 +521,13 @@ static void __wait_on_freeing_inode(struct inode *inode);
* by hand after calling find_inode now! This simplifies iunique and won't
* add any additional branch in the common code.
*/
-static struct inode * find_inode(struct super_block * sb, struct hlist_head *head, int (*test)(struct inode *, void *), void *data)
+static struct inode *find_inode(struct super_block *sb,
+ struct hlist_head *head,
+ int (*test)(struct inode *, void *),
+ void *data)
{
struct hlist_node *node;
- struct inode * inode = NULL;
+ struct inode *inode = NULL;
repeat:
hlist_for_each_entry(inode, node, head, i_hash) {
@@ -548,10 +548,11 @@ repeat:
* find_inode_fast is the fast path version of find_inode, see the comment at
* iget_locked for details.
*/
-static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head *head, unsigned long ino)
+static struct inode *find_inode_fast(struct super_block *sb,
+ struct hlist_head *head, unsigned long ino)
{
struct hlist_node *node;
- struct inode * inode = NULL;
+ struct inode *inode = NULL;
repeat:
hlist_for_each_entry(inode, node, head, i_hash) {
@@ -631,10 +632,10 @@ struct inode *new_inode(struct super_block *sb)
* here to attempt to avoid that.
*/
static unsigned int last_ino;
- struct inode * inode;
+ struct inode *inode;
spin_lock_prefetch(&inode_lock);
-
+
inode = alloc_inode(sb);
if (inode) {
spin_lock(&inode_lock);
@@ -645,7 +646,6 @@ struct inode *new_inode(struct super_block *sb)
}
return inode;
}
-
EXPORT_SYMBOL(new_inode);
void unlock_new_inode(struct inode *inode)
@@ -674,7 +674,6 @@ void unlock_new_inode(struct inode *inode)
inode->i_state &= ~(I_LOCK|I_NEW);
wake_up_inode(inode);
}
-
EXPORT_SYMBOL(unlock_new_inode);
/*
@@ -683,13 +682,17 @@ EXPORT_SYMBOL(unlock_new_inode);
* We no longer cache the sb_flags in i_flags - see fs.h
* -- rmk@arm.uk.linux.org
*/
-static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
+static struct inode *get_new_inode(struct super_block *sb,
+ struct hlist_head *head,
+ int (*test)(struct inode *, void *),
+ int (*set)(struct inode *, void *),
+ void *data)
{
- struct inode * inode;
+ struct inode *inode;
inode = alloc_inode(sb);
if (inode) {
- struct inode * old;
+ struct inode *old;
spin_lock(&inode_lock);
/* We released the lock, so.. */
@@ -731,13 +734,14 @@ set_failed:
* get_new_inode_fast is the fast path version of get_new_inode, see the
* comment at iget_locked for details.
*/
-static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_head *head, unsigned long ino)
+static struct inode *get_new_inode_fast(struct super_block *sb,
+ struct hlist_head *head, unsigned long ino)
{
- struct inode * inode;
+ struct inode *inode;
inode = alloc_inode(sb);
if (inode) {
- struct inode * old;
+ struct inode *old;
spin_lock(&inode_lock);
/* We released the lock, so.. */
@@ -823,7 +827,6 @@ struct inode *igrab(struct inode *inode)
spin_unlock(&inode_lock);
return inode;
}
-
EXPORT_SYMBOL(igrab);
/**
@@ -924,7 +927,6 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
return ifind(sb, head, test, data, 0);
}
-
EXPORT_SYMBOL(ilookup5_nowait);
/**
@@ -953,7 +955,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
return ifind(sb, head, test, data, 1);
}
-
EXPORT_SYMBOL(ilookup5);
/**
@@ -976,7 +977,6 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
return ifind_fast(sb, head, ino);
}
-
EXPORT_SYMBOL(ilookup);
/**
@@ -1015,7 +1015,6 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
*/
return get_new_inode(sb, head, test, set, data);
}
-
EXPORT_SYMBOL(iget5_locked);
/**
@@ -1047,7 +1046,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
*/
return get_new_inode_fast(sb, head, ino);
}
-
EXPORT_SYMBOL(iget_locked);
int insert_inode_locked(struct inode *inode)
@@ -1076,7 +1074,6 @@ int insert_inode_locked(struct inode *inode)
iput(old);
}
}
-
EXPORT_SYMBOL(insert_inode_locked);
int insert_inode_locked4(struct inode *inode, unsigned long hashval,
@@ -1106,7 +1103,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
iput(old);
}
}
-
EXPORT_SYMBOL(insert_inode_locked4);
/**
@@ -1124,7 +1120,6 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
hlist_add_head(&inode->i_hash, head);
spin_unlock(&inode_lock);
}
-
EXPORT_SYMBOL(__insert_inode_hash);
/**
@@ -1139,7 +1134,6 @@ void remove_inode_hash(struct inode *inode)
hlist_del_init(&inode->i_hash);
spin_unlock(&inode_lock);
}
-
EXPORT_SYMBOL(remove_inode_hash);
/*
@@ -1187,7 +1181,6 @@ void generic_delete_inode(struct inode *inode)
BUG_ON(inode->i_state != I_CLEAR);
destroy_inode(inode);
}
-
EXPORT_SYMBOL(generic_delete_inode);
static void generic_forget_inode(struct inode *inode)
@@ -1237,12 +1230,11 @@ void generic_drop_inode(struct inode *inode)
else
generic_forget_inode(inode);
}
-
EXPORT_SYMBOL_GPL(generic_drop_inode);
/*
* Called when we're dropping the last reference
- * to an inode.
+ * to an inode.
*
* Call the FS "drop()" function, defaulting to
* the legacy UNIX filesystem behaviour..
@@ -1262,7 +1254,7 @@ static inline void iput_final(struct inode *inode)
}
/**
- * iput - put an inode
+ * iput - put an inode
* @inode: inode to put
*
* Puts an inode, dropping its usage count. If the inode use count hits
@@ -1279,7 +1271,6 @@ void iput(struct inode *inode)
iput_final(inode);
}
}
-
EXPORT_SYMBOL(iput);
/**
@@ -1290,10 +1281,10 @@ EXPORT_SYMBOL(iput);
* Returns the block number on the device holding the inode that
* is the disk block number for the block of the file requested.
* That is, asked for block 4 of inode 1 the function will return the
- * disk block relative to the disk start that holds that block of the
+ * disk block relative to the disk start that holds that block of the
* file.
*/
-sector_t bmap(struct inode * inode, sector_t block)
+sector_t bmap(struct inode *inode, sector_t block)
{
sector_t res = 0;
if (inode->i_mapping->a_ops->bmap)
@@ -1425,7 +1416,6 @@ void file_update_time(struct file *file)
mark_inode_dirty_sync(inode);
mnt_drop_write(file->f_path.mnt);
}
-
EXPORT_SYMBOL(file_update_time);
int inode_needs_sync(struct inode *inode)
@@ -1436,7 +1426,6 @@ int inode_needs_sync(struct inode *inode)
return 1;
return 0;
}
-
EXPORT_SYMBOL(inode_needs_sync);
int inode_wait(void *word)
diff --git a/fs/libfs.c b/fs/libfs.c
index cd223190c4e9..80046ddf5063 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -246,8 +246,7 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
return 0;
Enomem:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
return -ENOMEM;
}
diff --git a/fs/namei.c b/fs/namei.c
index 78f253cd2d4f..967c3db92724 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1130,8 +1130,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
* @nd: pointer to nameidata
* @open_flags: open intent flags
*/
-int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
- struct nameidata *nd, int open_flags)
+static int path_lookup_open(int dfd, const char *name,
+ unsigned int lookup_flags, struct nameidata *nd, int open_flags)
{
struct file *filp = get_empty_filp();
int err;
@@ -1637,18 +1637,19 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
* open_to_namei_flags() for more details.
*/
struct file *do_filp_open(int dfd, const char *pathname,
- int open_flag, int mode)
+ int open_flag, int mode, int acc_mode)
{
struct file *filp;
struct nameidata nd;
- int acc_mode, error;
+ int error;
struct path path;
struct dentry *dir;
int count = 0;
int will_write;
int flag = open_to_namei_flags(open_flag);
- acc_mode = MAY_OPEN | ACC_MODE(flag);
+ if (!acc_mode)
+ acc_mode = MAY_OPEN | ACC_MODE(flag);
/* O_TRUNC implies we need access checks for write permissions */
if (flag & O_TRUNC)
@@ -1869,7 +1870,7 @@ do_link:
*/
struct file *filp_open(const char *filename, int flags, int mode)
{
- return do_filp_open(AT_FDCWD, filename, flags, mode);
+ return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
}
EXPORT_SYMBOL(filp_open);
diff --git a/fs/namespace.c b/fs/namespace.c
index 41196209a906..134d494158d9 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -695,12 +695,16 @@ static inline void mangle(struct seq_file *m, const char *s)
*/
int generic_show_options(struct seq_file *m, struct vfsmount *mnt)
{
- const char *options = mnt->mnt_sb->s_options;
+ const char *options;
+
+ rcu_read_lock();
+ options = rcu_dereference(mnt->mnt_sb->s_options);
if (options != NULL && options[0]) {
seq_putc(m, ',');
mangle(m, options);
}
+ rcu_read_unlock();
return 0;
}
@@ -721,11 +725,22 @@ EXPORT_SYMBOL(generic_show_options);
*/
void save_mount_options(struct super_block *sb, char *options)
{
- kfree(sb->s_options);
- sb->s_options = kstrdup(options, GFP_KERNEL);
+ BUG_ON(sb->s_options);
+ rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL));
}
EXPORT_SYMBOL(save_mount_options);
+void replace_mount_options(struct super_block *sb, char *options)
+{
+ char *old = sb->s_options;
+ rcu_assign_pointer(sb->s_options, options);
+ if (old) {
+ synchronize_rcu();
+ kfree(old);
+ }
+}
+EXPORT_SYMBOL(replace_mount_options);
+
#ifdef CONFIG_PROC_FS
/* iterator */
static void *m_start(struct seq_file *m, loff_t *pos)
@@ -1073,9 +1088,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
*/
if (flags & MNT_FORCE && sb->s_op->umount_begin) {
- lock_kernel();
sb->s_op->umount_begin(sb);
- unlock_kernel();
}
/*
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 6717200923fe..d2d67781c579 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -683,9 +683,12 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
*/
static void nfs_umount_begin(struct super_blo