Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / fs / hfsplus / inode.c
index d260dd3..0eb1a60 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
-#include <linux/version.h>
 #include <linux/mpage.h>
 
 #include "hfsplus_fs.h"
 
 static int hfsplus_readpage(struct file *file, struct page *page)
 {
-       //printk("readpage: %lu\n", page->index);
        return block_read_full_page(page, hfsplus_get_block);
 }
 
 static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
 {
-       //printk("writepage: %lu\n", page->index);
        return block_write_full_page(page, hfsplus_get_block, wbc);
 }
 
@@ -40,7 +37,7 @@ static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
        return generic_block_bmap(mapping, block, hfsplus_get_block);
 }
 
-int hfsplus_releasepage(struct page *page, int mask)
+static int hfsplus_releasepage(struct page *page, gfp_t mask)
 {
        struct inode *inode = page->mapping->host;
        struct super_block *sb = inode->i_sb;
@@ -71,12 +68,6 @@ int hfsplus_releasepage(struct page *page, int mask)
                        ;
                else if (atomic_read(&node->refcnt))
                        res = 0;
-               else for (i = 0; i < tree->pages_per_bnode; i++) {
-                       if (PageActive(node->page[i])) {
-                               res = 0;
-                               break;
-                       }
-               }
                if (res && node) {
                        hfs_bnode_unhash(node);
                        hfs_bnode_free(node);
@@ -99,19 +90,7 @@ int hfsplus_releasepage(struct page *page, int mask)
                } while (--i && nidx < tree->node_count);
                spin_unlock(&tree->hash_lock);
        }
-       //printk("releasepage: %lu,%x = %d\n", page->index, mask, res);
-       return res;
-}
-
-static int hfsplus_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
-                             struct buffer_head *bh_result, int create)
-{
-       int ret;
-
-       ret = hfsplus_get_block(inode, iblock, bh_result, create);
-       if (!ret)
-               bh_result->b_size = (1 << inode->i_blkbits);
-       return ret;
+       return res ? try_to_free_buffers(page) : 0;
 }
 
 static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
@@ -121,7 +100,7 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
        struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
 
        return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-                                 offset, nr_segs, hfsplus_get_blocks, NULL);
+                                 offset, nr_segs, hfsplus_get_block, NULL);
 }
 
 static int hfsplus_writepages(struct address_space *mapping,
@@ -130,7 +109,7 @@ static int hfsplus_writepages(struct address_space *mapping,
        return mpage_writepages(mapping, wbc, hfsplus_get_block);
 }
 
-struct address_space_operations hfsplus_btree_aops = {
+const struct address_space_operations hfsplus_btree_aops = {
        .readpage       = hfsplus_readpage,
        .writepage      = hfsplus_writepage,
        .sync_page      = block_sync_page,
@@ -140,7 +119,7 @@ struct address_space_operations hfsplus_btree_aops = {
        .releasepage    = hfsplus_releasepage,
 };
 
-struct address_space_operations hfsplus_aops = {
+const struct address_space_operations hfsplus_aops = {
        .readpage       = hfsplus_readpage,
        .writepage      = hfsplus_writepage,
        .sync_page      = block_sync_page,
@@ -189,11 +168,6 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent
        igrab(dir);
        hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes);
        mark_inode_dirty(inode);
-       {
-       void hfsplus_inode_check(struct super_block *sb);
-       atomic_inc(&HFSPLUS_SB(sb).inode_cnt);
-       hfsplus_inode_check(sb);
-       }
 out:
        d_add(dentry, inode);
        return NULL;
@@ -283,13 +257,13 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
        if (atomic_read(&file->f_count) != 0)
                return 0;
        if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
-               down(&inode->i_sem);
+               mutex_lock(&inode->i_mutex);
                hfsplus_file_truncate(inode);
                if (inode->i_flags & S_DEAD) {
                        hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
                        hfsplus_delete_inode(inode);
                }
-               up(&inode->i_sem);
+               mutex_unlock(&inode->i_mutex);
        }
        return 0;
 }
@@ -297,7 +271,7 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
 extern struct inode_operations hfsplus_dir_inode_operations;
 extern struct file_operations hfsplus_dir_operations;
 
-struct inode_operations hfsplus_file_inode_operations = {
+static struct inode_operations hfsplus_file_inode_operations = {
        .lookup         = hfsplus_file_lookup,
        .truncate       = hfsplus_file_truncate,
        .permission     = hfsplus_permission,
@@ -306,7 +280,7 @@ struct inode_operations hfsplus_file_inode_operations = {
        .listxattr      = hfsplus_listxattr,
 };
 
-struct file_operations hfsplus_file_operations = {
+static const struct file_operations hfsplus_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_file_read,
        .write          = generic_file_write,
@@ -324,18 +298,12 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
        if (!inode)
                return NULL;
 
-       {
-       void hfsplus_inode_check(struct super_block *sb);
-       atomic_inc(&HFSPLUS_SB(sb).inode_cnt);
-       hfsplus_inode_check(sb);
-       }
        inode->i_ino = HFSPLUS_SB(sb).next_cnid++;
        inode->i_mode = mode;
        inode->i_uid = current->fsuid;
        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);
@@ -438,7 +406,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;
 
@@ -451,7 +418,8 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
                inode->i_size = 2 + be32_to_cpu(folder->valence);
                inode->i_atime = hfsp_mt2ut(folder->access_date);
                inode->i_mtime = hfsp_mt2ut(folder->content_mod_date);
-               inode->i_ctime = inode->i_mtime;
+               inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date);
+               HFSPLUS_I(inode).create_date = folder->create_date;
                HFSPLUS_I(inode).fs_blocks = 0;
                inode->i_op = &hfsplus_dir_inode_operations;
                inode->i_fop = &hfsplus_dir_operations;
@@ -482,9 +450,10 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
                }
                inode->i_atime = hfsp_mt2ut(file->access_date);
                inode->i_mtime = hfsp_mt2ut(file->content_mod_date);
-               inode->i_ctime = inode->i_mtime;
+               inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date);
+               HFSPLUS_I(inode).create_date = file->create_date;
        } else {
-               printk("HFS+-fs: bad catalog entry used to create inode\n");
+               printk(KERN_ERR "hfs: bad catalog entry used to create inode\n");
                res = -EIO;
        }
        return res;