diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-02-04 22:16:39 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-02-04 22:16:39 -0500 |
commit | 8e04221029067cbaff3fc8f4daf991532afbcbaf (patch) | |
tree | 18cf757bcd315c76f5f458aa72a0a57db0a78985 /fs | |
parent | 9ad62ec4f752c82b39aa5927f23d894b46ae10b9 (diff) | |
parent | 2c940db250c1610d95ea5331dc819b8bd4db96ae (diff) |
Merge branch 'sh/stable-updates'
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bio-integrity.c | 3 | ||||
-rw-r--r-- | fs/bio.c | 7 | ||||
-rw-r--r-- | fs/exec.c | 10 | ||||
-rw-r--r-- | fs/fuse/file.c | 3 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 4 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 2 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 2 | ||||
-rw-r--r-- | fs/gfs2/lock_dlm.c | 11 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 12 | ||||
-rw-r--r-- | fs/gfs2/ops_inode.c | 3 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 8 | ||||
-rw-r--r-- | fs/gfs2/super.c | 1 | ||||
-rw-r--r-- | fs/nfs/file.c | 2 | ||||
-rw-r--r-- | fs/nfs/inode.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 78 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 2 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 17 | ||||
-rw-r--r-- | fs/nfs/super.c | 15 | ||||
-rw-r--r-- | fs/nfs/sysctl.c | 2 | ||||
-rw-r--r-- | fs/nfs/write.c | 3 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 2 |
22 files changed, 141 insertions, 52 deletions
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 49a34e7f7306..a16f29e888cd 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
@@ -61,7 +61,7 @@ static inline unsigned int vecs_to_idx(unsigned int nr) | |||
61 | 61 | ||
62 | static inline int use_bip_pool(unsigned int idx) | 62 | static inline int use_bip_pool(unsigned int idx) |
63 | { | 63 | { |
64 | if (idx == BIOVEC_NR_POOLS) | 64 | if (idx == BIOVEC_MAX_IDX) |
65 | return 1; | 65 | return 1; |
66 | 66 | ||
67 | return 0; | 67 | return 0; |
@@ -95,6 +95,7 @@ struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio, | |||
95 | 95 | ||
96 | /* Use mempool if lower order alloc failed or max vecs were requested */ | 96 | /* Use mempool if lower order alloc failed or max vecs were requested */ |
97 | if (bip == NULL) { | 97 | if (bip == NULL) { |
98 | idx = BIOVEC_MAX_IDX; /* so we free the payload properly later */ | ||
98 | bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask); | 99 | bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask); |
99 | 100 | ||
100 | if (unlikely(bip == NULL)) { | 101 | if (unlikely(bip == NULL)) { |
@@ -542,13 +542,18 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
542 | 542 | ||
543 | if (page == prev->bv_page && | 543 | if (page == prev->bv_page && |
544 | offset == prev->bv_offset + prev->bv_len) { | 544 | offset == prev->bv_offset + prev->bv_len) { |
545 | unsigned int prev_bv_len = prev->bv_len; | ||
545 | prev->bv_len += len; | 546 | prev->bv_len += len; |
546 | 547 | ||
547 | if (q->merge_bvec_fn) { | 548 | if (q->merge_bvec_fn) { |
548 | struct bvec_merge_data bvm = { | 549 | struct bvec_merge_data bvm = { |
550 | /* prev_bvec is already charged in | ||
551 | bi_size, discharge it in order to | ||
552 | simulate merging updated prev_bvec | ||
553 | as new bvec. */ | ||
549 | .bi_bdev = bio->bi_bdev, | 554 | .bi_bdev = bio->bi_bdev, |
550 | .bi_sector = bio->bi_sector, | 555 | .bi_sector = bio->bi_sector, |
551 | .bi_size = bio->bi_size, | 556 | .bi_size = bio->bi_size - prev_bv_len, |
552 | .bi_rw = bio->bi_rw, | 557 | .bi_rw = bio->bi_rw, |
553 | }; | 558 | }; |
554 | 559 | ||
@@ -961,6 +961,11 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
961 | goto out; | 961 | goto out; |
962 | 962 | ||
963 | bprm->mm = NULL; /* We're using it now */ | 963 | bprm->mm = NULL; /* We're using it now */ |
964 | |||
965 | current->flags &= ~PF_RANDOMIZE; | ||
966 | flush_thread(); | ||
967 | current->personality &= ~bprm->per_clear; | ||
968 | |||
964 | return 0; | 969 | return 0; |
965 | 970 | ||
966 | out: | 971 | out: |
@@ -997,9 +1002,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
997 | tcomm[i] = '\0'; | 1002 | tcomm[i] = '\0'; |
998 | set_task_comm(current, tcomm); | 1003 | set_task_comm(current, tcomm); |
999 | 1004 | ||
1000 | current->flags &= ~PF_RANDOMIZE; | ||
1001 | flush_thread(); | ||
1002 | |||
1003 | /* Set the new mm task size. We have to do that late because it may | 1005 | /* Set the new mm task size. We have to do that late because it may |
1004 | * depend on TIF_32BIT which is only updated in flush_thread() on | 1006 | * depend on TIF_32BIT which is only updated in flush_thread() on |
1005 | * some architectures like powerpc | 1007 | * some architectures like powerpc |
@@ -1015,8 +1017,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
1015 | set_dumpable(current->mm, suid_dumpable); | 1017 | set_dumpable(current->mm, suid_dumpable); |
1016 | } | 1018 | } |
1017 | 1019 | ||
1018 | current->personality &= ~bprm->per_clear; | ||
1019 | |||
1020 | /* | 1020 | /* |
1021 | * Flush performance counters when crossing a | 1021 | * Flush performance counters when crossing a |
1022 | * security domain: | 1022 | * security domain: |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c18913a777ae..a9f5e137f1d3 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -828,6 +828,9 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, | |||
828 | if (!page) | 828 | if (!page) |
829 | break; | 829 | break; |
830 | 830 | ||
831 | if (mapping_writably_mapped(mapping)) | ||
832 | flush_dcache_page(page); | ||
833 | |||
831 | pagefault_disable(); | 834 | pagefault_disable(); |
832 | tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes); | 835 | tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes); |
833 | pagefault_enable(); | 836 | pagefault_enable(); |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f455a03a09e2..f42663325931 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -769,6 +769,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
769 | if (!gl) | 769 | if (!gl) |
770 | return -ENOMEM; | 770 | return -ENOMEM; |
771 | 771 | ||
772 | atomic_inc(&sdp->sd_glock_disposal); | ||
772 | gl->gl_flags = 0; | 773 | gl->gl_flags = 0; |
773 | gl->gl_name = name; | 774 | gl->gl_name = name; |
774 | atomic_set(&gl->gl_ref, 1); | 775 | atomic_set(&gl->gl_ref, 1); |
@@ -1538,6 +1539,9 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) | |||
1538 | up_write(&gfs2_umount_flush_sem); | 1539 | up_write(&gfs2_umount_flush_sem); |
1539 | msleep(10); | 1540 | msleep(10); |
1540 | } | 1541 | } |
1542 | flush_workqueue(glock_workqueue); | ||
1543 | wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); | ||
1544 | gfs2_dump_lockstate(sdp); | ||
1541 | } | 1545 | } |
1542 | 1546 | ||
1543 | void gfs2_glock_finish_truncate(struct gfs2_inode *ip) | 1547 | void gfs2_glock_finish_truncate(struct gfs2_inode *ip) |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 13f0bd228132..c0262faf4725 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -123,7 +123,7 @@ struct lm_lockops { | |||
123 | int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname); | 123 | int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname); |
124 | void (*lm_unmount) (struct gfs2_sbd *sdp); | 124 | void (*lm_unmount) (struct gfs2_sbd *sdp); |
125 | void (*lm_withdraw) (struct gfs2_sbd *sdp); | 125 | void (*lm_withdraw) (struct gfs2_sbd *sdp); |
126 | void (*lm_put_lock) (struct kmem_cache *cachep, void *gl); | 126 | void (*lm_put_lock) (struct kmem_cache *cachep, struct gfs2_glock *gl); |
127 | unsigned int (*lm_lock) (struct gfs2_glock *gl, | 127 | unsigned int (*lm_lock) (struct gfs2_glock *gl, |
128 | unsigned int req_state, unsigned int flags); | 128 | unsigned int req_state, unsigned int flags); |
129 | void (*lm_cancel) (struct gfs2_glock *gl); | 129 | void (*lm_cancel) (struct gfs2_glock *gl); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 4792200978c8..bc0ad158e6b4 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -544,6 +544,8 @@ struct gfs2_sbd { | |||
544 | struct gfs2_holder sd_live_gh; | 544 | struct gfs2_holder sd_live_gh; |
545 | struct gfs2_glock *sd_rename_gl; | 545 | struct gfs2_glock *sd_rename_gl; |
546 | struct gfs2_glock *sd_trans_gl; | 546 | struct gfs2_glock *sd_trans_gl; |
547 | wait_queue_head_t sd_glock_wait; | ||
548 | atomic_t sd_glock_disposal; | ||
547 | 549 | ||
548 | /* Inode Stuff */ | 550 | /* Inode Stuff */ |
549 | 551 | ||
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 46df988323bc..0e5e0e7022e5 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c | |||
@@ -21,6 +21,7 @@ static void gdlm_ast(void *arg) | |||
21 | { | 21 | { |
22 | struct gfs2_glock *gl = arg; | 22 | struct gfs2_glock *gl = arg; |
23 | unsigned ret = gl->gl_state; | 23 | unsigned ret = gl->gl_state; |
24 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
24 | 25 | ||
25 | BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED); | 26 | BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED); |
26 | 27 | ||
@@ -30,6 +31,8 @@ static void gdlm_ast(void *arg) | |||
30 | switch (gl->gl_lksb.sb_status) { | 31 | switch (gl->gl_lksb.sb_status) { |
31 | case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */ | 32 | case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */ |
32 | kmem_cache_free(gfs2_glock_cachep, gl); | 33 | kmem_cache_free(gfs2_glock_cachep, gl); |
34 | if (atomic_dec_and_test(&sdp->sd_glock_disposal)) | ||
35 | wake_up(&sdp->sd_glock_wait); | ||
33 | return; | 36 | return; |
34 | case -DLM_ECANCEL: /* Cancel while getting lock */ | 37 | case -DLM_ECANCEL: /* Cancel while getting lock */ |
35 | ret |= LM_OUT_CANCELED; | 38 | ret |= LM_OUT_CANCELED; |
@@ -164,14 +167,16 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl, | |||
164 | return LM_OUT_ASYNC; | 167 | return LM_OUT_ASYNC; |
165 | } | 168 | } |
166 | 169 | ||
167 | static void gdlm_put_lock(struct kmem_cache *cachep, void *ptr) | 170 | static void gdlm_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl) |
168 | { | 171 | { |
169 | struct gfs2_glock *gl = ptr; | 172 | struct gfs2_sbd *sdp = gl->gl_sbd; |
170 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; | 173 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
171 | int error; | 174 | int error; |
172 | 175 | ||
173 | if (gl->gl_lksb.sb_lkid == 0) { | 176 | if (gl->gl_lksb.sb_lkid == 0) { |
174 | kmem_cache_free(cachep, gl); | 177 | kmem_cache_free(cachep, gl); |
178 | if (atomic_dec_and_test(&sdp->sd_glock_disposal)) | ||
179 | wake_up(&sdp->sd_glock_wait); | ||
175 | return; | 180 | return; |
176 | } | 181 | } |
177 | 182 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index edfee24f3636..8a102f731003 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -82,6 +82,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
82 | 82 | ||
83 | gfs2_tune_init(&sdp->sd_tune); | 83 | gfs2_tune_init(&sdp->sd_tune); |
84 | 84 | ||
85 | init_waitqueue_head(&sdp->sd_glock_wait); | ||
86 | atomic_set(&sdp->sd_glock_disposal, 0); | ||
85 | spin_lock_init(&sdp->sd_statfs_spin); | 87 | spin_lock_init(&sdp->sd_statfs_spin); |
86 | 88 | ||
87 | spin_lock_init(&sdp->sd_rindex_spin); | 89 | spin_lock_init(&sdp->sd_rindex_spin); |
@@ -983,9 +985,17 @@ static const match_table_t nolock_tokens = { | |||
983 | { Opt_err, NULL }, | 985 | { Opt_err, NULL }, |
984 | }; | 986 | }; |
985 | 987 | ||
988 | static void nolock_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl) | ||
989 | { | ||
990 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
991 | kmem_cache_free(cachep, gl); | ||
992 | if (atomic_dec_and_test(&sdp->sd_glock_disposal)) | ||
993 | wake_up(&sdp->sd_glock_wait); | ||
994 | } | ||
995 | |||
986 | static const struct lm_lockops nolock_ops = { | 996 | static const struct lm_lockops nolock_ops = { |
987 | .lm_proto_name = "lock_nolock", | 997 | .lm_proto_name = "lock_nolock", |
988 | .lm_put_lock = kmem_cache_free, | 998 | .lm_put_lock = nolock_put_lock, |
989 | .lm_tokens = &nolock_tokens, | 999 | .lm_tokens = &nolock_tokens, |
990 | }; | 1000 | }; |
991 | 1001 | ||
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 78f73ca1ef3e..84350e1be66d 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -1088,7 +1088,8 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1088 | error = vfs_follow_link(nd, buf); | 1088 | error = vfs_follow_link(nd, buf); |
1089 | if (buf != array) | 1089 | if (buf != array) |
1090 | kfree(buf); | 1090 | kfree(buf); |
1091 | } | 1091 | } else |
1092 | path_put(&nd->path); | ||
1092 | 1093 | ||
1093 | return ERR_PTR(error); | 1094 | return ERR_PTR(error); |
1094 | } | 1095 | } |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 0608f490c295..503b842f3ba2 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -591,11 +591,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
591 | u64 rgrp_count = ip->i_disksize; | 591 | u64 rgrp_count = ip->i_disksize; |
592 | int error; | 592 | int error; |
593 | 593 | ||
594 | if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) { | 594 | do_div(rgrp_count, sizeof(struct gfs2_rindex)); |
595 | gfs2_consist_inode(ip); | ||
596 | return -EIO; | ||
597 | } | ||
598 | |||
599 | clear_rgrpdi(sdp); | 595 | clear_rgrpdi(sdp); |
600 | 596 | ||
601 | file_ra_state_init(&ra_state, inode->i_mapping); | 597 | file_ra_state_init(&ra_state, inode->i_mapping); |
@@ -915,7 +911,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | |||
915 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) | 911 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) |
916 | { | 912 | { |
917 | BUG_ON(ip->i_alloc != NULL); | 913 | BUG_ON(ip->i_alloc != NULL); |
918 | ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_KERNEL); | 914 | ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_NOFS); |
919 | return ip->i_alloc; | 915 | return ip->i_alloc; |
920 | } | 916 | } |
921 | 917 | ||
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index c282ad41f3d1..b9dd3da22c0a 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/gfs2_ondisk.h> | 21 | #include <linux/gfs2_ondisk.h> |
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/time.h> | 23 | #include <linux/time.h> |
24 | #include <linux/wait.h> | ||
24 | 25 | ||
25 | #include "gfs2.h" | 26 | #include "gfs2.h" |
26 | #include "incore.h" | 27 | #include "incore.h" |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 6b891328f332..63f2071d6445 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -486,6 +486,8 @@ static int nfs_release_page(struct page *page, gfp_t gfp) | |||
486 | { | 486 | { |
487 | dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); | 487 | dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); |
488 | 488 | ||
489 | if (gfp & __GFP_WAIT) | ||
490 | nfs_wb_page(page->mapping->host, page); | ||
489 | /* If PagePrivate() is set, then the page is not freeable */ | 491 | /* If PagePrivate() is set, then the page is not freeable */ |
490 | if (PagePrivate(page)) | 492 | if (PagePrivate(page)) |
491 | return 0; | 493 | return 0; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index faa091865ad0..f141bde7756a 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1261,8 +1261,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1261 | 1261 | ||
1262 | if (fattr->valid & NFS_ATTR_FATTR_MODE) { | 1262 | if (fattr->valid & NFS_ATTR_FATTR_MODE) { |
1263 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { | 1263 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { |
1264 | umode_t newmode = inode->i_mode & S_IFMT; | ||
1265 | newmode |= fattr->mode & S_IALLUGO; | ||
1266 | inode->i_mode = newmode; | ||
1264 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1267 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1265 | inode->i_mode = fattr->mode; | ||
1266 | } | 1268 | } |
1267 | } else if (server->caps & NFS_CAP_MODE) | 1269 | } else if (server->caps & NFS_CAP_MODE) |
1268 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | 1270 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 865265bdca03..0c6fda33d66e 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -146,6 +146,7 @@ enum { | |||
146 | NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ | 146 | NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ |
147 | NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ | 147 | NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ |
148 | NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */ | 148 | NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */ |
149 | NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */ | ||
149 | }; | 150 | }; |
150 | 151 | ||
151 | struct nfs4_state { | 152 | struct nfs4_state { |
@@ -277,6 +278,7 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t); | |||
277 | extern void nfs4_schedule_state_recovery(struct nfs_client *); | 278 | extern void nfs4_schedule_state_recovery(struct nfs_client *); |
278 | extern void nfs4_schedule_state_manager(struct nfs_client *); | 279 | extern void nfs4_schedule_state_manager(struct nfs_client *); |
279 | extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); | 280 | extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); |
281 | extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state); | ||
280 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); | 282 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); |
281 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); | 283 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); |
282 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); | 284 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 198d51d17c13..375f0fae2c6a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -249,19 +249,15 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
249 | if (state == NULL) | 249 | if (state == NULL) |
250 | break; | 250 | break; |
251 | nfs4_state_mark_reclaim_nograce(clp, state); | 251 | nfs4_state_mark_reclaim_nograce(clp, state); |
252 | case -NFS4ERR_STALE_CLIENTID: | 252 | goto do_state_recovery; |
253 | case -NFS4ERR_STALE_STATEID: | 253 | case -NFS4ERR_STALE_STATEID: |
254 | case -NFS4ERR_EXPIRED: | 254 | if (state == NULL) |
255 | nfs4_schedule_state_recovery(clp); | ||
256 | ret = nfs4_wait_clnt_recover(clp); | ||
257 | if (ret == 0) | ||
258 | exception->retry = 1; | ||
259 | #if !defined(CONFIG_NFS_V4_1) | ||
260 | break; | ||
261 | #else /* !defined(CONFIG_NFS_V4_1) */ | ||
262 | if (!nfs4_has_session(server->nfs_client)) | ||
263 | break; | 255 | break; |
264 | /* FALLTHROUGH */ | 256 | nfs4_state_mark_reclaim_reboot(clp, state); |
257 | case -NFS4ERR_STALE_CLIENTID: | ||
258 | case -NFS4ERR_EXPIRED: | ||
259 | goto do_state_recovery; | ||
260 | #if defined(CONFIG_NFS_V4_1) | ||
265 | case -NFS4ERR_BADSESSION: | 261 | case -NFS4ERR_BADSESSION: |
266 | case -NFS4ERR_BADSLOT: | 262 | case -NFS4ERR_BADSLOT: |
267 | case -NFS4ERR_BAD_HIGH_SLOT: | 263 | case -NFS4ERR_BAD_HIGH_SLOT: |
@@ -274,7 +270,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
274 | nfs4_schedule_state_recovery(clp); | 270 | nfs4_schedule_state_recovery(clp); |
275 | exception->retry = 1; | 271 | exception->retry = 1; |
276 | break; | 272 | break; |
277 | #endif /* !defined(CONFIG_NFS_V4_1) */ | 273 | #endif /* defined(CONFIG_NFS_V4_1) */ |
278 | case -NFS4ERR_FILE_OPEN: | 274 | case -NFS4ERR_FILE_OPEN: |
279 | if (exception->timeout > HZ) { | 275 | if (exception->timeout > HZ) { |
280 | /* We have retried a decent amount, time to | 276 | /* We have retried a decent amount, time to |
@@ -293,6 +289,12 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
293 | } | 289 | } |
294 | /* We failed to handle the error */ | 290 | /* We failed to handle the error */ |
295 | return nfs4_map_errors(ret); | 291 | return nfs4_map_errors(ret); |
292 | do_state_recovery: | ||
293 | nfs4_schedule_state_recovery(clp); | ||
294 | ret = nfs4_wait_clnt_recover(clp); | ||
295 | if (ret == 0) | ||
296 | exception->retry = 1; | ||
297 | return ret; | ||
296 | } | 298 | } |
297 | 299 | ||
298 | 300 | ||
@@ -1658,6 +1660,8 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in | |||
1658 | status = PTR_ERR(state); | 1660 | status = PTR_ERR(state); |
1659 | if (IS_ERR(state)) | 1661 | if (IS_ERR(state)) |
1660 | goto err_opendata_put; | 1662 | goto err_opendata_put; |
1663 | if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0) | ||
1664 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); | ||
1661 | nfs4_opendata_put(opendata); | 1665 | nfs4_opendata_put(opendata); |
1662 | nfs4_put_state_owner(sp); | 1666 | nfs4_put_state_owner(sp); |
1663 | *res = state; | 1667 | *res = state; |
@@ -3422,15 +3426,14 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3422 | if (state == NULL) | 3426 | if (state == NULL) |
3423 | break; | 3427 | break; |
3424 | nfs4_state_mark_reclaim_nograce(clp, state); | 3428 | nfs4_state_mark_reclaim_nograce(clp, state); |
3425 | case -NFS4ERR_STALE_CLIENTID: | 3429 | goto do_state_recovery; |
3426 | case -NFS4ERR_STALE_STATEID: | 3430 | case -NFS4ERR_STALE_STATEID: |
3431 | if (state == NULL) | ||
3432 | break; | ||
3433 | nfs4_state_mark_reclaim_reboot(clp, state); | ||
3434 | case -NFS4ERR_STALE_CLIENTID: | ||
3427 | case -NFS4ERR_EXPIRED: | 3435 | case -NFS4ERR_EXPIRED: |
3428 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | 3436 | goto do_state_recovery; |
3429 | nfs4_schedule_state_recovery(clp); | ||
3430 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | ||
3431 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | ||
3432 | task->tk_status = 0; | ||
3433 | return -EAGAIN; | ||
3434 | #if defined(CONFIG_NFS_V4_1) | 3437 | #if defined(CONFIG_NFS_V4_1) |
3435 | case -NFS4ERR_BADSESSION: | 3438 | case -NFS4ERR_BADSESSION: |
3436 | case -NFS4ERR_BADSLOT: | 3439 | case -NFS4ERR_BADSLOT: |
@@ -3458,6 +3461,13 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3458 | } | 3461 | } |
3459 | task->tk_status = nfs4_map_errors(task->tk_status); | 3462 | task->tk_status = nfs4_map_errors(task->tk_status); |
3460 | return 0; | 3463 | return 0; |
3464 | do_state_recovery: | ||
3465 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | ||
3466 | nfs4_schedule_state_recovery(clp); | ||
3467 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | ||
3468 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | ||
3469 | task->tk_status = 0; | ||
3470 | return -EAGAIN; | ||
3461 | } | 3471 | } |
3462 | 3472 | ||
3463 | static int | 3473 | static int |
@@ -4088,6 +4098,28 @@ static const struct rpc_call_ops nfs4_recover_lock_ops = { | |||
4088 | .rpc_release = nfs4_lock_release, | 4098 | .rpc_release = nfs4_lock_release, |
4089 | }; | 4099 | }; |
4090 | 4100 | ||
4101 | static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) | ||
4102 | { | ||
4103 | struct nfs_client *clp = server->nfs_client; | ||
4104 | struct nfs4_state *state = lsp->ls_state; | ||
4105 | |||
4106 | switch (error) { | ||
4107 | case -NFS4ERR_ADMIN_REVOKED: | ||
4108 | case -NFS4ERR_BAD_STATEID: | ||
4109 | case -NFS4ERR_EXPIRED: | ||
4110 | if (new_lock_owner != 0 || | ||
4111 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | ||
4112 | nfs4_state_mark_reclaim_nograce(clp, state); | ||
4113 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | ||
4114 | break; | ||
4115 | case -NFS4ERR_STALE_STATEID: | ||
4116 | if (new_lock_owner != 0 || | ||
4117 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | ||
4118 | nfs4_state_mark_reclaim_reboot(clp, state); | ||
4119 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | ||
4120 | }; | ||
4121 | } | ||
4122 | |||
4091 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type) | 4123 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type) |
4092 | { | 4124 | { |
4093 | struct nfs4_lockdata *data; | 4125 | struct nfs4_lockdata *data; |
@@ -4126,6 +4158,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
4126 | ret = nfs4_wait_for_completion_rpc_task(task); | 4158 | ret = nfs4_wait_for_completion_rpc_task(task); |
4127 | if (ret == 0) { | 4159 | if (ret == 0) { |
4128 | ret = data->rpc_status; | 4160 | ret = data->rpc_status; |
4161 | if (ret) | ||
4162 | nfs4_handle_setlk_error(data->server, data->lsp, | ||
4163 | data->arg.new_lock_owner, ret); | ||
4129 | } else | 4164 | } else |
4130 | data->cancelled = 1; | 4165 | data->cancelled = 1; |
4131 | rpc_put_task(task); | 4166 | rpc_put_task(task); |
@@ -4181,8 +4216,11 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock | |||
4181 | { | 4216 | { |
4182 | struct nfs_inode *nfsi = NFS_I(state->inode); | 4217 | struct nfs_inode *nfsi = NFS_I(state->inode); |
4183 | unsigned char fl_flags = request->fl_flags; | 4218 | unsigned char fl_flags = request->fl_flags; |
4184 | int status; | 4219 | int status = -ENOLCK; |
4185 | 4220 | ||
4221 | if ((fl_flags & FL_POSIX) && | ||
4222 | !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags)) | ||
4223 | goto out; | ||
4186 | /* Is this a delegated open? */ | 4224 | /* Is this a delegated open? */ |
4187 | status = nfs4_set_lock_state(state, request); | 4225 | status = nfs4_set_lock_state(state, request); |
4188 | if (status != 0) | 4226 | if (status != 0) |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6d263ed79e92..c1e2733f4fa4 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -901,7 +901,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp) | |||
901 | nfs4_schedule_state_manager(clp); | 901 | nfs4_schedule_state_manager(clp); |
902 | } | 902 | } |
903 | 903 | ||
904 | static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) | 904 | int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) |
905 | { | 905 | { |
906 | 906 | ||
907 | set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); | 907 | set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index e2975939126a..a12c45b65dd4 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -176,6 +176,12 @@ void nfs_release_request(struct nfs_page *req) | |||
176 | kref_put(&req->wb_kref, nfs_free_request); | 176 | kref_put(&req->wb_kref, nfs_free_request); |
177 | } | 177 | } |
178 | 178 | ||
179 | static int nfs_wait_bit_uninterruptible(void *word) | ||
180 | { | ||
181 | io_schedule(); | ||
182 | return 0; | ||
183 | } | ||
184 | |||
179 | /** | 185 | /** |
180 | * nfs_wait_on_request - Wait for a request to complete. | 186 | * nfs_wait_on_request - Wait for a request to complete. |
181 | * @req: request to wait upon. | 187 | * @req: request to wait upon. |
@@ -186,14 +192,9 @@ void nfs_release_request(struct nfs_page *req) | |||
186 | int | 192 | int |
187 | nfs_wait_on_request(struct nfs_page *req) | 193 | nfs_wait_on_request(struct nfs_page *req) |
188 | { | 194 | { |
189 | int ret = 0; | 195 | return wait_on_bit(&req->wb_flags, PG_BUSY, |
190 | 196 | nfs_wait_bit_uninterruptible, | |
191 | if (!test_bit(PG_BUSY, &req->wb_flags)) | 197 | TASK_UNINTERRUPTIBLE); |
192 | goto out; | ||
193 | ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY, | ||
194 | nfs_wait_bit_killable, TASK_KILLABLE); | ||
195 | out: | ||
196 | return ret; | ||
197 | } | 198 | } |
198 | 199 | ||
199 | /** | 200 | /** |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ce907efc5508..f1afee4eea77 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -243,6 +243,7 @@ static int nfs_show_stats(struct seq_file *, struct vfsmount *); | |||
243 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); | 243 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); |
244 | static int nfs_xdev_get_sb(struct file_system_type *fs_type, | 244 | static int nfs_xdev_get_sb(struct file_system_type *fs_type, |
245 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); | 245 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
246 | static void nfs_put_super(struct super_block *); | ||
246 | static void nfs_kill_super(struct super_block *); | 247 | static void nfs_kill_super(struct super_block *); |
247 | static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); | 248 | static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); |
248 | 249 | ||
@@ -266,6 +267,7 @@ static const struct super_operations nfs_sops = { | |||
266 | .alloc_inode = nfs_alloc_inode, | 267 | .alloc_inode = nfs_alloc_inode, |
267 | .destroy_inode = nfs_destroy_inode, | 268 | .destroy_inode = nfs_destroy_inode, |
268 | .write_inode = nfs_write_inode, | 269 | .write_inode = nfs_write_inode, |
270 | .put_super = nfs_put_super, | ||
269 | .statfs = nfs_statfs, | 271 | .statfs = nfs_statfs, |
270 | .clear_inode = nfs_clear_inode, | 272 | .clear_inode = nfs_clear_inode, |
271 | .umount_begin = nfs_umount_begin, | 273 | .umount_begin = nfs_umount_begin, |
@@ -335,6 +337,7 @@ static const struct super_operations nfs4_sops = { | |||
335 | .alloc_inode = nfs_alloc_inode, | 337 | .alloc_inode = nfs_alloc_inode, |
336 | .destroy_inode = nfs_destroy_inode, | 338 | .destroy_inode = nfs_destroy_inode, |
337 | .write_inode = nfs_write_inode, | 339 | .write_inode = nfs_write_inode, |
340 | .put_super = nfs_put_super, | ||
338 | .statfs = nfs_statfs, | 341 | .statfs = nfs_statfs, |
339 | .clear_inode = nfs4_clear_inode, | 342 | .clear_inode = nfs4_clear_inode, |
340 | .umount_begin = nfs_umount_begin, | 343 | .umount_begin = nfs_umount_begin, |
@@ -2258,6 +2261,17 @@ error_splat_super: | |||
2258 | } | 2261 | } |
2259 | 2262 | ||
2260 | /* | 2263 | /* |
2264 | * Ensure that we unregister the bdi before kill_anon_super | ||
2265 | * releases the device name | ||
2266 | */ | ||
2267 | static void nfs_put_super(struct super_block *s) | ||
2268 | { | ||
2269 | struct nfs_server *server = NFS_SB(s); | ||
2270 | |||
2271 | bdi_unregister(&server->backing_dev_info); | ||
2272 | } | ||
2273 | |||
2274 | /* | ||
2261 | * Destroy an NFS2/3 superblock | 2275 | * Destroy an NFS2/3 superblock |
2262 | */ | 2276 | */ |
2263 | static void nfs_kill_super(struct super_block *s) | 2277 | static void nfs_kill_super(struct super_block *s) |
@@ -2265,7 +2279,6 @@ static void nfs_kill_super(struct super_block *s) | |||
2265 | struct nfs_server *server = NFS_SB(s); | 2279 | struct nfs_server *server = NFS_SB(s); |
2266 | 2280 | ||
2267 | kill_anon_super(s); | 2281 | kill_anon_super(s); |
2268 | bdi_unregister(&server->backing_dev_info); | ||
2269 | nfs_fscache_release_super_cookie(s); | 2282 | nfs_fscache_release_super_cookie(s); |
2270 | nfs_free_server(server); | 2283 | nfs_free_server(server); |
2271 | } | 2284 | } |
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c index 70e1fbbaaeab..ad4d2e787b20 100644 --- a/fs/nfs/sysctl.c +++ b/fs/nfs/sysctl.c | |||
@@ -15,8 +15,10 @@ | |||
15 | 15 | ||
16 | #include "callback.h" | 16 | #include "callback.h" |
17 | 17 | ||
18 | #ifdef CONFIG_NFS_V4 | ||
18 | static const int nfs_set_port_min = 0; | 19 | static const int nfs_set_port_min = 0; |
19 | static const int nfs_set_port_max = 65535; | 20 | static const int nfs_set_port_max = 65535; |
21 | #endif | ||
20 | static struct ctl_table_header *nfs_callback_sysctl_table; | 22 | static struct ctl_table_header *nfs_callback_sysctl_table; |
21 | 23 | ||
22 | static ctl_table nfs_cb_sysctls[] = { | 24 | static ctl_table nfs_cb_sysctls[] = { |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index d171696017f4..7b54b8bb101f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1233,7 +1233,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) | |||
1233 | 1233 | ||
1234 | 1234 | ||
1235 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1235 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1236 | void nfs_commitdata_release(void *data) | 1236 | static void nfs_commitdata_release(void *data) |
1237 | { | 1237 | { |
1238 | struct nfs_write_data *wdata = data; | 1238 | struct nfs_write_data *wdata = data; |
1239 | 1239 | ||
@@ -1541,6 +1541,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) | |||
1541 | break; | 1541 | break; |
1542 | } | 1542 | } |
1543 | ret = nfs_wait_on_request(req); | 1543 | ret = nfs_wait_on_request(req); |
1544 | nfs_release_request(req); | ||
1544 | if (ret < 0) | 1545 | if (ret < 0) |
1545 | goto out; | 1546 | goto out; |
1546 | } | 1547 | } |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 17584c524486..105b508b47a8 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2829,7 +2829,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2829 | || sci->sc_seq_request != sci->sc_seq_done); | 2829 | || sci->sc_seq_request != sci->sc_seq_done); |
2830 | spin_unlock(&sci->sc_state_lock); | 2830 | spin_unlock(&sci->sc_state_lock); |
2831 | 2831 | ||
2832 | if (flag || nilfs_segctor_confirm(sci)) | 2832 | if (flag || !nilfs_segctor_confirm(sci)) |
2833 | nilfs_segctor_write_out(sci); | 2833 | nilfs_segctor_write_out(sci); |
2834 | 2834 | ||
2835 | WARN_ON(!list_empty(&sci->sc_copied_buffers)); | 2835 | WARN_ON(!list_empty(&sci->sc_copied_buffers)); |