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
......@@ -371,8 +371,6 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
int retval = -EINVAL;
char *name;
lock_kernel();
name = getname(path);
retval = PTR_ERR(name);
if (IS_ERR(name))
......@@ -392,7 +390,6 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
}
putname(name);
out:
unlock_kernel();
return retval;
}
......
......@@ -1789,12 +1789,13 @@ static int dv1394_open(struct inode *inode, struct file *file)
} else {
/* look up the card by ID */
unsigned long flags;
int idx = ieee1394_file_to_instance(file);
spin_lock_irqsave(&dv1394_cards_lock, flags);
if (!list_empty(&dv1394_cards)) {
struct video_card *p;
list_for_each_entry(p, &dv1394_cards, list) {
if ((p->id) == ieee1394_file_to_instance(file)) {
if ((p->id) == idx) {
video = p;
break;
}
......@@ -1803,7 +1804,7 @@ static int dv1394_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&dv1394_cards_lock, flags);
if (!video) {
debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file));
debug_printk("dv1394: OHCI card %d not found", idx);
return -ENODEV;
}
......
......@@ -5,6 +5,7 @@
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <asm/atomic.h>
#include "hosts.h"
......@@ -155,7 +156,10 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
*/
static inline unsigned char ieee1394_file_to_instance(struct file *file)
{
return file->f_path.dentry->d_inode->i_cindex;
int idx = cdev_index(file->f_path.dentry->d_inode);
if (idx < 0)
idx = 0;
return idx;
}
extern int hpsb_disable_irm;
......
......@@ -39,6 +39,7 @@
#include <linux/parser.h>
#include <linux/notifier.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include "usb.h"
#include "hcd.h"
......@@ -265,9 +266,13 @@ static int remount(struct super_block *sb, int *flags, char *data)
return -EINVAL;
}
lock_kernel();
if (usbfs_mount && usbfs_mount->mnt_sb)
update_sb(usbfs_mount->mnt_sb);
unlock_kernel();
return 0;
}
......
......@@ -53,6 +53,7 @@ struct adfs_dir_ops {
int (*update)(struct adfs_dir *dir, struct object_info *obj);
int (*create)(struct adfs_dir *dir, struct object_info *obj);
int (*remove)(struct adfs_dir *dir, struct object_info *obj);
int (*sync)(struct adfs_dir *dir);
void (*free)(struct adfs_dir *dir);
};
......@@ -90,7 +91,8 @@ extern const struct dentry_operations adfs_dentry_operations;
extern struct adfs_dir_ops adfs_f_dir_ops;
extern struct adfs_dir_ops adfs_fplus_dir_ops;
extern int adfs_dir_update(struct super_block *sb, struct object_info *obj);
extern int adfs_dir_update(struct super_block *sb, struct object_info *obj,
int wait);
/* file.c */
extern const struct inode_operations adfs_file_inode_operations;
......
......@@ -83,7 +83,7 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
int
adfs_dir_update(struct super_block *sb, struct object_info *obj)
adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
{
int ret = -EINVAL;
#ifdef CONFIG_ADFS_FS_RW
......@@ -106,6 +106,12 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj)
ret = ops->update(&dir, obj);
write_unlock(&adfs_dir_lock);
if (wait) {
int err = ops->sync(&dir);
if (!ret)
ret = err;
}
ops->free(&dir);
out:
#endif
......@@ -199,7 +205,7 @@ const struct file_operations adfs_dir_operations = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
.readdir = adfs_readdir,
.fsync = file_fsync,
.fsync = simple_fsync,
};
static int
......
......@@ -437,6 +437,22 @@ adfs_f_update(struct adfs_dir *dir, struct object_info *obj)
#endif
}
static int
adfs_f_sync(struct adfs_dir *dir)
{
int err = 0;
int i;
for (i = dir->nr_buffers - 1; i >= 0; i--) {
struct buffer_head *bh = dir->bh[i];
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh))
err = -EIO;
}
return err;
}
static void
adfs_f_free(struct adfs_dir *dir)
{
......@@ -456,5 +472,6 @@ struct adfs_dir_ops adfs_f_dir_ops = {
.setpos = adfs_f_setpos,
.getnext = adfs_f_getnext,
.update = adfs_f_update,
.sync = adfs_f_sync,
.free = adfs_f_free
};
......@@ -161,6 +161,22 @@ adfs_fplus_getnext(struct adfs_dir *dir, struct object_info *obj)
return ret;
}
static int
adfs_fplus_sync(struct adfs_dir *dir)
{
int err = 0;
int i;
for (i = dir->nr_buffers - 1; i >= 0; i--) {
struct buffer_head *bh = dir->bh[i];
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh))
err = -EIO;
}
return err;
}
static void
adfs_fplus_free(struct adfs_dir *dir)
{
......@@ -175,5 +191,6 @@ struct adfs_dir_ops adfs_fplus_dir_ops = {
.read = adfs_fplus_read,
.setpos = adfs_fplus_setpos,
.getnext = adfs_fplus_getnext,
.sync = adfs_fplus_sync,
.free = adfs_fplus_free
};
......@@ -30,7 +30,7 @@ const struct file_operations adfs_file_operations = {
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.mmap = generic_file_mmap,
.fsync = file_fsync,
.fsync = simple_fsync,
.write = do_sync_write,
.aio_write = generic_file_aio_write,
.splice_read = generic_file_splice_read,
......
......@@ -376,7 +376,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
* The adfs-specific inode data has already been updated by
* adfs_notify_change()
*/
int adfs_write_inode(struct inode *inode, int unused)
int adfs_write_inode(struct inode *inode, int wait)
{
struct super_block *sb = inode->i_sb;
struct object_info obj;
......@@ -391,7 +391,7 @@ int adfs_write_inode(struct inode *inode, int unused)
obj.attr = ADFS_I(inode)->attr;
obj.size = inode->i_size;
ret = adfs_dir_update(sb, &obj);
ret = adfs_dir_update(sb, &obj, wait);
unlock_kernel();
return ret;
}
......
......@@ -62,7 +62,7 @@ static DEFINE_RWLOCK(adfs_map_lock);
#define GET_FRAG_ID(_map,_start,_idmask) \
({ \
unsigned char *_m = _map + (_start >> 3); \
u32 _frag = get_unaligned((u32 *)_m); \
u32 _frag = get_unaligned_le32(_m); \
_frag >>= (_start & 7); \
_frag & _idmask; \
})
......
......@@ -132,11 +132,15 @@ static void adfs_put_super(struct super_block *sb)
int i;
struct adfs_sb_info *asb = ADFS_SB(sb);
lock_kernel();
for (i = 0; i < asb->s_map_size; i++)
brelse(asb->s_map[i].dm_bh);
kfree(asb->s_map);
kfree(asb);
sb->s_fs_info = NULL;
unlock_kernel();
}
static int adfs_show_options(struct seq_file *seq, struct vfsmount *mnt)
......
......@@ -182,6 +182,7 @@ extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dent
void affs_free_prealloc(struct inode *inode);
extern void affs_truncate(struct inode *);
int affs_file_fsync(struct file *, struct dentry *, int);
/* dir.c */
......
......@@ -21,7 +21,7 @@ const struct file_operations affs_dir_operations = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
.readdir = affs_readdir,
.fsync = file_fsync,
.fsync = affs_file_fsync,
};
/*
......
......@@ -34,7 +34,7 @@ const struct file_operations affs_file_operations = {
.mmap = generic_file_mmap,
.open = affs_file_open,
.release = affs_file_release,
.fsync = file_fsync,
.fsync = affs_file_fsync,
.splice_read = generic_file_splice_read,
};
......@@ -915,3 +915,15 @@ affs_truncate(struct inode *inode)
}
affs_free_prealloc(inode);
}
int affs_file_fsync(struct file *filp, struct dentry *dentry, int datasync)
{
struct inode * inode = dentry->d_inode;
int ret, err;
ret = write_inode_now(inode, 0);
err = sync_blockdev(inode->i_sb->s_bdev);
if (!ret)
ret = err;
return ret;
}
......@@ -16,6 +16,7 @@
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include "affs.h"
extern struct timezone sys_tz;
......@@ -23,50 +24,68 @@ extern struct timezone sys_tz;
static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int affs_remount (struct super_block *sb, int *flags, char *data);
static void
affs_commit_super(struct super_block *sb, int clean)
{
struct affs_sb_info *sbi = AFFS_SB(sb);
struct buffer_head *bh = sbi->s_root_bh;
struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh);
tail->bm_flag = cpu_to_be32(clean);
secs_to_datestamp(get_seconds(), &tail->disk_change);
affs_fix_checksum(sb, bh);
mark_buffer_dirty(bh);
}
static void
affs_put_super(struct super_block *sb)
{
struct affs_sb_info *sbi = AFFS_SB(sb);
pr_debug("AFFS: put_super()\n");
if (!(sb->s_flags & MS_RDONLY)) {
AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1);
secs_to_datestamp(get_seconds(),
&AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
affs_fix_checksum(sb, sbi->s_root_bh);
mark_buffer_dirty(sbi->s_root_bh);
}
lock_kernel();
if (!(sb->s_flags & MS_RDONLY))
affs_commit_super(sb, 1);
kfree(sbi->s_prefix);
affs_free_bitmap(sb);
affs_brelse(sbi->s_root_bh);
kfree(sbi);
sb->s_fs_info = NULL;
return;
unlock_kernel();
}
static void
affs_write_super(struct super_block *sb)
{
int clean = 2;
struct affs_sb_info *sbi = AFFS_SB(sb);
lock_super(sb);
if (!(sb->s_flags & MS_RDONLY)) {
// if (sbi->s_bitmap[i].bm_bh) {
// if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) {
// clean = 0;
AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(clean);
secs_to_datestamp(get_seconds(),
&AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
affs_fix_checksum(sb, sbi->s_root_bh);
mark_buffer_dirty(sbi->s_root_bh);
affs_commit_super(sb, clean);
sb->s_dirt = !clean; /* redo until bitmap synced */
} else
sb->s_dirt = 0;
unlock_super(sb);
pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean);
}
static int
affs_sync_fs(struct super_block *sb, int wait)
{
lock_super(sb);
affs_commit_super(sb, 2);
sb->s_dirt = 0;
unlock_super(sb);
return 0;
}
static struct kmem_cache * affs_inode_cachep;
static struct inode *affs_alloc_inode(struct super_block *sb)
......@@ -124,6 +143,7 @@ static const struct super_operations affs_sops = {
.clear_inode = affs_clear_inode,
.put_super = affs_put_super,
.write_super = affs_write_super,
.sync_fs = affs_sync_fs,
.statfs = affs_statfs,
.remount_fs = affs_remount,
.show_options = generic_show_options,
......@@ -507,6 +527,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
kfree(new_opts);
return -EINVAL;
}
lock_kernel();
replace_mount_options(sb, new_opts);
sbi->s_flags = mount_flags;
......@@ -514,8 +535,10 @@ affs_remount(struct super_block *sb, int *flags, char *data)
sbi->s_uid = uid;
sbi->s_gid = gid;
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
unlock_kernel();
return 0;
}
if (*flags & MS_RDONLY) {
sb->s_dirt = 1;
while (sb->s_dirt)
......@@ -524,6 +547,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
} else
res = affs_init_bitmap(sb, flags);
unlock_kernel();
return res;
}
......
......@@ -244,7 +244,7 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, 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:
......
......@@ -440,8 +440,12 @@ static void afs_put_super(struct super_block *sb)
_enter("");
lock_kernel();
afs_put_volume(as->volume);
unlock_kernel();
_leave("");
}
......
......@@ -85,13 +85,12 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
}
path.mnt = mnt;
path_get(&path);
if (!follow_down(&path.mnt, &path.dentry)) {
if (!follow_down(&path)) {
path_put(&path);
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
continue;
}
while (d_mountpoint(path.dentry) &&
follow_down(&path.mnt, &path.dentry))
while (d_mountpoint(path.dentry) && follow_down(&path));
;
umount_ok = may_umount(path.mnt);
path_put(&path);
......
......@@ -223,12 +223,12 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
void autofs4_catatonic_mode(struct autofs_sb_info *);
static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry)
static inline int autofs4_follow_mount(struct path *path)
{
int res = 0;
while (d_mountpoint(*dentry)) {
int followed = follow_down(mnt, dentry);
while (d_mountpoint(path->dentry)) {
int followed = follow_down(path);
if (!followed)
break;
res = 1;
......
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