X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Freiserfs%2Finode.c;h=8f983da39865f93ea2500fbac4da04fabdf2d8c6;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=fde429f2b8d43ce4fdde5cf940340564aa16868f;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index fde429f2b..8f983da39 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -557,7 +557,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block, INITIALIZE_PATH(path); int pos_in_item; struct cpu_key key; - struct buffer_head * bh, * unbh = 0; + struct buffer_head * bh, * unbh = NULL; struct item_head * ih, tmp_ih; __u32 * item; int done; @@ -1114,9 +1114,9 @@ static void init_inode (struct inode * inode, struct path * path) REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd ); sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode ); } - inode->i_uid = INOXID_UID(uid, gid); - inode->i_gid = INOXID_GID(uid, gid); - inode->i_xid = INOXID_XID(uid, gid, 0); + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, 0); pathrelse (path); if (S_ISREG (inode->i_mode)) { @@ -1141,8 +1141,8 @@ static void init_inode (struct inode * inode, struct path * path) static void inode2sd (void * sd, struct inode * inode, loff_t size) { struct stat_data * sd_v2 = (struct stat_data *)sd; - uid_t uid = XIDINO_UID(inode->i_uid, inode->i_xid); - gid_t gid = XIDINO_GID(inode->i_gid, inode->i_xid); + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); __u16 flags; set_sd_v2_uid(sd_v2, uid ); @@ -1404,7 +1404,7 @@ struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key if (comp_short_keys (INODE_PKEY (inode), key) || is_bad_inode (inode)) { /* either due to i/o error or a stale NFS handle */ iput (inode); - inode = 0; + inode = NULL; } return inode; } @@ -1568,13 +1568,13 @@ static int reiserfs_new_directory (struct reiserfs_transaction_handle *th, old type (ITEM_VERSION_1). Do not set key (second arg is 0), it is done by reiserfs_new_inode */ if (old_format_only (sb)) { - make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2); + make_le_item_head (ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2); make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid, INODE_PKEY (dir)->k_dir_id, INODE_PKEY (dir)->k_objectid ); } else { - make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2); + make_le_item_head (ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2); make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid, INODE_PKEY (dir)->k_dir_id, @@ -1616,7 +1616,7 @@ static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th, le32_to_cpu (ih->ih_key.k_objectid), 1, TYPE_DIRECT, 3/*key length*/); - make_le_item_head (ih, 0, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/); + make_le_item_head (ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/); /* look for place in the tree for new item */ retval = search_item (sb, &key, path); @@ -1670,7 +1670,7 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th, sb = dir->i_sb; /* item head of new item */ - ih.ih_key.k_dir_id = INODE_PKEY (dir)->k_objectid; + ih.ih_key.k_dir_id = reiserfs_choose_packing(dir); ih.ih_key.k_objectid = cpu_to_le32 (reiserfs_get_unused_objectid (th)); if (!ih.ih_key.k_objectid) { err = -ENOMEM; @@ -1711,7 +1711,7 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th, REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; - REISERFS_I(inode)->i_jl = 0; + REISERFS_I(inode)->i_jl = NULL; REISERFS_I(inode)->i_attrs = REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode ); @@ -1720,9 +1720,9 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th, init_rwsem (&REISERFS_I(inode)->xattr_sem); if (old_format_only (sb)) - make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT); + make_le_item_head (&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT); else - make_le_item_head (&ih, 0, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); + make_le_item_head (&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); /* key to search for correct place for new stat data */ _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id), @@ -1739,7 +1739,6 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th, err = -EEXIST; goto out_bad_inode; } - if (old_format_only (sb)) { if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) { pathrelse (&path_to_key); @@ -2158,6 +2157,11 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control struct buffer_head *head, *bh; int partial = 0 ; int nr = 0; + int checked = PageChecked(page); + struct reiserfs_transaction_handle th; + struct super_block *s = inode->i_sb; + int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize; + th.t_trans_id = 0; /* The page dirty bit is cleared before writepage is called, which * means we have to tell create_empty_buffers to make dirty buffers @@ -2165,7 +2169,7 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control * in the BH_Uptodate is just a sanity check. */ if (!page_has_buffers(page)) { - create_empty_buffers(page, inode->i_sb->s_blocksize, + create_empty_buffers(page, s->s_blocksize, (1 << BH_Dirty) | (1 << BH_Uptodate)); } head = page_buffers(page) ; @@ -2189,10 +2193,10 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control kunmap_atomic(kaddr, KM_USER0) ; } bh = head ; - block = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits) ; + block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ; /* first map all the buffers, logging any direct items we find */ do { - if (buffer_dirty(bh) && (!buffer_mapped(bh) || + if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) || (buffer_mapped(bh) && bh->b_blocknr == 0))) { /* not mapped yet, or it points to a direct item, search * the btree for the mapping info, and log any direct @@ -2206,6 +2210,18 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control block++; } while(bh != head) ; + /* + * we start the transaction after map_block_for_writepage, + * because it can create holes in the file (an unbounded operation). + * starting it here, we can make a reliable estimate for how many + * blocks we're going to log + */ + if (checked) { + ClearPageChecked(page); + reiserfs_write_lock(s); + journal_begin(&th, s, bh_per_page + 1); + reiserfs_update_inode_transaction(inode); + } /* now go through and lock any dirty buffers on the page */ do { get_bh(bh); @@ -2214,6 +2230,11 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control if (buffer_mapped(bh) && bh->b_blocknr == 0) continue; + if (checked) { + reiserfs_prepare_for_journal(s, bh, 1); + journal_mark_dirty(&th, s, bh); + continue; + } /* from this point on, we know the buffer is mapped to a * real block and not a direct item */ @@ -2232,6 +2253,10 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control } } while((bh = bh->b_this_page) != head); + if (checked) { + journal_end(&th, s, bh_per_page + 1); + reiserfs_write_unlock(s); + } BUG_ON(PageWriteback(page)); set_page_writeback(page); unlock_page(page); @@ -2507,17 +2532,15 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) /* the page is locked, and the only places that log a data buffer * also lock the page. */ -#if 0 if (reiserfs_file_data_log(inode)) { - /* very conservative, leave the buffer pinned if anyone might need it. - ** this should be changed to drop the buffer if it is only in the - ** current transaction - */ + /* + * very conservative, leave the buffer pinned if + * anyone might need it. + */ if (buffer_journaled(bh) || buffer_journal_dirty(bh)) { ret = 0 ; } } else -#endif if (buffer_dirty(bh) || buffer_locked(bh)) { struct reiserfs_journal_list *jl; struct reiserfs_jh *jh = bh->b_private; @@ -2555,6 +2578,10 @@ static int reiserfs_invalidatepage(struct page *page, unsigned long offset) int ret = 1; BUG_ON(!PageLocked(page)); + + if (offset == 0) + ClearPageChecked(page); + if (!page_has_buffers(page)) goto out; @@ -2588,6 +2615,15 @@ out: return ret; } +static int reiserfs_set_page_dirty(struct page *page) { + struct inode *inode = page->mapping->host; + if (reiserfs_file_data_log(inode)) { + SetPageChecked(page); + return __set_page_dirty_nobuffers(page); + } + return __set_page_dirty_buffers(page); +} + /* * Returns 1 if the page's buffers were dropped. The page is locked. * @@ -2605,6 +2641,7 @@ static int reiserfs_releasepage(struct page *page, int unused_gfp_flags) struct buffer_head *bh ; int ret = 1 ; + WARN_ON(PageChecked(page)); spin_lock(&j->j_dirty_buffers_lock) ; head = page_buffers(page) ; bh = head ; @@ -2709,7 +2746,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; } if (!error) - inode_setattr(inode, attr) ; + error = inode_setattr(inode, attr) ; } @@ -2735,5 +2772,6 @@ struct address_space_operations reiserfs_address_space_operations = { .prepare_write = reiserfs_prepare_write, .commit_write = reiserfs_commit_write, .bmap = reiserfs_aop_bmap, - .direct_IO = reiserfs_direct_IO + .direct_IO = reiserfs_direct_IO, + .set_page_dirty = reiserfs_set_page_dirty, } ;