diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/befs/linuxvfs.c | 11 | ||||
| -rw-r--r-- | fs/jfs/inode.c | 16 | ||||
| -rw-r--r-- | fs/jfs/jfs_inode.h | 1 | ||||
| -rw-r--r-- | fs/jfs/super.c | 118 | ||||
| -rw-r--r-- | fs/lockd/svclock.c | 12 | ||||
| -rw-r--r-- | fs/nfs/namespace.c | 4 | ||||
| -rw-r--r-- | fs/nfs/read.c | 2 | ||||
| -rw-r--r-- | fs/nfs/write.c | 2 | ||||
| -rw-r--r-- | fs/reiserfs/file.c | 2 | ||||
| -rw-r--r-- | fs/reiserfs/inode.c | 26 | ||||
| -rw-r--r-- | fs/reiserfs/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/udf/ialloc.c | 11 | ||||
| -rw-r--r-- | fs/ufs/balloc.c | 2 | ||||
| -rw-r--r-- | fs/ufs/util.c | 17 | ||||
| -rw-r--r-- | fs/xfs/xfs_alloc.c | 103 |
15 files changed, 223 insertions, 106 deletions
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index fcaeead9696b..50cfca5c7efd 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
| @@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, const char *in, | |||
| 512 | wchar_t uni; | 512 | wchar_t uni; |
| 513 | int unilen, utflen; | 513 | int unilen, utflen; |
| 514 | char *result; | 514 | char *result; |
| 515 | int maxlen = in_len; /* The utf8->nls conversion can't make more chars */ | 515 | /* The utf8->nls conversion won't make the final nls string bigger |
| 516 | * than the utf one, but if the string is pure ascii they'll have the | ||
| 517 | * same width and an extra char is needed to save the additional \0 | ||
| 518 | */ | ||
| 519 | int maxlen = in_len + 1; | ||
| 516 | 520 | ||
| 517 | befs_debug(sb, "---> utf2nls()"); | 521 | befs_debug(sb, "---> utf2nls()"); |
| 518 | 522 | ||
| @@ -588,7 +592,10 @@ befs_nls2utf(struct super_block *sb, const char *in, | |||
| 588 | wchar_t uni; | 592 | wchar_t uni; |
| 589 | int unilen, utflen; | 593 | int unilen, utflen; |
| 590 | char *result; | 594 | char *result; |
| 591 | int maxlen = 3 * in_len; | 595 | /* There're nls characters that will translate to 3-chars-wide UTF-8 |
| 596 | * characters, a additional byte is needed to save the final \0 | ||
| 597 | * in special cases */ | ||
| 598 | int maxlen = (3 * in_len) + 1; | ||
| 592 | 599 | ||
| 593 | befs_debug(sb, "---> nls2utf()\n"); | 600 | befs_debug(sb, "---> nls2utf()\n"); |
| 594 | 601 | ||
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 43e3f566aad6..a223cf4faa9b 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
| @@ -168,16 +168,15 @@ void jfs_dirty_inode(struct inode *inode) | |||
| 168 | set_cflag(COMMIT_Dirty, inode); | 168 | set_cflag(COMMIT_Dirty, inode); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static int | 171 | int jfs_get_block(struct inode *ip, sector_t lblock, |
| 172 | jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | 172 | struct buffer_head *bh_result, int create) |
| 173 | struct buffer_head *bh_result, int create) | ||
| 174 | { | 173 | { |
| 175 | s64 lblock64 = lblock; | 174 | s64 lblock64 = lblock; |
| 176 | int rc = 0; | 175 | int rc = 0; |
| 177 | xad_t xad; | 176 | xad_t xad; |
| 178 | s64 xaddr; | 177 | s64 xaddr; |
| 179 | int xflag; | 178 | int xflag; |
| 180 | s32 xlen = max_blocks; | 179 | s32 xlen = bh_result->b_size >> ip->i_blkbits; |
| 181 | 180 | ||
| 182 | /* | 181 | /* |
| 183 | * Take appropriate lock on inode | 182 | * Take appropriate lock on inode |
| @@ -188,7 +187,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
| 188 | IREAD_LOCK(ip); | 187 | IREAD_LOCK(ip); |
| 189 | 188 | ||
| 190 | if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && | 189 | if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && |
| 191 | (!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) && | 190 | (!xtLookup(ip, lblock64, xlen, &xflag, &xaddr, &xlen, 0)) && |
| 192 | xaddr) { | 191 | xaddr) { |
| 193 | if (xflag & XAD_NOTRECORDED) { | 192 | if (xflag & XAD_NOTRECORDED) { |
| 194 | if (!create) | 193 | if (!create) |
| @@ -255,13 +254,6 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
| 255 | return rc; | 254 | return rc; |
| 256 | } | 255 | } |
| 257 | 256 | ||
| 258 | static int jfs_get_block(struct inode *ip, sector_t lblock, | ||
| 259 | struct buffer_head *bh_result, int create) | ||
| 260 | { | ||
| 261 | return jfs_get_blocks(ip, lblock, bh_result->b_size >> ip->i_blkbits, | ||
| 262 | bh_result, create); | ||
| 263 | } | ||
| 264 | |||
| 265 | static int jfs_writepage(struct page *page, struct writeback_control *wbc) | 257 | static int jfs_writepage(struct page *page, struct writeback_control *wbc) |
| 266 | { | 258 | { |
| 267 | return nobh_writepage(page, jfs_get_block, wbc); | 259 | return nobh_writepage(page, jfs_get_block, wbc); |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index b5c7da6190dc..1fc48df670c8 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
| @@ -32,6 +32,7 @@ extern void jfs_truncate_nolock(struct inode *, loff_t); | |||
| 32 | extern void jfs_free_zero_link(struct inode *); | 32 | extern void jfs_free_zero_link(struct inode *); |
| 33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); | 33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); |
| 34 | extern void jfs_set_inode_flags(struct inode *); | 34 | extern void jfs_set_inode_flags(struct inode *); |
| 35 | extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); | ||
| 35 | 36 | ||
| 36 | extern const struct address_space_operations jfs_aops; | 37 | extern const struct address_space_operations jfs_aops; |
| 37 | extern struct inode_operations jfs_dir_inode_operations; | 38 | extern struct inode_operations jfs_dir_inode_operations; |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 4f6cfebc82db..143bcd1d5eaa 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
| 27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
| 28 | #include <linux/posix_acl.h> | 28 | #include <linux/posix_acl.h> |
| 29 | #include <linux/buffer_head.h> | ||
| 29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
| 30 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
| 31 | 32 | ||
| @@ -298,7 +299,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, | |||
| 298 | break; | 299 | break; |
| 299 | } | 300 | } |
| 300 | 301 | ||
| 301 | #if defined(CONFIG_QUOTA) | 302 | #ifdef CONFIG_QUOTA |
| 302 | case Opt_quota: | 303 | case Opt_quota: |
| 303 | case Opt_usrquota: | 304 | case Opt_usrquota: |
| 304 | *flag |= JFS_USRQUOTA; | 305 | *flag |= JFS_USRQUOTA; |
| @@ -597,7 +598,7 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 597 | if (sbi->flag & JFS_NOINTEGRITY) | 598 | if (sbi->flag & JFS_NOINTEGRITY) |
| 598 | seq_puts(seq, ",nointegrity"); | 599 | seq_puts(seq, ",nointegrity"); |
| 599 | 600 | ||
| 600 | #if defined(CONFIG_QUOTA) | 601 | #ifdef CONFIG_QUOTA |
| 601 | if (sbi->flag & JFS_USRQUOTA) | 602 | if (sbi->flag & JFS_USRQUOTA) |
| 602 | seq_puts(seq, ",usrquota"); | 603 | seq_puts(seq, ",usrquota"); |
| 603 | 604 | ||
| @@ -608,6 +609,113 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 608 | return 0; | 609 | return 0; |
| 609 | } | 610 | } |
| 610 | 611 | ||
| 612 | #ifdef CONFIG_QUOTA | ||
| 613 | |||
| 614 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | ||
| 615 | * acquiring the locks... As quota files are never truncated and quota code | ||
| 616 | * itself serializes the operations (and noone else should touch the files) | ||
| 617 | * we don't have to be afraid of races */ | ||
| 618 | static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data, | ||
| 619 | size_t len, loff_t off) | ||
| 620 | { | ||
| 621 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
| 622 | sector_t blk = off >> sb->s_blocksize_bits; | ||
| 623 | int err = 0; | ||
| 624 | int offset = off & (sb->s_blocksize - 1); | ||
| 625 | int tocopy; | ||
| 626 | size_t toread; | ||
| 627 | struct buffer_head tmp_bh; | ||
| 628 | struct buffer_head *bh; | ||
| 629 | loff_t i_size = i_size_read(inode); | ||
| 630 | |||
| 631 | if (off > i_size) | ||
| 632 | return 0; | ||
| 633 | if (off+len > i_size) | ||
| 634 | len = i_size-off; | ||
| 635 | toread = len; | ||
| 636 | while (toread > 0) { | ||
| 637 | tocopy = sb->s_blocksize - offset < toread ? | ||
| 638 | sb->s_blocksize - offset : toread; | ||
| 639 | |||
| 640 | tmp_bh.b_state = 0; | ||
| 641 | tmp_bh.b_size = 1 << inode->i_blkbits; | ||
| 642 | err = jfs_get_block(inode, blk, &tmp_bh, 0); | ||
| 643 | if (err) | ||
| 644 | return err; | ||
| 645 | if (!buffer_mapped(&tmp_bh)) /* A hole? */ | ||
| 646 | memset(data, 0, tocopy); | ||
| 647 | else { | ||
| 648 | bh = sb_bread(sb, tmp_bh.b_blocknr); | ||
| 649 | if (!bh) | ||
| 650 | return -EIO; | ||
| 651 | memcpy(data, bh->b_data+offset, tocopy); | ||
| 652 | brelse(bh); | ||
| 653 | } | ||
| 654 | offset = 0; | ||
| 655 | toread -= tocopy; | ||
| 656 | data += tocopy; | ||
| 657 | blk++; | ||
| 658 | } | ||
| 659 | return len; | ||
| 660 | } | ||
| 661 | |||
| 662 | /* Write to quotafile */ | ||
| 663 | static ssize_t jfs_quota_write(struct super_block *sb, int type, | ||
| 664 | const char *data, size_t len, loff_t off) | ||
| 665 | { | ||
| 666 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
| 667 | sector_t blk = off >> sb->s_blocksize_bits; | ||
| 668 | int err = 0; | ||
| 669 | int offset = off & (sb->s_blocksize - 1); | ||
| 670 | int tocopy; | ||
| 671 | size_t towrite = len; | ||
| 672 | struct buffer_head tmp_bh; | ||
| 673 | struct buffer_head *bh; | ||
| 674 | |||
| 675 | mutex_lock(&inode->i_mutex); | ||
| 676 | while (towrite > 0) { | ||
| 677 | tocopy = sb->s_blocksize - offset < towrite ? | ||
| 678 | sb->s_blocksize - offset : towrite; | ||
| 679 | |||
| 680 | tmp_bh.b_state = 0; | ||
| 681 | tmp_bh.b_size = 1 << inode->i_blkbits; | ||
| 682 | err = jfs_get_block(inode, blk, &tmp_bh, 1); | ||
| 683 | if (err) | ||
| 684 | goto out; | ||
| 685 | if (offset || tocopy != sb->s_blocksize) | ||
| 686 | bh = sb_bread(sb, tmp_bh.b_blocknr); | ||
| 687 | else | ||
| 688 | bh = sb_getblk(sb, tmp_bh.b_blocknr); | ||
| 689 | if (!bh) { | ||
| 690 | err = -EIO; | ||
| 691 | goto out; | ||
| 692 | } | ||
| 693 | lock_buffer(bh); | ||
| 694 | memcpy(bh->b_data+offset, data, tocopy); | ||
| 695 | flush_dcache_page(bh->b_page); | ||
| 696 | set_buffer_uptodate(bh); | ||
| 697 | mark_buffer_dirty(bh); | ||
| 698 | unlock_buffer(bh); | ||
| 699 | brelse(bh); | ||
| 700 | offset = 0; | ||
| 701 | towrite -= tocopy; | ||
| 702 | data += tocopy; | ||
| 703 | blk++; | ||
| 704 | } | ||
| 705 | out: | ||
| 706 | if (len == towrite) | ||
| 707 | return err; | ||
| 708 | if (inode->i_size < off+len-towrite) | ||
| 709 | i_size_write(inode, off+len-towrite); | ||
| 710 | inode->i_version++; | ||
| 711 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 712 | mark_inode_dirty(inode); | ||
| 713 | mutex_unlock(&inode->i_mutex); | ||
| 714 | return len - towrite; | ||
| 715 | } | ||
| 716 | |||
| 717 | #endif | ||
| 718 | |||
| 611 | static struct super_operations jfs_super_operations = { | 719 | static struct super_operations jfs_super_operations = { |
| 612 | .alloc_inode = jfs_alloc_inode, | 720 | .alloc_inode = jfs_alloc_inode, |
| 613 | .destroy_inode = jfs_destroy_inode, | 721 | .destroy_inode = jfs_destroy_inode, |
| @@ -621,7 +729,11 @@ static struct super_operations jfs_super_operations = { | |||
| 621 | .unlockfs = jfs_unlockfs, | 729 | .unlockfs = jfs_unlockfs, |
| 622 | .statfs = jfs_statfs, | 730 | .statfs = jfs_statfs, |
| 623 | .remount_fs = jfs_remount, | 731 | .remount_fs = jfs_remount, |
| 624 | .show_options = jfs_show_options | 732 | .show_options = jfs_show_options, |
| 733 | #ifdef CONFIG_QUOTA | ||
| 734 | .quota_read = jfs_quota_read, | ||
| 735 | .quota_write = jfs_quota_write, | ||
| 736 | #endif | ||
| 625 | }; | 737 | }; |
| 626 | 738 | ||
| 627 | static struct export_operations jfs_export_operations = { | 739 | static struct export_operations jfs_export_operations = { |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index baf5ae513481..c9d419703cf3 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
| @@ -638,9 +638,6 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) | |||
| 638 | if (task->tk_status < 0) { | 638 | if (task->tk_status < 0) { |
| 639 | /* RPC error: Re-insert for retransmission */ | 639 | /* RPC error: Re-insert for retransmission */ |
| 640 | timeout = 10 * HZ; | 640 | timeout = 10 * HZ; |
| 641 | } else if (block->b_done) { | ||
| 642 | /* Block already removed, kill it for real */ | ||
| 643 | timeout = 0; | ||
| 644 | } else { | 641 | } else { |
| 645 | /* Call was successful, now wait for client callback */ | 642 | /* Call was successful, now wait for client callback */ |
| 646 | timeout = 60 * HZ; | 643 | timeout = 60 * HZ; |
| @@ -709,13 +706,10 @@ nlmsvc_retry_blocked(void) | |||
| 709 | break; | 706 | break; |
| 710 | if (time_after(block->b_when,jiffies)) | 707 | if (time_after(block->b_when,jiffies)) |
| 711 | break; | 708 | break; |
| 712 | dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n", | 709 | dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", |
| 713 | block, block->b_when, block->b_done); | 710 | block, block->b_when); |
| 714 | kref_get(&block->b_count); | 711 | kref_get(&block->b_count); |
| 715 | if (block->b_done) | 712 | nlmsvc_grant_blocked(block); |
| 716 | nlmsvc_unlink_block(block); | ||
| 717 | else | ||
| 718 | nlmsvc_grant_blocked(block); | ||
| 719 | nlmsvc_release_block(block); | 713 | nlmsvc_release_block(block); |
| 720 | } | 714 | } |
| 721 | 715 | ||
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 19b98ca468eb..86b3169c8cac 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
| @@ -51,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry, | |||
| 51 | namelen = dentry->d_name.len; | 51 | namelen = dentry->d_name.len; |
| 52 | buflen -= namelen + 1; | 52 | buflen -= namelen + 1; |
| 53 | if (buflen < 0) | 53 | if (buflen < 0) |
| 54 | goto Elong; | 54 | goto Elong_unlock; |
| 55 | end -= namelen; | 55 | end -= namelen; |
| 56 | memcpy(end, dentry->d_name.name, namelen); | 56 | memcpy(end, dentry->d_name.name, namelen); |
| 57 | *--end = '/'; | 57 | *--end = '/'; |
| @@ -68,6 +68,8 @@ char *nfs_path(const char *base, const struct dentry *dentry, | |||
| 68 | end -= namelen; | 68 | end -= namelen; |
| 69 | memcpy(end, base, namelen); | 69 | memcpy(end, base, namelen); |
| 70 | return end; | 70 | return end; |
| 71 | Elong_unlock: | ||
| 72 | spin_unlock(&dcache_lock); | ||
| 71 | Elong: | 73 | Elong: |
| 72 | return ERR_PTR(-ENAMETOOLONG); | 74 | return ERR_PTR(-ENAMETOOLONG); |
| 73 | } | 75 | } |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 52bf634260a1..65c0c5b32351 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
| @@ -63,7 +63,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) | |||
| 63 | return p; | 63 | return p; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | void nfs_readdata_free(struct nfs_read_data *p) | 66 | static void nfs_readdata_free(struct nfs_read_data *p) |
| 67 | { | 67 | { |
| 68 | if (p && (p->pagevec != &p->page_array[0])) | 68 | if (p && (p->pagevec != &p->page_array[0])) |
| 69 | kfree(p->pagevec); | 69 | kfree(p->pagevec); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 86bac6a5008e..50774991f8d5 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -137,7 +137,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | |||
| 137 | return p; | 137 | return p; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | void nfs_writedata_free(struct nfs_write_data *p) | 140 | static void nfs_writedata_free(struct nfs_write_data *p) |
| 141 | { | 141 | { |
| 142 | if (p && (p->pagevec != &p->page_array[0])) | 142 | if (p && (p->pagevec != &p->page_array[0])) |
| 143 | kfree(p->pagevec); | 143 | kfree(p->pagevec); |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index f318b58510fd..1627edd50810 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
| @@ -48,8 +48,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
| 48 | return 0; | 48 | return 0; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | reiserfs_write_lock(inode->i_sb); | ||
| 52 | mutex_lock(&inode->i_mutex); | 51 | mutex_lock(&inode->i_mutex); |
| 52 | reiserfs_write_lock(inode->i_sb); | ||
| 53 | /* freeing preallocation only involves relogging blocks that | 53 | /* freeing preallocation only involves relogging blocks that |
| 54 | * are already in the current transaction. preallocation gets | 54 | * are already in the current transaction. preallocation gets |
| 55 | * freed at the end of each transaction, so it is impossible for | 55 | * freed at the end of each transaction, so it is impossible for |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 12dfdcfbee3d..52f1e2136546 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -39,14 +39,10 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 39 | 39 | ||
| 40 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 40 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
| 41 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 41 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
| 42 | mutex_lock(&inode->i_mutex); | ||
| 43 | |||
| 44 | reiserfs_delete_xattrs(inode); | 42 | reiserfs_delete_xattrs(inode); |
| 45 | 43 | ||
| 46 | if (journal_begin(&th, inode->i_sb, jbegin_count)) { | 44 | if (journal_begin(&th, inode->i_sb, jbegin_count)) |
| 47 | mutex_unlock(&inode->i_mutex); | ||
| 48 | goto out; | 45 | goto out; |
| 49 | } | ||
| 50 | reiserfs_update_inode_transaction(inode); | 46 | reiserfs_update_inode_transaction(inode); |
| 51 | 47 | ||
| 52 | err = reiserfs_delete_object(&th, inode); | 48 | err = reiserfs_delete_object(&th, inode); |
| @@ -57,12 +53,8 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 57 | if (!err) | 53 | if (!err) |
| 58 | DQUOT_FREE_INODE(inode); | 54 | DQUOT_FREE_INODE(inode); |
| 59 | 55 | ||
| 60 | if (journal_end(&th, inode->i_sb, jbegin_count)) { | 56 | if (journal_end(&th, inode->i_sb, jbegin_count)) |
| 61 | mutex_unlock(&inode->i_mutex); | ||
| 62 | goto out; | 57 | goto out; |
| 63 | } | ||
| 64 | |||
| 65 | mutex_unlock(&inode->i_mutex); | ||
| 66 | 58 | ||
| 67 | /* check return value from reiserfs_delete_object after | 59 | /* check return value from reiserfs_delete_object after |
| 68 | * ending the transaction | 60 | * ending the transaction |
| @@ -2348,6 +2340,7 @@ static int reiserfs_write_full_page(struct page *page, | |||
| 2348 | unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT; | 2340 | unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT; |
| 2349 | int error = 0; | 2341 | int error = 0; |
| 2350 | unsigned long block; | 2342 | unsigned long block; |
| 2343 | sector_t last_block; | ||
| 2351 | struct buffer_head *head, *bh; | 2344 | struct buffer_head *head, *bh; |
| 2352 | int partial = 0; | 2345 | int partial = 0; |
| 2353 | int nr = 0; | 2346 | int nr = 0; |
| @@ -2395,10 +2388,19 @@ static int reiserfs_write_full_page(struct page *page, | |||
| 2395 | } | 2388 | } |
| 2396 | bh = head; | 2389 | bh = head; |
| 2397 | block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits); | 2390 | block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits); |
| 2391 | last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; | ||
| 2398 | /* first map all the buffers, logging any direct items we find */ | 2392 | /* first map all the buffers, logging any direct items we find */ |
| 2399 | do { | 2393 | do { |
| 2400 | if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) || | 2394 | if (block > last_block) { |
| 2401 | (buffer_mapped(bh) | 2395 | /* |
| 2396 | * This can happen when the block size is less than | ||
| 2397 | * the page size. The corresponding bytes in the page | ||
| 2398 | * were zero filled above | ||
| 2399 | */ | ||
| 2400 | clear_buffer_dirty(bh); | ||
| 2401 | set_buffer_uptodate(bh); | ||
| 2402 | } else if ((checked || buffer_dirty(bh)) && | ||
| 2403 | (!buffer_mapped(bh) || (buffer_mapped(bh) | ||
| 2402 | && bh->b_blocknr == | 2404 | && bh->b_blocknr == |
| 2403 | 0))) { | 2405 | 0))) { |
| 2404 | /* not mapped yet, or it points to a direct item, search | 2406 | /* not mapped yet, or it points to a direct item, search |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 745c88100895..a986b5e1e288 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
| @@ -116,12 +116,12 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
| 116 | if (REISERFS_I(inode)->i_flags & i_nopack_mask) { | 116 | if (REISERFS_I(inode)->i_flags & i_nopack_mask) { |
| 117 | return 0; | 117 | return 0; |
| 118 | } | 118 | } |
| 119 | reiserfs_write_lock(inode->i_sb); | ||
| 120 | 119 | ||
| 121 | /* we need to make sure nobody is changing the file size beneath | 120 | /* we need to make sure nobody is changing the file size beneath |
| 122 | ** us | 121 | ** us |
| 123 | */ | 122 | */ |
| 124 | mutex_lock(&inode->i_mutex); | 123 | mutex_lock(&inode->i_mutex); |
| 124 | reiserfs_write_lock(inode->i_sb); | ||
| 125 | 125 | ||
| 126 | write_from = inode->i_size & (blocksize - 1); | 126 | write_from = inode->i_size & (blocksize - 1); |
| 127 | /* if we are on a block boundary, we are already unpacked. */ | 127 | /* if we are on a block boundary, we are already unpacked. */ |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 3873c672cb4c..33323473e3c4 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
| @@ -75,6 +75,12 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) | |||
| 75 | } | 75 | } |
| 76 | *err = -ENOSPC; | 76 | *err = -ENOSPC; |
| 77 | 77 | ||
| 78 | UDF_I_UNIQUE(inode) = 0; | ||
| 79 | UDF_I_LENEXTENTS(inode) = 0; | ||
| 80 | UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; | ||
| 81 | UDF_I_NEXT_ALLOC_GOAL(inode) = 0; | ||
| 82 | UDF_I_STRAT4096(inode) = 0; | ||
| 83 | |||
| 78 | block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum, | 84 | block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum, |
| 79 | start, err); | 85 | start, err); |
| 80 | if (*err) | 86 | if (*err) |
| @@ -84,11 +90,6 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) | |||
| 84 | } | 90 | } |
| 85 | 91 | ||
| 86 | mutex_lock(&sbi->s_alloc_mutex); | 92 | mutex_lock(&sbi->s_alloc_mutex); |
| 87 | UDF_I_UNIQUE(inode) = 0; | ||
| 88 | UDF_I_LENEXTENTS(inode) = 0; | ||
| 89 | UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; | ||
| 90 | UDF_I_NEXT_ALLOC_GOAL(inode) = 0; | ||
| 91 | UDF_I_STRAT4096(inode) = 0; | ||
| 92 | if (UDF_SB_LVIDBH(sb)) | 93 | if (UDF_SB_LVIDBH(sb)) |
| 93 | { | 94 | { |
| 94 | struct logicalVolHeaderDesc *lvhd; | 95 | struct logicalVolHeaderDesc *lvhd; |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index b01804baa120..b82381475779 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
| @@ -248,7 +248,7 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, | |||
| 248 | 248 | ||
| 249 | if (likely(cur_index != index)) { | 249 | if (likely(cur_index != index)) { |
| 250 | page = ufs_get_locked_page(mapping, index); | 250 | page = ufs_get_locked_page(mapping, index); |
| 251 | if (IS_ERR(page)) | 251 | if (!page || IS_ERR(page)) /* it was truncated or EIO */ |
| 252 | continue; | 252 | continue; |
| 253 | } else | 253 | } else |
| 254 | page = locked_page; | 254 | page = locked_page; |
diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 337cf2c46d10..22f820a9b15c 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c | |||
| @@ -251,12 +251,12 @@ struct page *ufs_get_locked_page(struct address_space *mapping, | |||
| 251 | { | 251 | { |
| 252 | struct page *page; | 252 | struct page *page; |
| 253 | 253 | ||
| 254 | try_again: | ||
| 255 | page = find_lock_page(mapping, index); | 254 | page = find_lock_page(mapping, index); |
| 256 | if (!page) { | 255 | if (!page) { |
| 257 | page = read_cache_page(mapping, index, | 256 | page = read_cache_page(mapping, index, |
| 258 | (filler_t*)mapping->a_ops->readpage, | 257 | (filler_t*)mapping->a_ops->readpage, |
| 259 | NULL); | 258 | NULL); |
| 259 | |||
| 260 | if (IS_ERR(page)) { | 260 | if (IS_ERR(page)) { |
| 261 | printk(KERN_ERR "ufs_change_blocknr: " | 261 | printk(KERN_ERR "ufs_change_blocknr: " |
| 262 | "read_cache_page error: ino %lu, index: %lu\n", | 262 | "read_cache_page error: ino %lu, index: %lu\n", |
| @@ -266,6 +266,14 @@ try_again: | |||
| 266 | 266 | ||
| 267 | lock_page(page); | 267 | lock_page(page); |
| 268 | 268 | ||
| 269 | if (unlikely(page->mapping == NULL)) { | ||
| 270 | /* Truncate got there first */ | ||
| 271 | unlock_page(page); | ||
| 272 | page_cache_release(page); | ||
| 273 | page = NULL; | ||
| 274 | goto out; | ||
| 275 | } | ||
| 276 | |||
| 269 | if (!PageUptodate(page) || PageError(page)) { | 277 | if (!PageUptodate(page) || PageError(page)) { |
| 270 | unlock_page(page); | 278 | unlock_page(page); |
| 271 | page_cache_release(page); | 279 | page_cache_release(page); |
| @@ -275,15 +283,8 @@ try_again: | |||
| 275 | mapping->host->i_ino, index); | 283 | mapping->host->i_ino, index); |
| 276 | 284 | ||
| 277 | page = ERR_PTR(-EIO); | 285 | page = ERR_PTR(-EIO); |
| 278 | goto out; | ||
| 279 | } | 286 | } |
| 280 | } | 287 | } |
| 281 | |||
| 282 | if (unlikely(!page->mapping || !page_has_buffers(page))) { | ||
| 283 | unlock_page(page); | ||
| 284 | page_cache_release(page); | ||
| 285 | goto try_again;/*we really need these buffers*/ | ||
| 286 | } | ||
| 287 | out: | 288 | out: |
| 288 | return page; | 289 | return page; |
| 289 | } | 290 | } |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index eef6763f3a67..d2bbcd882a69 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
| @@ -1835,40 +1835,47 @@ xfs_alloc_fix_freelist( | |||
| 1835 | &agbp))) | 1835 | &agbp))) |
| 1836 | return error; | 1836 | return error; |
| 1837 | if (!pag->pagf_init) { | 1837 | if (!pag->pagf_init) { |
| 1838 | ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); | ||
| 1839 | ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); | ||
| 1838 | args->agbp = NULL; | 1840 | args->agbp = NULL; |
| 1839 | return 0; | 1841 | return 0; |
| 1840 | } | 1842 | } |
| 1841 | } else | 1843 | } else |
| 1842 | agbp = NULL; | 1844 | agbp = NULL; |
| 1843 | 1845 | ||
| 1844 | /* If this is a metadata preferred pag and we are user data | 1846 | /* |
| 1847 | * If this is a metadata preferred pag and we are user data | ||
| 1845 | * then try somewhere else if we are not being asked to | 1848 | * then try somewhere else if we are not being asked to |
| 1846 | * try harder at this point | 1849 | * try harder at this point |
| 1847 | */ | 1850 | */ |
| 1848 | if (pag->pagf_metadata && args->userdata && flags) { | 1851 | if (pag->pagf_metadata && args->userdata && |
| 1852 | (flags & XFS_ALLOC_FLAG_TRYLOCK)) { | ||
| 1853 | ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); | ||
| 1849 | args->agbp = NULL; | 1854 | args->agbp = NULL; |
| 1850 | return 0; | 1855 | return 0; |
| 1851 | } | 1856 | } |
| 1852 | 1857 | ||
| 1853 | need = XFS_MIN_FREELIST_PAG(pag, mp); | 1858 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { |
| 1854 | delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; | 1859 | need = XFS_MIN_FREELIST_PAG(pag, mp); |
| 1855 | /* | 1860 | delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; |
| 1856 | * If it looks like there isn't a long enough extent, or enough | 1861 | /* |
| 1857 | * total blocks, reject it. | 1862 | * If it looks like there isn't a long enough extent, or enough |
| 1858 | */ | 1863 | * total blocks, reject it. |
| 1859 | longest = (pag->pagf_longest > delta) ? | 1864 | */ |
| 1860 | (pag->pagf_longest - delta) : | 1865 | longest = (pag->pagf_longest > delta) ? |
| 1861 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); | 1866 | (pag->pagf_longest - delta) : |
| 1862 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1867 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); |
| 1863 | (!(flags & XFS_ALLOC_FLAG_FREEING) && | 1868 | if ((args->minlen + args->alignment + args->minalignslop - 1) > |
| 1864 | (int)(pag->pagf_freeblks + pag->pagf_flcount - | 1869 | longest || |
| 1865 | need - args->total) < | 1870 | ((int)(pag->pagf_freeblks + pag->pagf_flcount - |
| 1866 | (int)args->minleft)) { | 1871 | need - args->total) < (int)args->minleft)) { |
| 1867 | if (agbp) | 1872 | if (agbp) |
| 1868 | xfs_trans_brelse(tp, agbp); | 1873 | xfs_trans_brelse(tp, agbp); |
| 1869 | args->agbp = NULL; | 1874 | args->agbp = NULL; |
| 1870 | return 0; | 1875 | return 0; |
| 1876 | } | ||
| 1871 | } | 1877 | } |
| 1878 | |||
| 1872 | /* | 1879 | /* |
| 1873 | * Get the a.g. freespace buffer. | 1880 | * Get the a.g. freespace buffer. |
| 1874 | * Can fail if we're not blocking on locks, and it's held. | 1881 | * Can fail if we're not blocking on locks, and it's held. |
| @@ -1878,6 +1885,8 @@ xfs_alloc_fix_freelist( | |||
| 1878 | &agbp))) | 1885 | &agbp))) |
| 1879 | return error; | 1886 | return error; |
| 1880 | if (agbp == NULL) { | 1887 | if (agbp == NULL) { |
| 1888 | ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); | ||
| 1889 | ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); | ||
| 1881 | args->agbp = NULL; | 1890 | args->agbp = NULL; |
| 1882 | return 0; | 1891 | return 0; |
| 1883 | } | 1892 | } |
| @@ -1887,22 +1896,24 @@ xfs_alloc_fix_freelist( | |||
| 1887 | */ | 1896 | */ |
| 1888 | agf = XFS_BUF_TO_AGF(agbp); | 1897 | agf = XFS_BUF_TO_AGF(agbp); |
| 1889 | need = XFS_MIN_FREELIST(agf, mp); | 1898 | need = XFS_MIN_FREELIST(agf, mp); |
| 1890 | delta = need > be32_to_cpu(agf->agf_flcount) ? | ||
| 1891 | (need - be32_to_cpu(agf->agf_flcount)) : 0; | ||
| 1892 | /* | 1899 | /* |
| 1893 | * If there isn't enough total or single-extent, reject it. | 1900 | * If there isn't enough total or single-extent, reject it. |
| 1894 | */ | 1901 | */ |
| 1895 | longest = be32_to_cpu(agf->agf_longest); | 1902 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { |
| 1896 | longest = (longest > delta) ? (longest - delta) : | 1903 | delta = need > be32_to_cpu(agf->agf_flcount) ? |
| 1897 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); | 1904 | (need - be32_to_cpu(agf->agf_flcount)) : 0; |
| 1898 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1905 | longest = be32_to_cpu(agf->agf_longest); |
| 1899 | (!(flags & XFS_ALLOC_FLAG_FREEING) && | 1906 | longest = (longest > delta) ? (longest - delta) : |
| 1900 | (int)(be32_to_cpu(agf->agf_freeblks) + | 1907 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); |
| 1901 | be32_to_cpu(agf->agf_flcount) - need - args->total) < | 1908 | if ((args->minlen + args->alignment + args->minalignslop - 1) > |
| 1902 | (int)args->minleft)) { | 1909 | longest || |
| 1903 | xfs_trans_brelse(tp, agbp); | 1910 | ((int)(be32_to_cpu(agf->agf_freeblks) + |
| 1904 | args->agbp = NULL; | 1911 | be32_to_cpu(agf->agf_flcount) - need - args->total) < |
| 1905 | return 0; | 1912 | (int)args->minleft)) { |
| 1913 | xfs_trans_brelse(tp, agbp); | ||
| 1914 | args->agbp = NULL; | ||
| 1915 | return 0; | ||
| 1916 | } | ||
| 1906 | } | 1917 | } |
| 1907 | /* | 1918 | /* |
| 1908 | * Make the freelist shorter if it's too long. | 1919 | * Make the freelist shorter if it's too long. |
| @@ -1950,12 +1961,11 @@ xfs_alloc_fix_freelist( | |||
| 1950 | * on a completely full ag. | 1961 | * on a completely full ag. |
| 1951 | */ | 1962 | */ |
| 1952 | if (targs.agbno == NULLAGBLOCK) { | 1963 | if (targs.agbno == NULLAGBLOCK) { |
| 1953 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { | 1964 | if (flags & XFS_ALLOC_FLAG_FREEING) |
| 1954 | xfs_trans_brelse(tp, agflbp); | 1965 | break; |
| 1955 | args->agbp = NULL; | 1966 | xfs_trans_brelse(tp, agflbp); |
| 1956 | return 0; | 1967 | args->agbp = NULL; |
| 1957 | } | 1968 | return 0; |
| 1958 | break; | ||
| 1959 | } | 1969 | } |
| 1960 | /* | 1970 | /* |
| 1961 | * Put each allocated block on the list. | 1971 | * Put each allocated block on the list. |
| @@ -2442,31 +2452,26 @@ xfs_free_extent( | |||
| 2442 | xfs_fsblock_t bno, /* starting block number of extent */ | 2452 | xfs_fsblock_t bno, /* starting block number of extent */ |
| 2443 | xfs_extlen_t len) /* length of extent */ | 2453 | xfs_extlen_t len) /* length of extent */ |
| 2444 | { | 2454 | { |
| 2445 | #ifdef DEBUG | 2455 | xfs_alloc_arg_t args; |
| 2446 | xfs_agf_t *agf; /* a.g. freespace header */ | ||
| 2447 | #endif | ||
| 2448 | xfs_alloc_arg_t args; /* allocation argument structure */ | ||
| 2449 | int error; | 2456 | int error; |
| 2450 | 2457 | ||
| 2451 | ASSERT(len != 0); | 2458 | ASSERT(len != 0); |
| 2459 | memset(&args, 0, sizeof(xfs_alloc_arg_t)); | ||
| 2452 | args.tp = tp; | 2460 | args.tp = tp; |
| 2453 | args.mp = tp->t_mountp; | 2461 | args.mp = tp->t_mountp; |
| 2454 | args.agno = XFS_FSB_TO_AGNO(args.mp, bno); | 2462 | args.agno = XFS_FSB_TO_AGNO(args.mp, bno); |
| 2455 | ASSERT(args.agno < args.mp->m_sb.sb_agcount); | 2463 | ASSERT(args.agno < args.mp->m_sb.sb_agcount); |
| 2456 | args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); | 2464 | args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); |
| 2457 | args.alignment = 1; | ||
| 2458 | args.minlen = args.minleft = args.minalignslop = 0; | ||
| 2459 | down_read(&args.mp->m_peraglock); | 2465 | down_read(&args.mp->m_peraglock); |
| 2460 | args.pag = &args.mp->m_perag[args.agno]; | 2466 | args.pag = &args.mp->m_perag[args.agno]; |
| 2461 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) | 2467 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) |
| 2462 | goto error0; | 2468 | goto error0; |
| 2463 | #ifdef DEBUG | 2469 | #ifdef DEBUG |
| 2464 | ASSERT(args.agbp != NULL); | 2470 | ASSERT(args.agbp != NULL); |
| 2465 | agf = XFS_BUF_TO_AGF(args.agbp); | 2471 | ASSERT((args.agbno + len) <= |
| 2466 | ASSERT(args.agbno + len <= be32_to_cpu(agf->agf_length)); | 2472 | be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)); |
| 2467 | #endif | 2473 | #endif |
| 2468 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, | 2474 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); |
| 2469 | len, 0); | ||
| 2470 | error0: | 2475 | error0: |
| 2471 | up_read(&args.mp->m_peraglock); | 2476 | up_read(&args.mp->m_peraglock); |
| 2472 | return error; | 2477 | return error; |
