diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/bio-integrity.c | 5 | ||||
| -rw-r--r-- | fs/bio.c | 6 | ||||
| -rw-r--r-- | fs/ecryptfs/crypto.c | 2 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 3 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 3 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 5 | ||||
| -rw-r--r-- | fs/fat/inode.c | 4 | ||||
| -rw-r--r-- | fs/fs-writeback.c | 9 | ||||
| -rw-r--r-- | fs/inode.c | 7 | ||||
| -rw-r--r-- | fs/lockd/clntlock.c | 51 | ||||
| -rw-r--r-- | fs/nfs/client.c | 73 | ||||
| -rw-r--r-- | fs/nfs/dir.c | 8 | ||||
| -rw-r--r-- | fs/nfs/nfs3acl.c | 27 | ||||
| -rw-r--r-- | fs/nfs/nfs3xdr.c | 34 | ||||
| -rw-r--r-- | fs/nfs/nfs4namespace.c | 15 | ||||
| -rw-r--r-- | fs/ocfs2/alloc.c | 3 | ||||
| -rw-r--r-- | fs/ocfs2/aops.c | 7 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 3 | ||||
| -rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 6 | ||||
| -rw-r--r-- | fs/ocfs2/xattr.c | 30 | ||||
| -rw-r--r-- | fs/pipe.c | 8 | ||||
| -rw-r--r-- | fs/proc/base.c | 16 | ||||
| -rw-r--r-- | fs/proc/page.c | 2 | ||||
| -rw-r--r-- | fs/ramfs/file-nommu.c | 4 | ||||
| -rw-r--r-- | fs/squashfs/block.c | 21 | ||||
| -rw-r--r-- | fs/super.c | 5 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 12 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 2 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 10 | ||||
| -rw-r--r-- | fs/xfs/xfs_iget.c | 15 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_recover.c | 17 |
31 files changed, 300 insertions, 113 deletions
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 549b0144da11..fe2b1aa2464e 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
| @@ -685,19 +685,20 @@ EXPORT_SYMBOL(bio_integrity_split); | |||
| 685 | * bio_integrity_clone - Callback for cloning bios with integrity metadata | 685 | * bio_integrity_clone - Callback for cloning bios with integrity metadata |
| 686 | * @bio: New bio | 686 | * @bio: New bio |
| 687 | * @bio_src: Original bio | 687 | * @bio_src: Original bio |
| 688 | * @gfp_mask: Memory allocation mask | ||
| 688 | * @bs: bio_set to allocate bip from | 689 | * @bs: bio_set to allocate bip from |
| 689 | * | 690 | * |
| 690 | * Description: Called to allocate a bip when cloning a bio | 691 | * Description: Called to allocate a bip when cloning a bio |
| 691 | */ | 692 | */ |
| 692 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, | 693 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, |
| 693 | struct bio_set *bs) | 694 | gfp_t gfp_mask, struct bio_set *bs) |
| 694 | { | 695 | { |
| 695 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; | 696 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; |
| 696 | struct bio_integrity_payload *bip; | 697 | struct bio_integrity_payload *bip; |
| 697 | 698 | ||
| 698 | BUG_ON(bip_src == NULL); | 699 | BUG_ON(bip_src == NULL); |
| 699 | 700 | ||
| 700 | bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); | 701 | bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs); |
| 701 | 702 | ||
| 702 | if (bip == NULL) | 703 | if (bip == NULL) |
| 703 | return -EIO; | 704 | return -EIO; |
| @@ -463,10 +463,12 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | |||
| 463 | if (bio_integrity(bio)) { | 463 | if (bio_integrity(bio)) { |
| 464 | int ret; | 464 | int ret; |
| 465 | 465 | ||
| 466 | ret = bio_integrity_clone(b, bio, fs_bio_set); | 466 | ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); |
| 467 | 467 | ||
| 468 | if (ret < 0) | 468 | if (ret < 0) { |
| 469 | bio_put(b); | ||
| 469 | return NULL; | 470 | return NULL; |
| 471 | } | ||
| 470 | } | 472 | } |
| 471 | 473 | ||
| 472 | return b; | 474 | return b; |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f6caeb1d1106..bdca1f4b3a3e 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -946,6 +946,8 @@ static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( | |||
| 946 | list_for_each_entry(global_auth_tok, | 946 | list_for_each_entry(global_auth_tok, |
| 947 | &mount_crypt_stat->global_auth_tok_list, | 947 | &mount_crypt_stat->global_auth_tok_list, |
| 948 | mount_crypt_stat_list) { | 948 | mount_crypt_stat_list) { |
| 949 | if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK) | ||
| 950 | continue; | ||
| 949 | rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); | 951 | rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); |
| 950 | if (rc) { | 952 | if (rc) { |
| 951 | printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); | 953 | printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index c11fc95714ab..eb2267eca1fe 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -328,6 +328,7 @@ struct ecryptfs_dentry_info { | |||
| 328 | */ | 328 | */ |
| 329 | struct ecryptfs_global_auth_tok { | 329 | struct ecryptfs_global_auth_tok { |
| 330 | #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 | 330 | #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 |
| 331 | #define ECRYPTFS_AUTH_TOK_FNEK 0x00000002 | ||
| 331 | u32 flags; | 332 | u32 flags; |
| 332 | struct list_head mount_crypt_stat_list; | 333 | struct list_head mount_crypt_stat_list; |
| 333 | struct key *global_auth_tok_key; | 334 | struct key *global_auth_tok_key; |
| @@ -696,7 +697,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
| 696 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); | 697 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); |
| 697 | int | 698 | int |
| 698 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 699 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 699 | char *sig); | 700 | char *sig, u32 global_auth_tok_flags); |
| 700 | int ecryptfs_get_global_auth_tok_for_sig( | 701 | int ecryptfs_get_global_auth_tok_for_sig( |
| 701 | struct ecryptfs_global_auth_tok **global_auth_tok, | 702 | struct ecryptfs_global_auth_tok **global_auth_tok, |
| 702 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); | 703 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index ff539420cc6f..e4a6223c3145 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
| @@ -2375,7 +2375,7 @@ struct kmem_cache *ecryptfs_global_auth_tok_cache; | |||
| 2375 | 2375 | ||
| 2376 | int | 2376 | int |
| 2377 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 2377 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 2378 | char *sig) | 2378 | char *sig, u32 global_auth_tok_flags) |
| 2379 | { | 2379 | { |
| 2380 | struct ecryptfs_global_auth_tok *new_auth_tok; | 2380 | struct ecryptfs_global_auth_tok *new_auth_tok; |
| 2381 | int rc = 0; | 2381 | int rc = 0; |
| @@ -2389,6 +2389,7 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | |||
| 2389 | goto out; | 2389 | goto out; |
| 2390 | } | 2390 | } |
| 2391 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); | 2391 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); |
| 2392 | new_auth_tok->flags = global_auth_tok_flags; | ||
| 2392 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 2393 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
| 2393 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | 2394 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
| 2394 | list_add(&new_auth_tok->mount_crypt_stat_list, | 2395 | list_add(&new_auth_tok->mount_crypt_stat_list, |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 789cf2e1be1e..aed56c25539b 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -319,7 +319,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 319 | case ecryptfs_opt_ecryptfs_sig: | 319 | case ecryptfs_opt_ecryptfs_sig: |
| 320 | sig_src = args[0].from; | 320 | sig_src = args[0].from; |
| 321 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, | 321 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, |
| 322 | sig_src); | 322 | sig_src, 0); |
| 323 | if (rc) { | 323 | if (rc) { |
| 324 | printk(KERN_ERR "Error attempting to register " | 324 | printk(KERN_ERR "Error attempting to register " |
| 325 | "global sig; rc = [%d]\n", rc); | 325 | "global sig; rc = [%d]\n", rc); |
| @@ -370,7 +370,8 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 370 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 370 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
| 371 | rc = ecryptfs_add_global_auth_tok( | 371 | rc = ecryptfs_add_global_auth_tok( |
| 372 | mount_crypt_stat, | 372 | mount_crypt_stat, |
| 373 | mount_crypt_stat->global_default_fnek_sig); | 373 | mount_crypt_stat->global_default_fnek_sig, |
| 374 | ECRYPTFS_AUTH_TOK_FNEK); | ||
| 374 | if (rc) { | 375 | if (rc) { |
| 375 | printk(KERN_ERR "Error attempting to register " | 376 | printk(KERN_ERR "Error attempting to register " |
| 376 | "global fnek sig [%s]; rc = [%d]\n", | 377 | "global fnek sig [%s]; rc = [%d]\n", |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 6b74d09adbe5..de0004fe6e00 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
| @@ -202,9 +202,9 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block) | |||
| 202 | sector_t blocknr; | 202 | sector_t blocknr; |
| 203 | 203 | ||
| 204 | /* fat_get_cluster() assumes the requested blocknr isn't truncated. */ | 204 | /* fat_get_cluster() assumes the requested blocknr isn't truncated. */ |
| 205 | mutex_lock(&mapping->host->i_mutex); | 205 | down_read(&mapping->host->i_alloc_sem); |
| 206 | blocknr = generic_block_bmap(mapping, block, fat_get_block); | 206 | blocknr = generic_block_bmap(mapping, block, fat_get_block); |
| 207 | mutex_unlock(&mapping->host->i_mutex); | 207 | up_read(&mapping->host->i_alloc_sem); |
| 208 | 208 | ||
| 209 | return blocknr; | 209 | return blocknr; |
| 210 | } | 210 | } |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index e5eaa62fd17f..e3fe9918faaf 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -274,6 +274,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 274 | int ret; | 274 | int ret; |
| 275 | 275 | ||
| 276 | BUG_ON(inode->i_state & I_SYNC); | 276 | BUG_ON(inode->i_state & I_SYNC); |
| 277 | WARN_ON(inode->i_state & I_NEW); | ||
| 277 | 278 | ||
| 278 | /* Set I_SYNC, reset I_DIRTY */ | 279 | /* Set I_SYNC, reset I_DIRTY */ |
| 279 | dirty = inode->i_state & I_DIRTY; | 280 | dirty = inode->i_state & I_DIRTY; |
| @@ -298,6 +299,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | spin_lock(&inode_lock); | 301 | spin_lock(&inode_lock); |
| 302 | WARN_ON(inode->i_state & I_NEW); | ||
| 301 | inode->i_state &= ~I_SYNC; | 303 | inode->i_state &= ~I_SYNC; |
| 302 | if (!(inode->i_state & I_FREEING)) { | 304 | if (!(inode->i_state & I_FREEING)) { |
| 303 | if (!(inode->i_state & I_DIRTY) && | 305 | if (!(inode->i_state & I_DIRTY) && |
| @@ -470,6 +472,11 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
| 470 | break; | 472 | break; |
| 471 | } | 473 | } |
| 472 | 474 | ||
| 475 | if (inode->i_state & I_NEW) { | ||
| 476 | requeue_io(inode); | ||
| 477 | continue; | ||
| 478 | } | ||
| 479 | |||
| 473 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 480 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
| 474 | wbc->encountered_congestion = 1; | 481 | wbc->encountered_congestion = 1; |
| 475 | if (!sb_is_blkdev_sb(sb)) | 482 | if (!sb_is_blkdev_sb(sb)) |
| @@ -531,7 +538,7 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
| 531 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 538 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
| 532 | struct address_space *mapping; | 539 | struct address_space *mapping; |
| 533 | 540 | ||
| 534 | if (inode->i_state & (I_FREEING|I_WILL_FREE)) | 541 | if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) |
| 535 | continue; | 542 | continue; |
| 536 | mapping = inode->i_mapping; | 543 | mapping = inode->i_mapping; |
| 537 | if (mapping->nrpages == 0) | 544 | if (mapping->nrpages == 0) |
diff --git a/fs/inode.c b/fs/inode.c index 913ab2d9a5d1..826fb0b9d1c3 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -359,6 +359,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) | |||
| 359 | invalidate_inode_buffers(inode); | 359 | invalidate_inode_buffers(inode); |
| 360 | if (!atomic_read(&inode->i_count)) { | 360 | if (!atomic_read(&inode->i_count)) { |
| 361 | list_move(&inode->i_list, dispose); | 361 | list_move(&inode->i_list, dispose); |
| 362 | WARN_ON(inode->i_state & I_NEW); | ||
| 362 | inode->i_state |= I_FREEING; | 363 | inode->i_state |= I_FREEING; |
| 363 | count++; | 364 | count++; |
| 364 | continue; | 365 | continue; |
| @@ -460,6 +461,7 @@ static void prune_icache(int nr_to_scan) | |||
| 460 | continue; | 461 | continue; |
| 461 | } | 462 | } |
| 462 | list_move(&inode->i_list, &freeable); | 463 | list_move(&inode->i_list, &freeable); |
| 464 | WARN_ON(inode->i_state & I_NEW); | ||
| 463 | inode->i_state |= I_FREEING; | 465 | inode->i_state |= I_FREEING; |
| 464 | nr_pruned++; | 466 | nr_pruned++; |
| 465 | } | 467 | } |
| @@ -656,6 +658,7 @@ void unlock_new_inode(struct inode *inode) | |||
| 656 | * just created it (so there can be no old holders | 658 | * just created it (so there can be no old holders |
| 657 | * that haven't tested I_LOCK). | 659 | * that haven't tested I_LOCK). |
| 658 | */ | 660 | */ |
| 661 | WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); | ||
| 659 | inode->i_state &= ~(I_LOCK|I_NEW); | 662 | inode->i_state &= ~(I_LOCK|I_NEW); |
| 660 | wake_up_inode(inode); | 663 | wake_up_inode(inode); |
| 661 | } | 664 | } |
| @@ -1145,6 +1148,7 @@ void generic_delete_inode(struct inode *inode) | |||
| 1145 | 1148 | ||
| 1146 | list_del_init(&inode->i_list); | 1149 | list_del_init(&inode->i_list); |
| 1147 | list_del_init(&inode->i_sb_list); | 1150 | list_del_init(&inode->i_sb_list); |
| 1151 | WARN_ON(inode->i_state & I_NEW); | ||
| 1148 | inode->i_state |= I_FREEING; | 1152 | inode->i_state |= I_FREEING; |
| 1149 | inodes_stat.nr_inodes--; | 1153 | inodes_stat.nr_inodes--; |
| 1150 | spin_unlock(&inode_lock); | 1154 | spin_unlock(&inode_lock); |
| @@ -1186,16 +1190,19 @@ static void generic_forget_inode(struct inode *inode) | |||
| 1186 | spin_unlock(&inode_lock); | 1190 | spin_unlock(&inode_lock); |
| 1187 | return; | 1191 | return; |
| 1188 | } | 1192 | } |
| 1193 | WARN_ON(inode->i_state & I_NEW); | ||
| 1189 | inode->i_state |= I_WILL_FREE; | 1194 | inode->i_state |= I_WILL_FREE; |
| 1190 | spin_unlock(&inode_lock); | 1195 | spin_unlock(&inode_lock); |
| 1191 | write_inode_now(inode, 1); | 1196 | write_inode_now(inode, 1); |
| 1192 | spin_lock(&inode_lock); | 1197 | spin_lock(&inode_lock); |
| 1198 | WARN_ON(inode->i_state & I_NEW); | ||
| 1193 | inode->i_state &= ~I_WILL_FREE; | 1199 | inode->i_state &= ~I_WILL_FREE; |
| 1194 | inodes_stat.nr_unused--; | 1200 | inodes_stat.nr_unused--; |
| 1195 | hlist_del_init(&inode->i_hash); | 1201 | hlist_del_init(&inode->i_hash); |
| 1196 | } | 1202 | } |
| 1197 | list_del_init(&inode->i_list); | 1203 | list_del_init(&inode->i_list); |
| 1198 | list_del_init(&inode->i_sb_list); | 1204 | list_del_init(&inode->i_sb_list); |
| 1205 | WARN_ON(inode->i_state & I_NEW); | ||
| 1199 | inode->i_state |= I_FREEING; | 1206 | inode->i_state |= I_FREEING; |
| 1200 | inodes_stat.nr_inodes--; | 1207 | inodes_stat.nr_inodes--; |
| 1201 | spin_unlock(&inode_lock); | 1208 | spin_unlock(&inode_lock); |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 1f3b0fc0d351..aedc47a264c1 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
| @@ -139,6 +139,55 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
| 139 | return 0; | 139 | return 0; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 143 | static const struct in6_addr *nlmclnt_map_v4addr(const struct sockaddr *sap, | ||
| 144 | struct in6_addr *addr_mapped) | ||
| 145 | { | ||
| 146 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; | ||
| 147 | |||
| 148 | switch (sap->sa_family) { | ||
| 149 | case AF_INET6: | ||
| 150 | return &((const struct sockaddr_in6 *)sap)->sin6_addr; | ||
| 151 | case AF_INET: | ||
| 152 | ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, addr_mapped); | ||
| 153 | return addr_mapped; | ||
| 154 | } | ||
| 155 | |||
| 156 | return NULL; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* | ||
| 160 | * If lockd is using a PF_INET6 listener, all incoming requests appear | ||
| 161 | * to come from AF_INET6 remotes. The address of AF_INET remotes are | ||
| 162 | * mapped to AF_INET6 automatically by the network layer. In case the | ||
| 163 | * user passed an AF_INET server address at mount time, ensure both | ||
| 164 | * addresses are AF_INET6 before comparing them. | ||
| 165 | */ | ||
| 166 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
| 167 | const struct sockaddr *sap) | ||
| 168 | { | ||
| 169 | const struct in6_addr *addr1; | ||
| 170 | const struct in6_addr *addr2; | ||
| 171 | struct in6_addr addr1_mapped; | ||
| 172 | struct in6_addr addr2_mapped; | ||
| 173 | |||
| 174 | addr1 = nlmclnt_map_v4addr(nlm_addr(host), &addr1_mapped); | ||
| 175 | if (likely(addr1 != NULL)) { | ||
| 176 | addr2 = nlmclnt_map_v4addr(sap, &addr2_mapped); | ||
| 177 | if (likely(addr2 != NULL)) | ||
| 178 | return ipv6_addr_equal(addr1, addr2); | ||
| 179 | } | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | #else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
| 184 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
| 185 | const struct sockaddr *sap) | ||
| 186 | { | ||
| 187 | return nlm_cmp_addr(nlm_addr(host), sap); | ||
| 188 | } | ||
| 189 | #endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
| 190 | |||
| 142 | /* | 191 | /* |
| 143 | * The server lockd has called us back to tell us the lock was granted | 192 | * The server lockd has called us back to tell us the lock was granted |
| 144 | */ | 193 | */ |
| @@ -166,7 +215,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) | |||
| 166 | */ | 215 | */ |
| 167 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) | 216 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) |
| 168 | continue; | 217 | continue; |
| 169 | if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) | 218 | if (!nlmclnt_cmp_addr(block->b_host, addr)) |
| 170 | continue; | 219 | continue; |
| 171 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) | 220 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) |
| 172 | continue; | 221 | continue; |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 9b728f3565a1..574158ae2398 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
| @@ -255,6 +255,32 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | |||
| 255 | } | 255 | } |
| 256 | return 0; | 256 | return 0; |
| 257 | } | 257 | } |
| 258 | |||
| 259 | /* | ||
| 260 | * Test if two ip6 socket addresses refer to the same socket by | ||
| 261 | * comparing relevant fields. The padding bytes specifically, are not | ||
| 262 | * compared. sin6_flowinfo is not compared because it only affects QoS | ||
| 263 | * and sin6_scope_id is only compared if the address is "link local" | ||
| 264 | * because "link local" addresses need only be unique to a specific | ||
| 265 | * link. Conversely, ordinary unicast addresses might have different | ||
| 266 | * sin6_scope_id. | ||
| 267 | * | ||
| 268 | * The caller should ensure both socket addresses are AF_INET6. | ||
| 269 | */ | ||
| 270 | static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1, | ||
| 271 | const struct sockaddr *sa2) | ||
| 272 | { | ||
| 273 | const struct sockaddr_in6 *saddr1 = (const struct sockaddr_in6 *)sa1; | ||
| 274 | const struct sockaddr_in6 *saddr2 = (const struct sockaddr_in6 *)sa2; | ||
| 275 | |||
| 276 | if (!ipv6_addr_equal(&saddr1->sin6_addr, | ||
| 277 | &saddr1->sin6_addr)) | ||
| 278 | return 0; | ||
| 279 | if (ipv6_addr_scope(&saddr1->sin6_addr) == IPV6_ADDR_SCOPE_LINKLOCAL && | ||
| 280 | saddr1->sin6_scope_id != saddr2->sin6_scope_id) | ||
| 281 | return 0; | ||
| 282 | return saddr1->sin6_port == saddr2->sin6_port; | ||
| 283 | } | ||
| 258 | #else | 284 | #else |
| 259 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, | 285 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, |
| 260 | const struct sockaddr_in *sa2) | 286 | const struct sockaddr_in *sa2) |
| @@ -270,9 +296,52 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | |||
| 270 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, | 296 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, |
| 271 | (const struct sockaddr_in *)sa2); | 297 | (const struct sockaddr_in *)sa2); |
| 272 | } | 298 | } |
| 299 | |||
| 300 | static int nfs_sockaddr_cmp_ip6(const struct sockaddr * sa1, | ||
| 301 | const struct sockaddr * sa2) | ||
| 302 | { | ||
| 303 | return 0; | ||
| 304 | } | ||
| 273 | #endif | 305 | #endif |
| 274 | 306 | ||
| 275 | /* | 307 | /* |
| 308 | * Test if two ip4 socket addresses refer to the same socket, by | ||
| 309 | * comparing relevant fields. The padding bytes specifically, are | ||
| 310 | * not compared. | ||
| 311 | * | ||
| 312 | * The caller should ensure both socket addresses are AF_INET. | ||
| 313 | */ | ||
| 314 | static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1, | ||
| 315 | const struct sockaddr *sa2) | ||
| 316 | { | ||
| 317 | const struct sockaddr_in *saddr1 = (const struct sockaddr_in *)sa1; | ||
| 318 | const struct sockaddr_in *saddr2 = (const struct sockaddr_in *)sa2; | ||
| 319 | |||
| 320 | if (saddr1->sin_addr.s_addr != saddr2->sin_addr.s_addr) | ||
| 321 | return 0; | ||
| 322 | return saddr1->sin_port == saddr2->sin_port; | ||
| 323 | } | ||
| 324 | |||
| 325 | /* | ||
| 326 | * Test if two socket addresses represent the same actual socket, | ||
| 327 | * by comparing (only) relevant fields. | ||
| 328 | */ | ||
| 329 | static int nfs_sockaddr_cmp(const struct sockaddr *sa1, | ||
| 330 | const struct sockaddr *sa2) | ||
| 331 | { | ||
| 332 | if (sa1->sa_family != sa2->sa_family) | ||
| 333 | return 0; | ||
| 334 | |||
| 335 | switch (sa1->sa_family) { | ||
| 336 | case AF_INET: | ||
| 337 | return nfs_sockaddr_cmp_ip4(sa1, sa2); | ||
| 338 | case AF_INET6: | ||
| 339 | return nfs_sockaddr_cmp_ip6(sa1, sa2); | ||
| 340 | } | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 276 | * Find a client by IP address and protocol version | 345 | * Find a client by IP address and protocol version |
| 277 | * - returns NULL if no such client | 346 | * - returns NULL if no such client |
| 278 | */ | 347 | */ |
| @@ -344,8 +413,10 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp) | |||
| 344 | static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) | 413 | static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) |
| 345 | { | 414 | { |
| 346 | struct nfs_client *clp; | 415 | struct nfs_client *clp; |
| 416 | const struct sockaddr *sap = data->addr; | ||
| 347 | 417 | ||
| 348 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { | 418 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { |
| 419 | const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; | ||
| 349 | /* Don't match clients that failed to initialise properly */ | 420 | /* Don't match clients that failed to initialise properly */ |
| 350 | if (clp->cl_cons_state < 0) | 421 | if (clp->cl_cons_state < 0) |
| 351 | continue; | 422 | continue; |
| @@ -358,7 +429,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat | |||
| 358 | continue; | 429 | continue; |
| 359 | 430 | ||
| 360 | /* Match the full socket address */ | 431 | /* Match the full socket address */ |
| 361 | if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0) | 432 | if (!nfs_sockaddr_cmp(sap, clap)) |
| 362 | continue; | 433 | continue; |
| 363 | 434 | ||
| 364 | atomic_inc(&clp->cl_count); | 435 | atomic_inc(&clp->cl_count); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e35c8199f82f..672368f865ca 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1892,8 +1892,14 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) | |||
| 1892 | cache.cred = cred; | 1892 | cache.cred = cred; |
| 1893 | cache.jiffies = jiffies; | 1893 | cache.jiffies = jiffies; |
| 1894 | status = NFS_PROTO(inode)->access(inode, &cache); | 1894 | status = NFS_PROTO(inode)->access(inode, &cache); |
| 1895 | if (status != 0) | 1895 | if (status != 0) { |
| 1896 | if (status == -ESTALE) { | ||
| 1897 | nfs_zap_caches(inode); | ||
| 1898 | if (!S_ISDIR(inode->i_mode)) | ||
| 1899 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); | ||
| 1900 | } | ||
| 1896 | return status; | 1901 | return status; |
| 1902 | } | ||
| 1897 | nfs_access_add_cache(inode, &cache); | 1903 | nfs_access_add_cache(inode, &cache); |
| 1898 | out: | 1904 | out: |
| 1899 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) | 1905 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index cef62557c87d..6bbf0e6daad2 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
| @@ -292,7 +292,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 292 | { | 292 | { |
| 293 | struct nfs_server *server = NFS_SERVER(inode); | 293 | struct nfs_server *server = NFS_SERVER(inode); |
| 294 | struct nfs_fattr fattr; | 294 | struct nfs_fattr fattr; |
| 295 | struct page *pages[NFSACL_MAXPAGES] = { }; | 295 | struct page *pages[NFSACL_MAXPAGES]; |
| 296 | struct nfs3_setaclargs args = { | 296 | struct nfs3_setaclargs args = { |
| 297 | .inode = inode, | 297 | .inode = inode, |
| 298 | .mask = NFS_ACL, | 298 | .mask = NFS_ACL, |
| @@ -303,7 +303,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 303 | .rpc_argp = &args, | 303 | .rpc_argp = &args, |
| 304 | .rpc_resp = &fattr, | 304 | .rpc_resp = &fattr, |
| 305 | }; | 305 | }; |
| 306 | int status, count; | 306 | int status; |
| 307 | 307 | ||
| 308 | status = -EOPNOTSUPP; | 308 | status = -EOPNOTSUPP; |
| 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) | 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) |
| @@ -319,6 +319,20 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 319 | if (S_ISDIR(inode->i_mode)) { | 319 | if (S_ISDIR(inode->i_mode)) { |
| 320 | args.mask |= NFS_DFACL; | 320 | args.mask |= NFS_DFACL; |
| 321 | args.acl_default = dfacl; | 321 | args.acl_default = dfacl; |
| 322 | args.len = nfsacl_size(acl, dfacl); | ||
| 323 | } else | ||
| 324 | args.len = nfsacl_size(acl, NULL); | ||
| 325 | |||
| 326 | if (args.len > NFS_ACL_INLINE_BUFSIZE) { | ||
| 327 | unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); | ||
| 328 | |||
| 329 | status = -ENOMEM; | ||
| 330 | do { | ||
| 331 | args.pages[args.npages] = alloc_page(GFP_KERNEL); | ||
| 332 | if (args.pages[args.npages] == NULL) | ||
| 333 | goto out_freepages; | ||
| 334 | args.npages++; | ||
| 335 | } while (args.npages < npages); | ||
| 322 | } | 336 | } |
| 323 | 337 | ||
| 324 | dprintk("NFS call setacl\n"); | 338 | dprintk("NFS call setacl\n"); |
| @@ -329,10 +343,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 329 | nfs_zap_acl_cache(inode); | 343 | nfs_zap_acl_cache(inode); |
| 330 | dprintk("NFS reply setacl: %d\n", status); | 344 | dprintk("NFS reply setacl: %d\n", status); |
| 331 | 345 | ||
| 332 | /* pages may have been allocated at the xdr layer. */ | ||
| 333 | for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) | ||
| 334 | __free_page(args.pages[count]); | ||
| 335 | |||
| 336 | switch (status) { | 346 | switch (status) { |
| 337 | case 0: | 347 | case 0: |
| 338 | status = nfs_refresh_inode(inode, &fattr); | 348 | status = nfs_refresh_inode(inode, &fattr); |
| @@ -346,6 +356,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 346 | case -ENOTSUPP: | 356 | case -ENOTSUPP: |
| 347 | status = -EOPNOTSUPP; | 357 | status = -EOPNOTSUPP; |
| 348 | } | 358 | } |
| 359 | out_freepages: | ||
| 360 | while (args.npages != 0) { | ||
| 361 | args.npages--; | ||
| 362 | __free_page(args.pages[args.npages]); | ||
| 363 | } | ||
| 349 | out: | 364 | out: |
| 350 | return status; | 365 | return status; |
| 351 | } | 366 | } |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 11cdddec1432..6cdeacffde46 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
| @@ -82,8 +82,10 @@ | |||
| 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) | 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) |
| 83 | 83 | ||
| 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) | 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) |
| 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3)) | 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ |
| 86 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3)) | 86 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) |
| 87 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ | ||
| 88 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) | ||
| 87 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) | 89 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) |
| 88 | 90 | ||
| 89 | /* | 91 | /* |
| @@ -703,28 +705,18 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, | |||
| 703 | struct nfs3_setaclargs *args) | 705 | struct nfs3_setaclargs *args) |
| 704 | { | 706 | { |
| 705 | struct xdr_buf *buf = &req->rq_snd_buf; | 707 | struct xdr_buf *buf = &req->rq_snd_buf; |
| 706 | unsigned int base, len_in_head, len = nfsacl_size( | 708 | unsigned int base; |
| 707 | (args->mask & NFS_ACL) ? args->acl_access : NULL, | 709 | int err; |
| 708 | (args->mask & NFS_DFACL) ? args->acl_default : NULL); | ||
| 709 | int count, err; | ||
| 710 | 710 | ||
| 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); | 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); |
| 712 | *p++ = htonl(args->mask); | 712 | *p++ = htonl(args->mask); |
| 713 | base = (char *)p - (char *)buf->head->iov_base; | 713 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
| 714 | /* put as much of the acls into head as possible. */ | 714 | base = req->rq_slen; |
| 715 | len_in_head = min_t(unsigned int, buf->head->iov_len - base, len); | 715 | |
| 716 | len -= len_in_head; | 716 | if (args->npages != 0) |
| 717 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2)); | 717 | xdr_encode_pages(buf, args->pages, 0, args->len); |
| 718 | 718 | else | |
| 719 | for (count = 0; (count << PAGE_SHIFT) < len; count++) { | 719 | req->rq_slen += args->len; |
| 720 | args->pages[count] = alloc_page(GFP_KERNEL); | ||
| 721 | if (!args->pages[count]) { | ||
| 722 | while (count) | ||
| 723 | __free_page(args->pages[--count]); | ||
| 724 | return -ENOMEM; | ||
| 725 | } | ||
| 726 | } | ||
| 727 | xdr_encode_pages(buf, args->pages, 0, len); | ||
| 728 | 720 | ||
| 729 | err = nfsacl_encode(buf, base, args->inode, | 721 | err = nfsacl_encode(buf, base, args->inode, |
| 730 | (args->mask & NFS_ACL) ? | 722 | (args->mask & NFS_ACL) ? |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 30befc39b3c6..2a2a0a7143ad 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
| @@ -21,7 +21,9 @@ | |||
| 21 | #define NFSDBG_FACILITY NFSDBG_VFS | 21 | #define NFSDBG_FACILITY NFSDBG_VFS |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | * Check if fs_root is valid | 24 | * Convert the NFSv4 pathname components into a standard posix path. |
| 25 | * | ||
| 26 | * Note that the resulting string will be placed at the end of the buffer | ||
| 25 | */ | 27 | */ |
| 26 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, | 28 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, |
| 27 | char *buffer, ssize_t buflen) | 29 | char *buffer, ssize_t buflen) |
| @@ -99,21 +101,20 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
| 99 | { | 101 | { |
| 100 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 102 | struct vfsmount *mnt = ERR_PTR(-ENOENT); |
| 101 | char *mnt_path; | 103 | char *mnt_path; |
| 102 | int page2len; | 104 | unsigned int maxbuflen; |
| 103 | unsigned int s; | 105 | unsigned int s; |
| 104 | 106 | ||
| 105 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); | 107 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); |
| 106 | if (IS_ERR(mnt_path)) | 108 | if (IS_ERR(mnt_path)) |
| 107 | return mnt; | 109 | return mnt; |
| 108 | mountdata->mnt_path = mnt_path; | 110 | mountdata->mnt_path = mnt_path; |
| 109 | page2 += strlen(mnt_path) + 1; | 111 | maxbuflen = mnt_path - 1 - page2; |
| 110 | page2len = PAGE_SIZE - strlen(mnt_path) - 1; | ||
| 111 | 112 | ||
| 112 | for (s = 0; s < location->nservers; s++) { | 113 | for (s = 0; s < location->nservers; s++) { |
| 113 | const struct nfs4_string *buf = &location->servers[s]; | 114 | const struct nfs4_string *buf = &location->servers[s]; |
| 114 | struct sockaddr_storage addr; | 115 | struct sockaddr_storage addr; |
| 115 | 116 | ||
| 116 | if (buf->len <= 0 || buf->len >= PAGE_SIZE) | 117 | if (buf->len <= 0 || buf->len >= maxbuflen) |
| 117 | continue; | 118 | continue; |
| 118 | 119 | ||
| 119 | mountdata->addr = (struct sockaddr *)&addr; | 120 | mountdata->addr = (struct sockaddr *)&addr; |
| @@ -126,8 +127,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
| 126 | continue; | 127 | continue; |
| 127 | nfs_set_port(mountdata->addr, NFS_PORT); | 128 | nfs_set_port(mountdata->addr, NFS_PORT); |
| 128 | 129 | ||
| 129 | strncpy(page2, buf->data, page2len); | 130 | memcpy(page2, buf->data, buf->len); |
| 130 | page2[page2len] = '\0'; | 131 | page2[buf->len] = '\0'; |
| 131 | mountdata->hostname = page2; | 132 | mountdata->hostname = page2; |
| 132 | 133 | ||
| 133 | snprintf(page, PAGE_SIZE, "%s:%s", | 134 | snprintf(page, PAGE_SIZE, "%s:%s", |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 3a9e5deed74d..19e3a96aa02c 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -176,7 +176,8 @@ static int ocfs2_dinode_insert_check(struct inode *inode, | |||
| 176 | 176 | ||
| 177 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); | 177 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); |
| 178 | mlog_bug_on_msg(!ocfs2_sparse_alloc(osb) && | 178 | mlog_bug_on_msg(!ocfs2_sparse_alloc(osb) && |
| 179 | (OCFS2_I(inode)->ip_clusters != rec->e_cpos), | 179 | (OCFS2_I(inode)->ip_clusters != |
| 180 | le32_to_cpu(rec->e_cpos)), | ||
| 180 | "Device %s, asking for sparse allocation: inode %llu, " | 181 | "Device %s, asking for sparse allocation: inode %llu, " |
| 181 | "cpos %u, clusters %u\n", | 182 | "cpos %u, clusters %u\n", |
| 182 | osb->dev_str, | 183 | osb->dev_str, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index a067a6cffb01..8e1709a679b7 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -227,7 +227,7 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page, | |||
| 227 | size = i_size_read(inode); | 227 | size = i_size_read(inode); |
| 228 | 228 | ||
| 229 | if (size > PAGE_CACHE_SIZE || | 229 | if (size > PAGE_CACHE_SIZE || |
| 230 | size > ocfs2_max_inline_data(inode->i_sb)) { | 230 | size > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) { |
| 231 | ocfs2_error(inode->i_sb, | 231 | ocfs2_error(inode->i_sb, |
| 232 | "Inode %llu has with inline data has bad size: %Lu", | 232 | "Inode %llu has with inline data has bad size: %Lu", |
| 233 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 233 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
| @@ -1555,6 +1555,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, | |||
| 1555 | int ret, written = 0; | 1555 | int ret, written = 0; |
| 1556 | loff_t end = pos + len; | 1556 | loff_t end = pos + len; |
| 1557 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 1557 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| 1558 | struct ocfs2_dinode *di = NULL; | ||
| 1558 | 1559 | ||
| 1559 | mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", | 1560 | mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", |
| 1560 | (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, | 1561 | (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, |
| @@ -1587,7 +1588,9 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, | |||
| 1587 | /* | 1588 | /* |
| 1588 | * Check whether the write can fit. | 1589 | * Check whether the write can fit. |
| 1589 | */ | 1590 | */ |
| 1590 | if (mmap_page || end > ocfs2_max_inline_data(inode->i_sb)) | 1591 | di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; |
| 1592 | if (mmap_page || | ||
| 1593 | end > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) | ||
| 1591 | return 0; | 1594 | return 0; |
| 1592 | 1595 | ||
| 1593 | do_inline_write: | 1596 | do_inline_write: |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 084aba86c3b2..4b11762f249e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -532,7 +532,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
| 532 | 532 | ||
| 533 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); | 533 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); |
| 534 | 534 | ||
| 535 | fe->id2.i_data.id_count = cpu_to_le16(ocfs2_max_inline_data(osb->sb)); | 535 | fe->id2.i_data.id_count = cpu_to_le16( |
| 536 | ocfs2_max_inline_data_with_xattr(osb->sb, fe)); | ||
| 536 | } else { | 537 | } else { |
| 537 | fel = &fe->id2.i_list; | 538 | fel = &fe->id2.i_list; |
| 538 | fel->l_tree_depth = 0; | 539 | fel->l_tree_depth = 0; |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index c7ae45aaa36c..2332ef740f4f 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
| @@ -1070,12 +1070,6 @@ static inline int ocfs2_fast_symlink_chars(struct super_block *sb) | |||
| 1070 | offsetof(struct ocfs2_dinode, id2.i_symlink); | 1070 | offsetof(struct ocfs2_dinode, id2.i_symlink); |
| 1071 | } | 1071 | } |
| 1072 | 1072 | ||
| 1073 | static inline int ocfs2_max_inline_data(struct super_block *sb) | ||
| 1074 | { | ||
| 1075 | return sb->s_blocksize - | ||
| 1076 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, | 1073 | static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, |
| 1080 | struct ocfs2_dinode *di) | 1074 | struct ocfs2_dinode *di) |
| 1081 | { | 1075 | { |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 4ddd788add67..2563df89fc2a 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -547,8 +547,12 @@ int ocfs2_calc_xattr_init(struct inode *dir, | |||
| 547 | * when blocksize = 512, may reserve one more cluser for | 547 | * when blocksize = 512, may reserve one more cluser for |
| 548 | * xattr bucket, otherwise reserve one metadata block | 548 | * xattr bucket, otherwise reserve one metadata block |
| 549 | * for them is ok. | 549 | * for them is ok. |
| 550 | * If this is a new directory with inline data, | ||
| 551 | * we choose to reserve the entire inline area for | ||
| 552 | * directory contents and force an external xattr block. | ||
| 550 | */ | 553 | */ |
| 551 | if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || | 554 | if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || |
| 555 | (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) || | ||
| 552 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { | 556 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { |
| 553 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); | 557 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); |
| 554 | if (ret) { | 558 | if (ret) { |
| @@ -4791,19 +4795,33 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, | |||
| 4791 | char *val, | 4795 | char *val, |
| 4792 | int value_len) | 4796 | int value_len) |
| 4793 | { | 4797 | { |
| 4794 | int offset; | 4798 | int ret, offset, block_off; |
| 4795 | struct ocfs2_xattr_value_root *xv; | 4799 | struct ocfs2_xattr_value_root *xv; |
| 4796 | struct ocfs2_xattr_entry *xe = xs->here; | 4800 | struct ocfs2_xattr_entry *xe = xs->here; |
| 4801 | struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); | ||
| 4802 | void *base; | ||
| 4797 | 4803 | ||
| 4798 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); | 4804 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); |
| 4799 | 4805 | ||
| 4800 | offset = le16_to_cpu(xe->xe_name_offset) + | 4806 | ret = ocfs2_xattr_bucket_get_name_value(inode, xh, |
| 4801 | OCFS2_XATTR_SIZE(xe->xe_name_len); | 4807 | xe - xh->xh_entries, |
| 4808 | &block_off, | ||
| 4809 | &offset); | ||
| 4810 | if (ret) { | ||
| 4811 | mlog_errno(ret); | ||
| 4812 | goto out; | ||
| 4813 | } | ||
| 4802 | 4814 | ||
| 4803 | xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); | 4815 | base = bucket_block(xs->bucket, block_off); |
| 4816 | xv = (struct ocfs2_xattr_value_root *)(base + offset + | ||
| 4817 | OCFS2_XATTR_SIZE(xe->xe_name_len)); | ||
| 4804 | 4818 | ||
| 4805 | return __ocfs2_xattr_set_value_outside(inode, handle, | 4819 | ret = __ocfs2_xattr_set_value_outside(inode, handle, |
| 4806 | xv, val, value_len); | 4820 | xv, val, value_len); |
| 4821 | if (ret) | ||
| 4822 | mlog_errno(ret); | ||
| 4823 | out: | ||
| 4824 | return ret; | ||
| 4807 | } | 4825 | } |
| 4808 | 4826 | ||
| 4809 | static int ocfs2_rm_xattr_cluster(struct inode *inode, | 4827 | static int ocfs2_rm_xattr_cluster(struct inode *inode, |
| @@ -699,12 +699,12 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on) | |||
| 699 | int retval; | 699 | int retval; |
| 700 | 700 | ||
| 701 | mutex_lock(&inode->i_mutex); | 701 | mutex_lock(&inode->i_mutex); |
| 702 | |||
| 703 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); | 702 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); |
| 704 | 703 | if (retval >= 0) { | |
| 705 | if (retval >= 0) | ||
| 706 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); | 704 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); |
| 707 | 705 | if (retval < 0) /* this can happen only if on == T */ | |
| 706 | fasync_helper(-1, filp, 0, &pipe->fasync_readers); | ||
| 707 | } | ||
| 708 | mutex_unlock(&inode->i_mutex); | 708 | mutex_unlock(&inode->i_mutex); |
| 709 | 709 | ||
| 710 | if (retval < 0) | 710 | if (retval < 0) |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 0c9de19a1633..beaa0ce3b82e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -3066,7 +3066,6 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3066 | int retval = -ENOENT; | 3066 | int retval = -ENOENT; |
| 3067 | ino_t ino; | 3067 | ino_t ino; |
| 3068 | int tid; | 3068 | int tid; |
| 3069 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ | ||
| 3070 | struct pid_namespace *ns; | 3069 | struct pid_namespace *ns; |
| 3071 | 3070 | ||
| 3072 | task = get_proc_task(inode); | 3071 | task = get_proc_task(inode); |
| @@ -3083,18 +3082,18 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3083 | goto out_no_task; | 3082 | goto out_no_task; |
| 3084 | retval = 0; | 3083 | retval = 0; |
| 3085 | 3084 | ||
| 3086 | switch (pos) { | 3085 | switch ((unsigned long)filp->f_pos) { |
| 3087 | case 0: | 3086 | case 0: |
| 3088 | ino = inode->i_ino; | 3087 | ino = inode->i_ino; |
| 3089 | if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) | 3088 | if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0) |
| 3090 | goto out; | 3089 | goto out; |
| 3091 | pos++; | 3090 | filp->f_pos++; |
| 3092 | /* fall through */ | 3091 | /* fall through */ |
| 3093 | case 1: | 3092 | case 1: |
| 3094 | ino = parent_ino(dentry); | 3093 | ino = parent_ino(dentry); |
| 3095 | if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) | 3094 | if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0) |
| 3096 | goto out; | 3095 | goto out; |
| 3097 | pos++; | 3096 | filp->f_pos++; |
| 3098 | /* fall through */ | 3097 | /* fall through */ |
| 3099 | } | 3098 | } |
| 3100 | 3099 | ||
| @@ -3104,9 +3103,9 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3104 | ns = filp->f_dentry->d_sb->s_fs_info; | 3103 | ns = filp->f_dentry->d_sb->s_fs_info; |
| 3105 | tid = (int)filp->f_version; | 3104 | tid = (int)filp->f_version; |
| 3106 | filp->f_version = 0; | 3105 | filp->f_version = 0; |
| 3107 | for (task = first_tid(leader, tid, pos - 2, ns); | 3106 | for (task = first_tid(leader, tid, filp->f_pos - 2, ns); |
| 3108 | task; | 3107 | task; |
| 3109 | task = next_tid(task), pos++) { | 3108 | task = next_tid(task), filp->f_pos++) { |
| 3110 | tid = task_pid_nr_ns(task, ns); | 3109 | tid = task_pid_nr_ns(task, ns); |
| 3111 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { | 3110 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { |
| 3112 | /* returning this tgid failed, save it as the first | 3111 | /* returning this tgid failed, save it as the first |
| @@ -3117,7 +3116,6 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3117 | } | 3116 | } |
| 3118 | } | 3117 | } |
| 3119 | out: | 3118 | out: |
| 3120 | filp->f_pos = pos; | ||
| 3121 | put_task_struct(leader); | 3119 | put_task_struct(leader); |
| 3122 | out_no_task: | 3120 | out_no_task: |
| 3123 | return retval; | 3121 | return retval; |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 2d1345112a42..e9983837d08d 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
| @@ -80,7 +80,7 @@ static const struct file_operations proc_kpagecount_operations = { | |||
| 80 | #define KPF_RECLAIM 9 | 80 | #define KPF_RECLAIM 9 |
| 81 | #define KPF_BUDDY 10 | 81 | #define KPF_BUDDY 10 |
| 82 | 82 | ||
| 83 | #define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos) | 83 | #define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos) |
| 84 | 84 | ||
| 85 | static ssize_t kpageflags_read(struct file *file, char __user *buf, | 85 | static ssize_t kpageflags_read(struct file *file, char __user *buf, |
| 86 | size_t count, loff_t *ppos) | 86 | size_t count, loff_t *ppos) |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index b9b567a28376..5d7c7ececa64 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
| @@ -114,6 +114,9 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
| 114 | if (!pagevec_add(&lru_pvec, page)) | 114 | if (!pagevec_add(&lru_pvec, page)) |
| 115 | __pagevec_lru_add_file(&lru_pvec); | 115 | __pagevec_lru_add_file(&lru_pvec); |
| 116 | 116 | ||
| 117 | /* prevent the page from being discarded on memory pressure */ | ||
| 118 | SetPageDirty(page); | ||
| 119 | |||
| 117 | unlock_page(page); | 120 | unlock_page(page); |
| 118 | } | 121 | } |
| 119 | 122 | ||
| @@ -126,6 +129,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
| 126 | return -EFBIG; | 129 | return -EFBIG; |
| 127 | 130 | ||
| 128 | add_error: | 131 | add_error: |
| 132 | pagevec_lru_add_file(&lru_pvec); | ||
| 129 | page_cache_release(pages + loop); | 133 | page_cache_release(pages + loop); |
| 130 | for (loop++; loop < npages; loop++) | 134 | for (loop++; loop < npages; loop++) |
| 131 | __free_page(pages + loop); | 135 | __free_page(pages + loop); |
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index 321728f48f2d..2a7960310349 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c | |||
| @@ -184,15 +184,7 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
| 184 | offset = 0; | 184 | offset = 0; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | if (msblk->stream.avail_out == 0) { | 187 | if (msblk->stream.avail_out == 0 && page < pages) { |
| 188 | if (page == pages) { | ||
| 189 | ERROR("zlib_inflate tried to " | ||
| 190 | "decompress too much data, " | ||
| 191 | "expected %d bytes. Zlib " | ||
| 192 | "data probably corrupt\n", | ||
| 193 | srclength); | ||
| 194 | goto release_mutex; | ||
| 195 | } | ||
| 196 | msblk->stream.next_out = buffer[page++]; | 188 | msblk->stream.next_out = buffer[page++]; |
| 197 | msblk->stream.avail_out = PAGE_CACHE_SIZE; | 189 | msblk->stream.avail_out = PAGE_CACHE_SIZE; |
| 198 | } | 190 | } |
| @@ -209,25 +201,20 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
| 209 | zlib_init = 1; | 201 | zlib_init = 1; |
| 210 | } | 202 | } |
| 211 | 203 | ||
| 212 | zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); | 204 | zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); |
| 213 | 205 | ||
| 214 | if (msblk->stream.avail_in == 0 && k < b) | 206 | if (msblk->stream.avail_in == 0 && k < b) |
| 215 | put_bh(bh[k++]); | 207 | put_bh(bh[k++]); |
| 216 | } while (zlib_err == Z_OK); | 208 | } while (zlib_err == Z_OK); |
| 217 | 209 | ||
| 218 | if (zlib_err != Z_STREAM_END) { | 210 | if (zlib_err != Z_STREAM_END) { |
| 219 | ERROR("zlib_inflate returned unexpected result" | 211 | ERROR("zlib_inflate error, data probably corrupt\n"); |
| 220 | " 0x%x, srclength %d, avail_in %d," | ||
| 221 | " avail_out %d\n", zlib_err, srclength, | ||
| 222 | msblk->stream.avail_in, | ||
| 223 | msblk->stream.avail_out); | ||
| 224 | goto release_mutex; | 212 | goto release_mutex; |
| 225 | } | 213 | } |
| 226 | 214 | ||
| 227 | zlib_err = zlib_inflateEnd(&msblk->stream); | 215 | zlib_err = zlib_inflateEnd(&msblk->stream); |
| 228 | if (zlib_err != Z_OK) { | 216 | if (zlib_err != Z_OK) { |
| 229 | ERROR("zlib_inflateEnd returned unexpected result 0x%x," | 217 | ERROR("zlib_inflate error, data probably corrupt\n"); |
| 230 | " srclength %d\n", zlib_err, srclength); | ||
| 231 | goto release_mutex; | 218 | goto release_mutex; |
| 232 | } | 219 | } |
| 233 | length = msblk->stream.total_out; | 220 | length = msblk->stream.total_out; |
diff --git a/fs/super.c b/fs/super.c index 8349ed6b1412..6ce501447ada 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -371,8 +371,10 @@ retry: | |||
| 371 | continue; | 371 | continue; |
| 372 | if (!grab_super(old)) | 372 | if (!grab_super(old)) |
| 373 | goto retry; | 373 | goto retry; |
| 374 | if (s) | 374 | if (s) { |
| 375 | up_write(&s->s_umount); | ||
| 375 | destroy_super(s); | 376 | destroy_super(s); |
| 377 | } | ||
| 376 | return old; | 378 | return old; |
| 377 | } | 379 | } |
| 378 | } | 380 | } |
| @@ -387,6 +389,7 @@ retry: | |||
| 387 | err = set(s, data); | 389 | err = set(s, data); |
| 388 | if (err) { | 390 | if (err) { |
| 389 | spin_unlock(&sb_lock); | 391 | spin_unlock(&sb_lock); |
| 392 | up_write(&s->s_umount); | ||
| 390 | destroy_super(s); | 393 | destroy_super(s); |
| 391 | return ERR_PTR(err); | 394 | return ERR_PTR(err); |
| 392 | } | 395 | } |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index cb329edc925b..aa1016bb9134 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -34,6 +34,12 @@ | |||
| 34 | #include <linux/backing-dev.h> | 34 | #include <linux/backing-dev.h> |
| 35 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
| 36 | 36 | ||
| 37 | #include "xfs_sb.h" | ||
| 38 | #include "xfs_inum.h" | ||
| 39 | #include "xfs_ag.h" | ||
| 40 | #include "xfs_dmapi.h" | ||
| 41 | #include "xfs_mount.h" | ||
| 42 | |||
| 37 | static kmem_zone_t *xfs_buf_zone; | 43 | static kmem_zone_t *xfs_buf_zone; |
| 38 | STATIC int xfsbufd(void *); | 44 | STATIC int xfsbufd(void *); |
| 39 | STATIC int xfsbufd_wakeup(int, gfp_t); | 45 | STATIC int xfsbufd_wakeup(int, gfp_t); |
| @@ -1435,10 +1441,12 @@ xfs_unregister_buftarg( | |||
| 1435 | 1441 | ||
| 1436 | void | 1442 | void |
| 1437 | xfs_free_buftarg( | 1443 | xfs_free_buftarg( |
| 1438 | xfs_buftarg_t *btp) | 1444 | struct xfs_mount *mp, |
| 1445 | struct xfs_buftarg *btp) | ||
| 1439 | { | 1446 | { |
| 1440 | xfs_flush_buftarg(btp, 1); | 1447 | xfs_flush_buftarg(btp, 1); |
| 1441 | xfs_blkdev_issue_flush(btp); | 1448 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
| 1449 | xfs_blkdev_issue_flush(btp); | ||
| 1442 | xfs_free_bufhash(btp); | 1450 | xfs_free_bufhash(btp); |
| 1443 | iput(btp->bt_mapping->host); | 1451 | iput(btp->bt_mapping->host); |
| 1444 | 1452 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 288ae7c4c800..9b4d666ad31f 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
| @@ -413,7 +413,7 @@ static inline int XFS_bwrite(xfs_buf_t *bp) | |||
| 413 | * Handling of buftargs. | 413 | * Handling of buftargs. |
| 414 | */ | 414 | */ |
| 415 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); | 415 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); |
| 416 | extern void xfs_free_buftarg(xfs_buftarg_t *); | 416 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); |
| 417 | extern void xfs_wait_buftarg(xfs_buftarg_t *); | 417 | extern void xfs_wait_buftarg(xfs_buftarg_t *); |
| 418 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); | 418 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); |
| 419 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); | 419 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c71e226da7f5..32ae5028e96b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -734,15 +734,15 @@ xfs_close_devices( | |||
| 734 | { | 734 | { |
| 735 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 735 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
| 736 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; | 736 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; |
| 737 | xfs_free_buftarg(mp->m_logdev_targp); | 737 | xfs_free_buftarg(mp, mp->m_logdev_targp); |
| 738 | xfs_blkdev_put(logdev); | 738 | xfs_blkdev_put(logdev); |
| 739 | } | 739 | } |
| 740 | if (mp->m_rtdev_targp) { | 740 | if (mp->m_rtdev_targp) { |
| 741 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; | 741 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; |
| 742 | xfs_free_buftarg(mp->m_rtdev_targp); | 742 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
| 743 | xfs_blkdev_put(rtdev); | 743 | xfs_blkdev_put(rtdev); |
| 744 | } | 744 | } |
| 745 | xfs_free_buftarg(mp->m_ddev_targp); | 745 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | /* | 748 | /* |
| @@ -811,9 +811,9 @@ xfs_open_devices( | |||
| 811 | 811 | ||
| 812 | out_free_rtdev_targ: | 812 | out_free_rtdev_targ: |
| 813 | if (mp->m_rtdev_targp) | 813 | if (mp->m_rtdev_targp) |
| 814 | xfs_free_buftarg(mp->m_rtdev_targp); | 814 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
| 815 | out_free_ddev_targ: | 815 | out_free_ddev_targ: |
| 816 | xfs_free_buftarg(mp->m_ddev_targp); | 816 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
| 817 | out_close_rtdev: | 817 | out_close_rtdev: |
| 818 | if (rtdev) | 818 | if (rtdev) |
| 819 | xfs_blkdev_put(rtdev); | 819 | xfs_blkdev_put(rtdev); |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e2fb6210d4c5..478e587087fe 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -246,9 +246,6 @@ xfs_iget_cache_miss( | |||
| 246 | goto out_destroy; | 246 | goto out_destroy; |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | if (lock_flags) | ||
| 250 | xfs_ilock(ip, lock_flags); | ||
| 251 | |||
| 252 | /* | 249 | /* |
| 253 | * Preload the radix tree so we can insert safely under the | 250 | * Preload the radix tree so we can insert safely under the |
| 254 | * write spinlock. Note that we cannot sleep inside the preload | 251 | * write spinlock. Note that we cannot sleep inside the preload |
| @@ -256,7 +253,16 @@ xfs_iget_cache_miss( | |||
| 256 | */ | 253 | */ |
| 257 | if (radix_tree_preload(GFP_KERNEL)) { | 254 | if (radix_tree_preload(GFP_KERNEL)) { |
| 258 | error = EAGAIN; | 255 | error = EAGAIN; |
| 259 | goto out_unlock; | 256 | goto out_destroy; |
| 257 | } | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Because the inode hasn't been added to the radix-tree yet it can't | ||
| 261 | * be found by another thread, so we can do the non-sleeping lock here. | ||
| 262 | */ | ||
| 263 | if (lock_flags) { | ||
| 264 | if (!xfs_ilock_nowait(ip, lock_flags)) | ||
| 265 | BUG(); | ||
| 260 | } | 266 | } |
| 261 | 267 | ||
| 262 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | 268 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); |
| @@ -284,7 +290,6 @@ xfs_iget_cache_miss( | |||
| 284 | out_preload_end: | 290 | out_preload_end: |
| 285 | write_unlock(&pag->pag_ici_lock); | 291 | write_unlock(&pag->pag_ici_lock); |
| 286 | radix_tree_preload_end(); | 292 | radix_tree_preload_end(); |
| 287 | out_unlock: | ||
| 288 | if (lock_flags) | 293 | if (lock_flags) |
| 289 | xfs_iunlock(ip, lock_flags); | 294 | xfs_iunlock(ip, lock_flags); |
| 290 | out_destroy: | 295 | out_destroy: |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b1047de2fffd..61af610d79b3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -1455,10 +1455,19 @@ xlog_recover_add_to_trans( | |||
| 1455 | item = item->ri_prev; | 1455 | item = item->ri_prev; |
| 1456 | 1456 | ||
| 1457 | if (item->ri_total == 0) { /* first region to be added */ | 1457 | if (item->ri_total == 0) { /* first region to be added */ |
| 1458 | item->ri_total = in_f->ilf_size; | 1458 | if (in_f->ilf_size == 0 || |
| 1459 | ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM); | 1459 | in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { |
| 1460 | item->ri_buf = kmem_zalloc((item->ri_total * | 1460 | xlog_warn( |
| 1461 | sizeof(xfs_log_iovec_t)), KM_SLEEP); | 1461 | "XFS: bad number of regions (%d) in inode log format", |
| 1462 | in_f->ilf_size); | ||
| 1463 | ASSERT(0); | ||
| 1464 | return XFS_ERROR(EIO); | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | item->ri_total = in_f->ilf_size; | ||
| 1468 | item->ri_buf = | ||
| 1469 | kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), | ||
| 1470 | KM_SLEEP); | ||
| 1462 | } | 1471 | } |
| 1463 | ASSERT(item->ri_total > item->ri_cnt); | 1472 | ASSERT(item->ri_total > item->ri_cnt); |
| 1464 | /* Description region is ri_buf[0] */ | 1473 | /* Description region is ri_buf[0] */ |
