Commit 4b4f1d01 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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()
  ...
parents 875287ca aa7dfb89
......@@ -192,77 +192,42 @@ static int autofs_dev_ioctl_protosubver(struct file *fp,
return 0;
}
/*
* Walk down the mount stack looking for an autofs mount that
* has the requested device number (aka. new_encode_dev(sb->s_dev).
*/
static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
static int find_autofs_mount(const char *pathname,
struct path *res,
int test(struct path *path, void *data),
void *data)
{
struct dentry *dentry;
struct inode *inode;
struct super_block *sb;
dev_t s_dev;
unsigned int err;
struct path path;
int err = kern_path(pathname, 0, &path);
if (err)
return err;
err = -ENOENT;
/* Lookup the dentry name at the base of our mount point */
dentry = d_lookup(nd->path.dentry, &nd->last);
if (!dentry)
goto out;
dput(nd->path.dentry);
nd->path.dentry = dentry;
/* And follow the mount stack looking for our autofs mount */
while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
inode = nd->path.dentry->d_inode;
if (!inode)
break;
sb = inode->i_sb;
s_dev = new_encode_dev(sb->s_dev);
if (devno == s_dev) {
if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
while (path.dentry == path.mnt->mnt_root) {
if (path.mnt->mnt_sb->s_magic == AUTOFS_SUPER_MAGIC) {
if (test(&path, data)) {
path_get(&path);
if (!err) /* already found some */
path_put(res);
*res = path;
err = 0;
break;
}
}
if (!follow_up(&path))
break;
}
out:
path_put(&path);
return err;
}
/*
* Walk down the mount stack looking for an autofs mount that
* has the requested mount type (ie. indirect, direct or offset).
*/
static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
static int test_by_dev(struct path *path, void *p)
{
struct dentry *dentry;
struct autofs_info *ino;
unsigned int err;
err = -ENOENT;
/* Lookup the dentry name at the base of our mount point */
dentry = d_lookup(nd->path.dentry, &nd->last);
if (!dentry)
goto out;
dput(nd->path.dentry);
nd->path.dentry = dentry;
return path->mnt->mnt_sb->s_dev == *(dev_t *)p;
}
/* And follow the mount stack looking for our autofs mount */
while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
ino = autofs4_dentry_ino(nd->path.dentry);
if (ino && ino->sbi->type & type) {
err = 0;
break;
}
}
out:
return err;
static int test_by_type(struct path *path, void *p)
{
struct autofs_info *ino = autofs4_dentry_ino(path->dentry);
return ino && ino->sbi->type & *(unsigned *)p;
}
static 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)
* Open a file descriptor on the autofs mount point corresponding
* to the given path and device number (aka. new_encode_dev(sb->s_dev)).
*/
static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
{
struct file *filp;
struct nameidata nd;
int err, fd;
fd = get_unused_fd();
if (likely(fd >= 0)) {
/* Get nameidata of the parent directory */
err = path_lookup(path, LOOKUP_PARENT, &nd);
struct file *filp;
struct path path;
err = find_autofs_mount(name, &path, test_by_dev, &devid);
if (err)
goto out;
/*
* Search down, within the parent, looking for an
* autofs super block that has the device number
* Find autofs super block that has the device number
* corresponding to the autofs fs we want to open.
*/
err = autofs_dev_ioctl_find_super(&nd, devid);
if (err) {
path_put(&nd.path);
goto out;
}
filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
filp = dentry_open(path.dentry, path.mnt, O_RDONLY,
current_cred());
if (IS_ERR(filp)) {
err = PTR_ERR(filp);
......@@ -340,7 +299,7 @@ static int autofs_dev_ioctl_openmount(struct file *fp,
param->ioctlfd = -1;
path = param->path;
devid = param->openmount.devid;
devid = new_decode_dev(param->openmount.devid);
err = 0;
fd = autofs_dev_ioctl_open_mountpoint(path, devid);
......@@ -475,8 +434,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
struct autofs_dev_ioctl *param)
{
struct autofs_info *ino;
struct nameidata nd;
const char *path;
struct path path;
dev_t devid;
int err = -ENOENT;
......@@ -485,32 +443,24 @@ static int autofs_dev_ioctl_requester(struct file *fp,
goto out;
}
path = param->path;
devid = new_encode_dev(sbi->sb->s_dev);
devid = sbi->sb->s_dev;
param->requester.uid = param->requester.gid = -1;
/* Get nameidata of the parent directory */
err = path_lookup(path, LOOKUP_PARENT, &nd);
err = find_autofs_mount(param->path, &path, test_by_dev, &devid);
if (err)
goto out;
err = autofs_dev_ioctl_find_super(&nd, devid);
if (err)
goto out_release;
ino = autofs4_dentry_ino(nd.path.dentry);
ino = autofs4_dentry_ino(path.dentry);
if (ino) {
err = 0;
autofs4_expire_wait(nd.path.dentry);
autofs4_expire_wait(path.dentry);
spin_lock(&sbi->fs_lock);
param->requester.uid = ino->uid;
param->requester.gid = ino->gid;
spin_unlock(&sbi->fs_lock);
}
out_release:
path_put(&nd.path);
path_put(&path);
out:
return err;
}
......@@ -569,8 +519,8 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
struct autofs_sb_info *sbi,
struct autofs_dev_ioctl *param)
{
struct nameidata nd;
const char *path;
struct path path;
const char *name;
unsigned int type;
unsigned int devid, magic;
int err = -ENOENT;
......@@ -580,71 +530,46 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
goto out;
}
path = param->path;
name = param->path;
type = param->ismountpoint.in.type;
param->ismountpoint.out.devid = devid = 0;
param->ismountpoint.out.magic = magic = 0;
if (!fp || param->ioctlfd == -1) {
if (autofs_type_any(type)) {
struct super_block *sb;
err = path_lookup(path, LOOKUP_FOLLOW, &nd);
if (err)
goto out;
sb = nd.path.dentry->d_sb;
devid = new_encode_dev(sb->s_dev);
} else {
struct autofs_info *ino;
err = path_lookup(path, LOOKUP_PARENT, &nd);
if (err)
goto out;
err = autofs_dev_ioctl_find_sbi_type(&nd, type);
if (err)
goto out_release;
ino = autofs4_dentry_ino(nd.path.dentry);
devid = autofs4_get_dev(ino->sbi);
}
if (autofs_type_any(type))
err = kern_path(name, LOOKUP_FOLLOW, &path);
else
err = find_autofs_mount(name, &path, test_by_type, &type);
if (err)
goto out;
devid = new_encode_dev(path.mnt->mnt_sb->s_dev);
err = 0;
if (nd.path.dentry->d_inode &&
nd.path.mnt->mnt_root == nd.path.dentry) {
if (path.dentry->d_inode &&
path.mnt->mnt_root == path.dentry) {
err = 1;
magic = nd.path.dentry->d_inode->i_sb->s_magic;
magic = path.dentry->d_inode->i_sb->s_magic;
}
} else {
dev_t dev = autofs4_get_dev(sbi);
dev_t dev = sbi->sb->s_dev;
err = path_lookup(path, LOOKUP_PARENT, &nd);
err = find_autofs_mount(name, &path, test_by_dev, &dev);
if (err)
goto out;
err = autofs_dev_ioctl_find_super(&nd, dev);
if (err)
goto out_release;
devid = dev;
devid = new_encode_dev(dev);
err = have_submounts(nd.path.dentry);
err = have_submounts(path.dentry);
if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) {
if (follow_down(&nd.path.mnt, &nd.path.dentry)) {
struct inode *inode = nd.path.dentry->d_inode;
magic = inode->i_sb->s_magic;
}
if (path.mnt->mnt_mountpoint != path.mnt->mnt_root) {
if (follow_down(&path))
magic = path.mnt->mnt_sb->s_magic;
}
}
param->ismountpoint.out.devid = devid;
param->ismountpoint.out.magic = magic;
out_release:
path_put(&nd.path);
path_put(&path);
out:
return err;
}
......
......@@ -48,19 +48,19 @@ static inline int autofs4_can_expire(struct dentry *dentry,
static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
{
struct dentry *top = dentry;
struct path path = {.mnt = mnt, .dentry = dentry};
int status = 1;
DPRINTK("dentry %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
mntget(mnt);
dget(dentry);
path_get(&path);
if (!follow_down(&mnt, &dentry))
if (!follow_down(&path))
goto done;
if (is_autofs4_dentry(dentry)) {
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
if (is_autofs4_dentry(path.dentry)) {
struct autofs_sb_info *sbi = autofs4_sbi(path.dentry->d_sb);
/* This is an autofs submount, we can't expire it */
if (autofs_type_indirect(sbi->type))
......@@ -70,7 +70,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
* Otherwise it's an offset mount and we need to check
* if we can umount its mount, if there is one.
*/
if (!d_mountpoint(dentry)) {
if (!d_mountpoint(path.dentry)) {
status = 0;
goto done;
}
......@@ -86,8 +86,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
status = 0;
done:
DPRINTK("returning = %d", status);
dput(dentry);
mntput(mnt);
path_put(&path);
return status;
}
......
......@@ -181,7 +181,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
nd->flags);
/*
* For an expire of a covered direct or offset mount we need
* to beeak out of follow_down() at the autofs mount trigger
* to break out of follow_down() at the autofs mount trigger
* (d_mounted--), so we can see the expiring flag, and manage
* the blocking and following here until the expire is completed.
*/
......@@ -190,7 +190,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
if (ino->flags & AUTOFS_INF_EXPIRING) {
spin_unlock(&sbi->fs_lock);
/* Follow down to our covering mount. */
if (!follow_down(&nd->path.mnt, &nd->path.dentry))
if (!follow_down(&nd->path))
goto done;
goto follow;
}
......@@ -230,8 +230,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
* to follow it.
*/
if (d_mountpoint(dentry)) {
if (!autofs4_follow_mount(&nd->path.mnt,
&nd->path.dentry)) {
if (!autofs4_follow_mount(&nd->path)) {
status = -ENOENT;
goto out_error;
}
......
......@@ -737,6 +737,8 @@ parse_options(char *options, befs_mount_options * opts)
static void
befs_put_super(struct super_block *sb)
{
lock_kernel();
kfree(BEFS_SB(sb)->mount_opts.iocharset);
BEFS_SB(sb)->mount_opts.iocharset = NULL;
......@@ -747,7 +749,8 @@ befs_put_super(struct super_block *sb)
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return;
unlock_kernel();
}
/* Allocate private field of the superblock, fill it.
......
......@@ -79,7 +79,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
const struct file_operations bfs_dir_operations = {
.read = generic_read_dir,
.readdir = bfs_readdir,
.fsync = file_fsync,
.fsync = simple_fsync,
.llseek = generic_file_llseek,
};
......@@ -205,7 +205,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry)
inode->i_nlink = 1;
}
de->ino = 0;
mark_buffer_dirty(bh);
mark_buffer_dirty_inode(bh, dir);
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
inode->i_ctime = dir->i_ctime;
......@@ -267,7 +267,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
new_inode->i_ctime = CURRENT_TIME_SEC;
inode_dec_link_count(new_inode);
}
mark_buffer_dirty(old_bh);
mark_buffer_dirty_inode(old_bh, old_dir);
error = 0;
end_rename:
......@@ -320,7 +320,7 @@ static int bfs_add_entry(struct inode *dir, const unsigned char *name,
for (i = 0; i < BFS_NAMELEN; i++)
de->name[i] =
(i < namelen) ? name[i] : 0;
mark_buffer_dirty(bh);
mark_buffer_dirty_inode(bh, dir);
brelse(bh);
return 0;
}
......
......@@ -30,6 +30,7 @@ MODULE_LICENSE("GPL");
#define dprintf(x...)
#endif
static void bfs_write_super(struct super_block *s);
void dump_imap(const char *prefix, struct super_block *s);
struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
......@@ -97,14 +98,15 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
return ERR_PTR(-EIO);
}
static int bfs_write_inode(struct inode *inode, int unused)
static int bfs_write_inode(struct inode *inode, int wait)
{
struct bfs_sb_info *info = BFS_SB(inode->i_sb);
unsigned int ino = (u16)inode->i_ino;
unsigned long i_sblock;
struct bfs_inode *di;
struct buffer_head *bh;
int block, off;
struct bfs_sb_info *info = BFS_SB(inode->i_sb);
int err = 0;
dprintf("ino=%08x\n", ino);
......@@ -145,9 +147,14 @@ static int bfs_write_inode(struct inode *inode, int unused)
di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
mark_buffer_dirty(bh);
if (wait) {
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh))
err = -EIO;
}
brelse(bh);
mutex_unlock(&info->bfs_lock);
return 0;
return err;
}
static void bfs_delete_inode(struct inode *inode)
......@@ -209,6 +216,26 @@ static void bfs_delete_inode(struct inode *inode)
clear_inode(inode);
}
static int bfs_sync_fs(struct super_block *sb, int wait)
{
struct bfs_sb_info *info = BFS_SB(sb);
mutex_lock(&info->bfs_lock);
mark_buffer_dirty(info->si_sbh);
sb->s_dirt = 0;
mutex_unlock(&info->bfs_lock);
return 0;
}
static void bfs_write_super(struct super_block *sb)
{
if (!(sb->s_flags & MS_RDONLY))
bfs_sync_fs(sb, 1);
else
sb->s_dirt = 0;
}
static void bfs_put_super(struct super_block *s)
{
struct bfs_sb_info *info = BFS_SB(s);
......@@ -216,11 +243,18 @@ static void bfs_put_super(struct super_block *s)
if (!info)
return;
lock_kernel();
if (s->s_dirt)
bfs_write_super(s);
brelse(info->si_sbh);
mutex_destroy(&info->bfs_lock);
kfree(info->si_imap);
kfree(info);
s->s_fs_info = NULL;
unlock_kernel();
}
static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
......@@ -240,17 +274,6 @@ static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
return 0;
}
static void bfs_write_super(struct super_block *s)
{
struct bfs_sb_info *info = BFS_SB(s);
mutex_lock(&info->bfs_lock);
if (!(s->s_flags & MS_RDONLY))
mark_buffer_dirty(info->si_sbh);
s->s_dirt = 0;
mutex_unlock(&info->bfs_lock);
}
static struct kmem_cache *bfs_inode_cachep;
static struct inode *bfs_alloc_inode(struct super_block *sb)
......@@ -298,6 +321,7 @@ static const struct super_operations bfs_sops = {
.delete_inode = bfs_delete_inode,
.put_super = bfs_put_super,
.write_super = bfs_write_super,
.sync_fs = bfs_sync_fs,
.statfs = bfs_statfs,
};
......
......@@ -176,17 +176,22 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
iov, offset, nr_segs, blkdev_get_blocks, NULL);
}
int __sync_blockdev(struct block_device *bdev, int wait)
{
if (!bdev)
return 0;
if (!wait)
return filemap_flush(bdev->bd_inode->i_mapping);
return filemap_write_and_wait(bdev->bd_inode->i_mapping);
}
/*
* Write out and wait upon all the dirty data associated with a block
* device via its mapping. Does not take the superblock lock.
*/
int sync_blockdev(struct block_device *bdev)
{
int ret = 0;
if (bdev)
ret = filemap_write_and_wait(bdev->bd_inode->i_mapping);
return ret;
return __sync_blockdev(bdev, 1);
}
EXPORT_SYMBOL(sync_blockdev);
......@@ -199,7 +204,7 @@ int fsync_bdev(struct block_device *bdev)
{
struct super_block *sb = get_super(bdev);
if (sb) {
int res = fsync_super(sb);
int res = sync_filesystem(sb);
drop_super(sb);
return res;
}
......@@ -241,7 +246,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
sb->s_frozen = SB_FREEZE_WRITE;
smp_wmb();
__fsync_super(sb);
sync_filesystem(sb);
sb->s_frozen = SB_FREEZE_TRANS;
smp_wmb();
......
......@@ -2322,7 +2322,6 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
btrfs_update_inode(trans, root, dir);
btrfs_drop_nlink(inode);
ret = btrfs_update_inode(trans, root, inode);
dir->i_sb->s_dirt = 1;
out:
return ret;
}
......@@ -2806,7 +2805,6 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
pending_del_nr);
}
btrfs_free_path(path);
inode->i_sb->s_dirt = 1;
return ret;
}
......@@ -3768,7 +3766,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
init_special_inode(inode, inode->i_mode, rdev);
btrfs_update_inode(trans, root, inode);
}
dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
out_unlock:
......@@ -3833,7 +3830,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
inode->i_op = &btrfs_file_inode_operations;
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
}
dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
out_unlock:
......@@ -3880,7 +3876,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
if (err)
drop_inode = 1;
dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, dir);
err = btrfs_update_inode(trans, root, inode);
......@@ -3962,7 +3957,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
d_instantiate(dentry, inode);
drop_on_err = 0;
dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
......@@ -4991,7 +4985,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
inode->i_op = &btrfs_file_inode_operations;
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
}
dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
if (drop_inode)
......
......@@ -394,10 +394,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
struct btrfs_root *root = btrfs_sb(sb);
int ret;
if (sb->s_flags & MS_RDONLY)
return 0;
sb->s_dirt = 0;
if (!wait) {
filemap_flush(root->fs_info->btree_inode->i_mapping);
return 0;
......@@ -408,7 +404,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
trans = btrfs_start_transaction(root, 1);
ret = btrfs_commit_transaction(trans, root);
sb->s_dirt = 0;
return ret;
}
......@@ -454,11 +449,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
return 0;
}
static void btrfs_write_super(struct super_block *sb)
{
sb->s_dirt = 0;
}
static int btrfs_test_super(struct super_block *s, void *data)
{
struct btrfs_fs_devices *test_fs_devices = data;
......@@ -689,7 +679,6 @@ static int btrfs_unfreeze(struct super_block *sb)
static struct super_operations btrfs_super_ops = {
.delete_inode = btrfs_delete_inode,
.put_super = btrfs_put_super,
.write_super = btrfs_write_super,
.sync_fs = btrfs_sync_fs,
.show_options = btrfs_show_options,
.write_inode = btrfs_write_inode,
......
......@@ -354,7 +354,9 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache)
/* make sure all pages pinned by operations on behalf of the netfs are
* written to disc */
cachefiles_begin_secure(cache, &saved_cred);
ret = fsync_super(cache->mnt->mnt_sb);
down_read(&cache->mnt->mnt_sb->s_umount);
ret = sync_filesystem(cache->mnt->mnt_sb);
up_read(&cache->mnt->mnt_sb->s_umount);
cachefiles_end_secure(cache, saved_cred);
if (ret == -EIO)
......
......@@ -375,7 +375,6 @@ static int chrdev_open(struct inode *inode, struct file *filp)
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
inode->i_cindex = idx;
list_add(&inode->i_devices, &p->list);
new = NULL;
} else if (!cdev_get(p))
......@@ -405,6 +404,18 @@ static int chrdev_open(struct inode *inode, struct file *filp)
return ret;
}
int cdev_index(struct inode *inode)
{
int idx;
struct kobject *kobj;
kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
if (!kobj)
return -1;
kobject_put(kobj);
return idx;
}
void cd_forget(struct inode *inode)
{
spin_lock(&cdev_lock);
......@@ -557,6 +568,7 @@ EXPORT_SYMBOL(cdev_init);
EXPORT_SYMBOL(cdev_alloc);
EXPORT_SYMBOL(cdev_del);
EXPORT_SYMBOL(cdev_add);
EXPORT_SYMBOL(cdev_index);
EXPORT_SYMBOL(register_chrdev);
EXPORT_SYMBOL(unregister_chrdev);
EXPORT_SYMBOL(directly_mappable_cdev_bdi);
......@@ -275,7 +275,7 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
case -EBUSY:
/* someone else made a mount here whilst we were busy */
while (d_mountpoint(nd->path.dentry) &&
follow_down(&nd->path.mnt, &nd->path.dentry))
follow_down(&nd->path))
;
err = 0;
default:
......
......@@ -204,6 +204,9 @@ cifs_put_super(struct super_block *sb)
cFYI(1, ("Empty cifs superblock info passed to unmount"));
return;
}
lock_kernel();
rc = cifs_umount(sb, cifs_sb);
if (rc)
cERROR(1, ("cifs_umount failed with return code %d", rc));
......@@ -216,7 +219,8 @@ cifs_put_super(struct super_block *sb)
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
return;
unlock_kernel();
}
static int
......
......@@ -812,10 +812,8 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
}
}
lock_kernel();
retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
flags, (void*)data_page);
unlock_kernel();
out4:
free_page(data_page);
......
......@@ -1910,7 +1910,7 @@ char *__d_path(const struct path *path, struct path *root,
spin_lock(&vfsmount_lock);
prepend(&end, &buflen, "\0", 1);
if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
if (d_unlinked(dentry) &&
(prepend(&end, &buflen, " (deleted)", 10) != 0))
goto Elong;
......@@ -2035,7 +2035,7 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
spin_lock(&dcache_lock);
prepend(&end, &buflen, "\0", 1);
if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
if (d_unlinked(dentry) &&
(prepend(&end, &buflen, "//deleted", 9) != 0))
goto Elong;
if (buflen < 1)
......@@ -2097,9 +2097,8 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
read_unlock(&current->fs->lock);
error = -ENOENT;
/* Has the current directory has been unlinked? */
spin_lock(&dcache_lock);
if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
if (!d_unlinked(pwd.dentry)) {
unsigned long len;
struct path tmp = root;
char * cwd;
......
......@@ -27,6 +27,7 @@
#include <linux/mount.h>
#include <linux/key.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/crypto.h>
#include "ecryptfs_kernel.h"
......@@ -120,9 +121,13 @@ static void ecryptfs_put_super(struct super_block *sb)
{
struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
lock_kernel();
ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
ecryptfs_set_superblock_private(sb, NULL);
unlock_kernel();
}
/**
......
......@@ -200,20 +200,21 @@ static const struct export_operations exofs_export_ops;
/*
* Write the superblock to the OSD
*/
static void exofs_write_super(struct super_block *sb)
static int exofs_sync_fs(struct super_block *sb, int wait)
{
struct exofs_sb_info *sbi;
struct exofs_fscb *fscb;
struct osd_request *or;
struct osd_obj_id obj;
int ret;
int ret = -ENOMEM;
fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
if (!fscb) {
EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
return;
return -ENOMEM;
}
lock_super(sb);
lock_kernel();
sbi = sb->s_fs_info;
fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
......@@ -246,7 +247,17 @@ static void exofs_write_super(struct super_block *sb)
if (or)
osd_end_request(or);
unlock_kernel();
unlock_super(sb);
kfree(fscb);
return ret;
}
static void exofs_write_super(struct super_block *sb)
{
if (!(sb->s_flags & MS_RDONLY))
exofs_sync_fs(sb, 1);
else
sb->s_dirt = 0;
}
/*
......@@ -258,6 +269,11 @@ static void exofs_put_super(struct super_block *sb)
int num_pend;
struct exofs_sb_info *sbi = sb->s_fs_info;
lock_kernel();
if (sb->s_dirt)
exofs_write_super(sb);
/* make sure there are no pending commands */
for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
num_pend = atomic_read(&sbi->s_curr_pending)) {
......@@ -271,6 +287,8 @@ static void exofs_put_super(struct super_block *sb)
osduld_put_device(sbi->s_dev);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
unlock_kernel();
}
/*
......@@ -484,6 +502,7 @@ static const struct super_operations exofs_sops = {
.delete_inode = exofs_delete_inode,
.put_super = exofs_put_super,
.write_super = exofs_write_super,
.sync_fs = exofs_sync_fs,
.statfs = exofs_statfs,
};
......
......@@ -4,7 +4,7 @@
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o dir.o file.o fsync.o ialloc.o inode.o \
ext2-y := balloc.o dir.o file.o ialloc.o inode.o \
ioctl.o namei.o super.o symlink.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
......
......@@ -720,5 +720,5 @@ const struct file_operations ext2_dir_operations = {
#ifdef CONFIG_COMPAT
.compat_ioctl = ext2_compat_ioctl,
#endif
.fsync = ext2_sync_file,
.fsync = simple_fsync,
};
......@@ -113,9 +113,6 @@ extern int ext2_empty_dir (struct inode *);
extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
/* fsync.c */
extern int ext2_sync_file (struct file *, struct dentry *, int);
/* ialloc.c */
extern struct inode * ext2_new_inode (struct inode *, int);
extern void ext2_free_inode (struct inode *);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment