X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjfs%2Finode.c;h=ea8d961686004cc6b0227ad9efcd791e554c1f05;hb=refs%2Fheads%2Fvserver;hp=69e397ef94f6ed91f37d6d8fcd81e36209dc3d0a;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 69e397ef9..ea8d96168 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -22,7 +22,9 @@ #include #include #include +#include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_filsys.h" #include "jfs_imap.h" #include "jfs_extent.h" @@ -30,17 +32,9 @@ #include "jfs_debug.h" -extern struct inode_operations jfs_dir_inode_operations; -extern struct inode_operations jfs_file_inode_operations; -extern struct inode_operations jfs_symlink_inode_operations; -extern struct file_operations jfs_dir_operations; -extern struct file_operations jfs_file_operations; -struct address_space_operations jfs_aops; -extern int freeZeroLink(struct inode *); - void jfs_read_inode(struct inode *inode) { - if (diRead(inode)) { + if (diRead(inode)) { make_bad_inode(inode); return; } @@ -52,8 +46,6 @@ void jfs_read_inode(struct inode *inode) } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &jfs_dir_inode_operations; inode->i_fop = &jfs_dir_operations; - inode->i_mapping->a_ops = &jfs_aops; - mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); } else if (S_ISLNK(inode->i_mode)) { if (inode->i_size >= IDATASIZE) { inode->i_op = &page_symlink_inode_operations; @@ -64,6 +56,7 @@ void jfs_read_inode(struct inode *inode) inode->i_op = &jfs_file_inode_operations; init_special_inode(inode, inode->i_mode, inode->i_rdev); } + jfs_set_inode_flags(inode); } /* @@ -98,16 +91,16 @@ int jfs_commit_inode(struct inode *inode, int wait) } tid = txBegin(inode->i_sb, COMMIT_INODE); - down(&JFS_IP(inode)->commit_sem); + mutex_lock(&JFS_IP(inode)->commit_mutex); /* - * Retest inode state after taking commit_sem + * Retest inode state after taking commit_mutex */ if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode)) rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0); txEnd(tid); - up(&JFS_IP(inode)->commit_sem); + mutex_unlock(&JFS_IP(inode)->commit_mutex); return rc; } @@ -137,17 +130,23 @@ void jfs_delete_inode(struct inode *inode) { jfs_info("In jfs_delete_inode, inode = 0x%p", inode); - if (test_cflag(COMMIT_Freewmap, inode)) - freeZeroLink(inode); + if (!is_bad_inode(inode) && + (JFS_IP(inode)->fileset == FILESYSTEM_I)) { + truncate_inode_pages(&inode->i_data, 0); - diFree(inode); + if (test_cflag(COMMIT_Freewmap, inode)) + jfs_free_zero_link(inode); - /* - * Free the inode from the quota allocation. - */ - DQUOT_INIT(inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); + diFree(inode); + + /* + * Free the inode from the quota allocation. + */ + DQUOT_INIT(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); + DLIMIT_FREE_INODE(inode); + } clear_inode(inode); } @@ -171,46 +170,27 @@ void jfs_dirty_inode(struct inode *inode) set_cflag(COMMIT_Dirty, inode); } -static int -jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, - struct buffer_head *bh_result, int create) +int jfs_get_block(struct inode *ip, sector_t lblock, + struct buffer_head *bh_result, int create) { s64 lblock64 = lblock; - int no_size_check = 0; int rc = 0; - int take_locks; xad_t xad; s64 xaddr; int xflag; - s32 xlen; + s32 xlen = bh_result->b_size >> ip->i_blkbits; - /* - * If this is a special inode (imap, dmap) or directory, - * the lock should already be taken - */ - take_locks = ((JFS_IP(ip)->fileset != AGGREGATE_I) && - !S_ISDIR(ip->i_mode)); /* * Take appropriate lock on inode */ - if (take_locks) { - if (create) - IWRITE_LOCK(ip); - else - IREAD_LOCK(ip); - } - - /* - * A directory's "data" is the inode index table, but i_size is the - * size of the d-tree, so don't check the offset against i_size - */ - if (S_ISDIR(ip->i_mode)) - no_size_check = 1; - - if ((no_size_check || - ((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) && - (xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, no_size_check) - == 0) && xlen) { + if (create) + IWRITE_LOCK(ip); + else + IREAD_LOCK(ip); + + if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && + (!xtLookup(ip, lblock64, xlen, &xflag, &xaddr, &xlen, 0)) && + xaddr) { if (xflag & XAD_NOTRECORDED) { if (!create) /* @@ -249,7 +229,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, #ifdef _JFS_4K if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) goto unlock; - rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE); + rc = extAlloc(ip, xlen, lblock64, &xad, false); if (rc) goto unlock; @@ -269,24 +249,16 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, /* * Release lock on inode */ - if (take_locks) { - if (create) - IWRITE_UNLOCK(ip); - else - IREAD_UNLOCK(ip); - } + if (create) + IWRITE_UNLOCK(ip); + else + IREAD_UNLOCK(ip); return rc; } -static int jfs_get_block(struct inode *ip, sector_t lblock, - struct buffer_head *bh_result, int create) -{ - return jfs_get_blocks(ip, lblock, 1, bh_result, create); -} - static int jfs_writepage(struct page *page, struct writeback_control *wbc) { - return block_write_full_page(page, jfs_get_block, wbc); + return nobh_writepage(page, jfs_get_block, wbc); } static int jfs_writepages(struct address_space *mapping, @@ -324,10 +296,10 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb, struct inode *inode = file->f_mapping->host; return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, - offset, nr_segs, jfs_get_blocks, NULL); + offset, nr_segs, jfs_get_block, NULL); } -struct address_space_operations jfs_aops = { +const struct address_space_operations jfs_aops = { .readpage = jfs_readpage, .readpages = jfs_readpages, .writepage = jfs_writepage, @@ -359,18 +331,18 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length) tid = txBegin(ip->i_sb, 0); /* - * The commit_sem cannot be taken before txBegin. + * The commit_mutex cannot be taken before txBegin. * txBegin may block and there is a chance the inode * could be marked dirty and need to be committed * before txBegin unblocks */ - down(&JFS_IP(ip)->commit_sem); + mutex_lock(&JFS_IP(ip)->commit_mutex); newsize = xtTruncate(tid, ip, length, COMMIT_TRUNCATE | COMMIT_PWMAP); if (newsize < 0) { txEnd(tid); - up(&JFS_IP(ip)->commit_sem); + mutex_unlock(&JFS_IP(ip)->commit_mutex); break; } @@ -379,7 +351,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length) txCommit(tid, 1, &ip, 0); txEnd(tid); - up(&JFS_IP(ip)->commit_sem); + mutex_unlock(&JFS_IP(ip)->commit_mutex); } while (newsize > length); /* Truncate isn't always atomic */ }