diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/Kconfig | 3 | ||||
-rw-r--r-- | fs/nfs/direct.c | 3 | ||||
-rw-r--r-- | fs/nfs/file.c | 2 | ||||
-rw-r--r-- | fs/nfs/fscache.c | 9 | ||||
-rw-r--r-- | fs/nfs/inode.c | 4 | ||||
-rw-r--r-- | fs/nfs/mount_clnt.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 2 | ||||
-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/nfs4xdr.c | 6 | ||||
-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 | 6 |
15 files changed, 107 insertions, 46 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 59e5673b4597..a43d07e7b924 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig | |||
@@ -95,8 +95,7 @@ config ROOT_NFS | |||
95 | Most people say N here. | 95 | Most people say N here. |
96 | 96 | ||
97 | config NFS_FSCACHE | 97 | config NFS_FSCACHE |
98 | bool "Provide NFS client caching support (EXPERIMENTAL)" | 98 | bool "Provide NFS client caching support" |
99 | depends on EXPERIMENTAL | ||
100 | depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y | 99 | depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y |
101 | help | 100 | help |
102 | Say Y here if you want NFS data to be cached locally on disc through | 101 | Say Y here if you want NFS data to be cached locally on disc through |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index e1d415e97849..0d289823e856 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -342,6 +342,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
342 | data->res.fattr = &data->fattr; | 342 | data->res.fattr = &data->fattr; |
343 | data->res.eof = 0; | 343 | data->res.eof = 0; |
344 | data->res.count = bytes; | 344 | data->res.count = bytes; |
345 | nfs_fattr_init(&data->fattr); | ||
345 | msg.rpc_argp = &data->args; | 346 | msg.rpc_argp = &data->args; |
346 | msg.rpc_resp = &data->res; | 347 | msg.rpc_resp = &data->res; |
347 | 348 | ||
@@ -575,6 +576,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
575 | data->res.count = 0; | 576 | data->res.count = 0; |
576 | data->res.fattr = &data->fattr; | 577 | data->res.fattr = &data->fattr; |
577 | data->res.verf = &data->verf; | 578 | data->res.verf = &data->verf; |
579 | nfs_fattr_init(&data->fattr); | ||
578 | 580 | ||
579 | NFS_PROTO(data->inode)->commit_setup(data, &msg); | 581 | NFS_PROTO(data->inode)->commit_setup(data, &msg); |
580 | 582 | ||
@@ -766,6 +768,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, | |||
766 | data->res.fattr = &data->fattr; | 768 | data->res.fattr = &data->fattr; |
767 | data->res.count = bytes; | 769 | data->res.count = bytes; |
768 | data->res.verf = &data->verf; | 770 | data->res.verf = &data->verf; |
771 | nfs_fattr_init(&data->fattr); | ||
769 | 772 | ||
770 | task_setup_data.task = &data->task; | 773 | task_setup_data.task = &data->task; |
771 | task_setup_data.callback_data = data; | 774 | task_setup_data.callback_data = data; |
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/fscache.c b/fs/nfs/fscache.c index fa588006588d..237874f1af23 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -354,12 +354,11 @@ void nfs_fscache_reset_inode_cookie(struct inode *inode) | |||
354 | */ | 354 | */ |
355 | int nfs_fscache_release_page(struct page *page, gfp_t gfp) | 355 | int nfs_fscache_release_page(struct page *page, gfp_t gfp) |
356 | { | 356 | { |
357 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); | ||
358 | struct fscache_cookie *cookie = nfsi->fscache; | ||
359 | |||
360 | BUG_ON(!cookie); | ||
361 | |||
362 | if (PageFsCache(page)) { | 357 | if (PageFsCache(page)) { |
358 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); | ||
359 | struct fscache_cookie *cookie = nfsi->fscache; | ||
360 | |||
361 | BUG_ON(!cookie); | ||
363 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", | 362 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", |
364 | cookie, page, nfsi); | 363 | cookie, page, nfsi); |
365 | 364 | ||
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/mount_clnt.c b/fs/nfs/mount_clnt.c index 0adefc40cc89..59047f8d7d72 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -120,7 +120,7 @@ static struct { | |||
120 | { .status = MNT3ERR_INVAL, .errno = -EINVAL, }, | 120 | { .status = MNT3ERR_INVAL, .errno = -EINVAL, }, |
121 | { .status = MNT3ERR_NAMETOOLONG, .errno = -ENAMETOOLONG, }, | 121 | { .status = MNT3ERR_NAMETOOLONG, .errno = -ENAMETOOLONG, }, |
122 | { .status = MNT3ERR_NOTSUPP, .errno = -ENOTSUPP, }, | 122 | { .status = MNT3ERR_NOTSUPP, .errno = -ENOTSUPP, }, |
123 | { .status = MNT3ERR_SERVERFAULT, .errno = -ESERVERFAULT, }, | 123 | { .status = MNT3ERR_SERVERFAULT, .errno = -EREMOTEIO, }, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | struct mountres { | 126 | struct mountres { |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 5e078b222b4e..7bc2da8efd4a 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -699,7 +699,7 @@ static struct { | |||
699 | { NFSERR_BAD_COOKIE, -EBADCOOKIE }, | 699 | { NFSERR_BAD_COOKIE, -EBADCOOKIE }, |
700 | { NFSERR_NOTSUPP, -ENOTSUPP }, | 700 | { NFSERR_NOTSUPP, -ENOTSUPP }, |
701 | { NFSERR_TOOSMALL, -ETOOSMALL }, | 701 | { NFSERR_TOOSMALL, -ETOOSMALL }, |
702 | { NFSERR_SERVERFAULT, -ESERVERFAULT }, | 702 | { NFSERR_SERVERFAULT, -EREMOTEIO }, |
703 | { NFSERR_BADTYPE, -EBADTYPE }, | 703 | { NFSERR_BADTYPE, -EBADTYPE }, |
704 | { NFSERR_JUKEBOX, -EJUKEBOX }, | 704 | { NFSERR_JUKEBOX, -EJUKEBOX }, |
705 | { -1, -EIO } | 705 | { -1, -EIO } |
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/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e437fd6a819f..5cd5184b56db 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4631,7 +4631,7 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
4631 | * If the server returns different values for sessionID, slotID or | 4631 | * If the server returns different values for sessionID, slotID or |
4632 | * sequence number, the server is looney tunes. | 4632 | * sequence number, the server is looney tunes. |
4633 | */ | 4633 | */ |
4634 | status = -ESERVERFAULT; | 4634 | status = -EREMOTEIO; |
4635 | 4635 | ||
4636 | if (memcmp(id.data, res->sr_session->sess_id.data, | 4636 | if (memcmp(id.data, res->sr_session->sess_id.data, |
4637 | NFS4_MAX_SESSIONID_LEN)) { | 4637 | NFS4_MAX_SESSIONID_LEN)) { |
@@ -5774,7 +5774,7 @@ static struct { | |||
5774 | { NFS4ERR_BAD_COOKIE, -EBADCOOKIE }, | 5774 | { NFS4ERR_BAD_COOKIE, -EBADCOOKIE }, |
5775 | { NFS4ERR_NOTSUPP, -ENOTSUPP }, | 5775 | { NFS4ERR_NOTSUPP, -ENOTSUPP }, |
5776 | { NFS4ERR_TOOSMALL, -ETOOSMALL }, | 5776 | { NFS4ERR_TOOSMALL, -ETOOSMALL }, |
5777 | { NFS4ERR_SERVERFAULT, -ESERVERFAULT }, | 5777 | { NFS4ERR_SERVERFAULT, -EREMOTEIO }, |
5778 | { NFS4ERR_BADTYPE, -EBADTYPE }, | 5778 | { NFS4ERR_BADTYPE, -EBADTYPE }, |
5779 | { NFS4ERR_LOCKED, -EAGAIN }, | 5779 | { NFS4ERR_LOCKED, -EAGAIN }, |
5780 | { NFS4ERR_SYMLINK, -ELOOP }, | 5780 | { NFS4ERR_SYMLINK, -ELOOP }, |
@@ -5801,7 +5801,7 @@ nfs4_stat_to_errno(int stat) | |||
5801 | } | 5801 | } |
5802 | if (stat <= 10000 || stat > 10100) { | 5802 | if (stat <= 10000 || stat > 10100) { |
5803 | /* The server is looney tunes. */ | 5803 | /* The server is looney tunes. */ |
5804 | return -ESERVERFAULT; | 5804 | return -EREMOTEIO; |
5805 | } | 5805 | } |
5806 | /* If we cannot translate the error, the recovery routines should | 5806 | /* If we cannot translate the error, the recovery routines should |
5807 | * handle it. | 5807 | * handle it. |
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..d63d964a0392 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 | } |
@@ -1597,8 +1598,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage, | |||
1597 | struct nfs_page *req; | 1598 | struct nfs_page *req; |
1598 | int ret; | 1599 | int ret; |
1599 | 1600 | ||
1600 | if (PageFsCache(page)) | 1601 | nfs_fscache_release_page(page, GFP_KERNEL); |
1601 | nfs_fscache_release_page(page, GFP_KERNEL); | ||
1602 | 1602 | ||
1603 | req = nfs_find_and_lock_request(page); | 1603 | req = nfs_find_and_lock_request(page); |
1604 | ret = PTR_ERR(req); | 1604 | ret = PTR_ERR(req); |