exec: RT sub-thread can livelock and monopolize CPU on exec
[safe/jmp/linux-2.6] / fs / hfsplus / inode.c
index 924ecde..37744cf 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/mpage.h>
+#include <linux/sched.h>
 
 #include "hfsplus_fs.h"
 #include "hfsplus_raw.h"
@@ -26,10 +27,14 @@ static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
        return block_write_full_page(page, hfsplus_get_block, wbc);
 }
 
-static int hfsplus_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int hfsplus_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata)
 {
-       return cont_prepare_write(page, from, to, hfsplus_get_block,
-               &HFSPLUS_I(page->mapping->host).phys_size);
+       *pagep = NULL;
+       return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+                               hfsplus_get_block,
+                               &HFSPLUS_I(mapping->host).phys_size);
 }
 
 static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
@@ -97,7 +102,7 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
                const struct iovec *iov, loff_t offset, unsigned long nr_segs)
 {
        struct file *file = iocb->ki_filp;
-       struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
+       struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
 
        return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
                                  offset, nr_segs, hfsplus_get_block, NULL);
@@ -113,8 +118,8 @@ const struct address_space_operations hfsplus_btree_aops = {
        .readpage       = hfsplus_readpage,
        .writepage      = hfsplus_writepage,
        .sync_page      = block_sync_page,
-       .prepare_write  = hfsplus_prepare_write,
-       .commit_write   = generic_commit_write,
+       .write_begin    = hfsplus_write_begin,
+       .write_end      = generic_write_end,
        .bmap           = hfsplus_bmap,
        .releasepage    = hfsplus_releasepage,
 };
@@ -123,13 +128,18 @@ const struct address_space_operations hfsplus_aops = {
        .readpage       = hfsplus_readpage,
        .writepage      = hfsplus_writepage,
        .sync_page      = block_sync_page,
-       .prepare_write  = hfsplus_prepare_write,
-       .commit_write   = generic_commit_write,
+       .write_begin    = hfsplus_write_begin,
+       .write_end      = generic_write_end,
        .bmap           = hfsplus_bmap,
        .direct_IO      = hfsplus_direct_IO,
        .writepages     = hfsplus_writepages,
 };
 
+struct dentry_operations hfsplus_dentry_operations = {
+       .d_hash       = hfsplus_hash_dentry,
+       .d_compare    = hfsplus_compare_dentry,
+};
+
 static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry,
                                          struct nameidata *nd)
 {
@@ -268,10 +278,10 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-extern struct inode_operations hfsplus_dir_inode_operations;
+extern const struct inode_operations hfsplus_dir_inode_operations;
 extern struct file_operations hfsplus_dir_operations;
 
-static struct inode_operations hfsplus_file_inode_operations = {
+static const struct inode_operations hfsplus_file_inode_operations = {
        .lookup         = hfsplus_file_lookup,
        .truncate       = hfsplus_file_truncate,
        .permission     = hfsplus_permission,
@@ -282,10 +292,12 @@ static struct inode_operations hfsplus_file_inode_operations = {
 
 static const struct file_operations hfsplus_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = generic_file_read,
-       .write          = generic_file_write,
+       .read           = do_sync_read,
+       .aio_read       = generic_file_aio_read,
+       .write          = do_sync_write,
+       .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
        .fsync          = file_fsync,
        .open           = hfsplus_file_open,
        .release        = hfsplus_file_release,
@@ -304,7 +316,6 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
        inode->i_gid = current->fsgid;
        inode->i_nlink = 1;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
-       inode->i_blksize = HFSPLUS_SB(sb).alloc_blksz;
        INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
        init_MUTEX(&HFSPLUS_I(inode).extents_lock);
        atomic_set(&HFSPLUS_I(inode).opencnt, 0);
@@ -407,7 +418,6 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
        type = hfs_bnode_read_u16(fd->bnode, fd->entryoffset);
 
        HFSPLUS_I(inode).dev = 0;
-       inode->i_blksize = HFSPLUS_SB(inode->i_sb).alloc_blksz;
        if (type == HFSPLUS_FOLDER) {
                struct hfsplus_cat_folder *folder = &entry.folder;