Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
NFS: Don't clobber the attribute type in nfs_update_inode()
NFS: Fix a umount race
NFS: Fix an Oops when truncating a file
NFS: Ensure that we handle NFS4ERR_STALE_STATEID correctly
NFSv4.1: Don't call nfs4_schedule_state_recovery() unnecessarily
NFSv4: Don't allow posix locking against servers that don't support it
NFSv4: Ensure that the NFSv4 locking can recover from stateid errors
NFS: Avoid warnings when CONFIG_NFS_V4=n
NFS: Make nfs_commitdata_release static
NFS: Try to commit unstable writes in nfs_release_page()
NFS: Fix a reference leak in nfs_wb_cancel_page()

+93 -32
+2
fs/nfs/file.c
··· 486 486 { 487 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 491 /* If PagePrivate() is set, then the page is not freeable */ 490 492 if (PagePrivate(page)) 491 493 return 0;
+3 -1
fs/nfs/inode.c
··· 1261 1261 1262 1262 if (fattr->valid & NFS_ATTR_FATTR_MODE) { 1263 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 1267 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1265 - inode->i_mode = fattr->mode; 1266 1268 } 1267 1269 } else if (server->caps & NFS_CAP_MODE) 1268 1270 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+2
fs/nfs/nfs4_fs.h
··· 146 146 NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ 147 147 NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ 148 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 152 struct nfs4_state { ··· 278 277 extern void nfs4_schedule_state_recovery(struct nfs_client *); 279 278 extern void nfs4_schedule_state_manager(struct nfs_client *); 280 279 extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); 280 + extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state); 281 281 extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); 282 282 extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 283 283 extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
+58 -20
fs/nfs/nfs4proc.c
··· 249 249 if (state == NULL) 250 250 break; 251 251 nfs4_state_mark_reclaim_nograce(clp, state); 252 - case -NFS4ERR_STALE_CLIENTID: 252 + goto do_state_recovery; 253 253 case -NFS4ERR_STALE_STATEID: 254 - case -NFS4ERR_EXPIRED: 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)) 254 + if (state == NULL) 263 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 261 case -NFS4ERR_BADSESSION: 266 262 case -NFS4ERR_BADSLOT: 267 263 case -NFS4ERR_BAD_HIGH_SLOT: ··· 270 274 nfs4_schedule_state_recovery(clp); 271 275 exception->retry = 1; 272 276 break; 273 - #endif /* !defined(CONFIG_NFS_V4_1) */ 277 + #endif /* defined(CONFIG_NFS_V4_1) */ 274 278 case -NFS4ERR_FILE_OPEN: 275 279 if (exception->timeout > HZ) { 276 280 /* We have retried a decent amount, time to ··· 289 293 } 290 294 /* We failed to handle the error */ 291 295 return nfs4_map_errors(ret); 296 + do_state_recovery: 297 + nfs4_schedule_state_recovery(clp); 298 + ret = nfs4_wait_clnt_recover(clp); 299 + if (ret == 0) 300 + exception->retry = 1; 301 + return ret; 292 302 } 293 303 294 304 ··· 1660 1658 status = PTR_ERR(state); 1661 1659 if (IS_ERR(state)) 1662 1660 goto err_opendata_put; 1661 + if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0) 1662 + set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); 1663 1663 nfs4_opendata_put(opendata); 1664 1664 nfs4_put_state_owner(sp); 1665 1665 *res = state; ··· 3426 3422 if (state == NULL) 3427 3423 break; 3428 3424 nfs4_state_mark_reclaim_nograce(clp, state); 3429 - case -NFS4ERR_STALE_CLIENTID: 3425 + goto do_state_recovery; 3430 3426 case -NFS4ERR_STALE_STATEID: 3427 + if (state == NULL) 3428 + break; 3429 + nfs4_state_mark_reclaim_reboot(clp, state); 3430 + case -NFS4ERR_STALE_CLIENTID: 3431 3431 case -NFS4ERR_EXPIRED: 3432 - rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 3433 - nfs4_schedule_state_recovery(clp); 3434 - if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) 3435 - rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 3436 - task->tk_status = 0; 3437 - return -EAGAIN; 3432 + goto do_state_recovery; 3438 3433 #if defined(CONFIG_NFS_V4_1) 3439 3434 case -NFS4ERR_BADSESSION: 3440 3435 case -NFS4ERR_BADSLOT: ··· 3461 3458 } 3462 3459 task->tk_status = nfs4_map_errors(task->tk_status); 3463 3460 return 0; 3461 + do_state_recovery: 3462 + rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 3463 + nfs4_schedule_state_recovery(clp); 3464 + if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) 3465 + rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 3466 + task->tk_status = 0; 3467 + return -EAGAIN; 3464 3468 } 3465 3469 3466 3470 static int ··· 4098 4088 .rpc_release = nfs4_lock_release, 4099 4089 }; 4100 4090 4091 + static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) 4092 + { 4093 + struct nfs_client *clp = server->nfs_client; 4094 + struct nfs4_state *state = lsp->ls_state; 4095 + 4096 + switch (error) { 4097 + case -NFS4ERR_ADMIN_REVOKED: 4098 + case -NFS4ERR_BAD_STATEID: 4099 + case -NFS4ERR_EXPIRED: 4100 + if (new_lock_owner != 0 || 4101 + (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) 4102 + nfs4_state_mark_reclaim_nograce(clp, state); 4103 + lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; 4104 + break; 4105 + case -NFS4ERR_STALE_STATEID: 4106 + if (new_lock_owner != 0 || 4107 + (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) 4108 + nfs4_state_mark_reclaim_reboot(clp, state); 4109 + lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; 4110 + }; 4111 + } 4112 + 4101 4113 static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type) 4102 4114 { 4103 4115 struct nfs4_lockdata *data; ··· 4158 4126 ret = nfs4_wait_for_completion_rpc_task(task); 4159 4127 if (ret == 0) { 4160 4128 ret = data->rpc_status; 4129 + if (ret) 4130 + nfs4_handle_setlk_error(data->server, data->lsp, 4131 + data->arg.new_lock_owner, ret); 4161 4132 } else 4162 4133 data->cancelled = 1; 4163 4134 rpc_put_task(task); ··· 4216 4181 { 4217 4182 struct nfs_inode *nfsi = NFS_I(state->inode); 4218 4183 unsigned char fl_flags = request->fl_flags; 4219 - int status; 4184 + int status = -ENOLCK; 4220 4185 4186 + if ((fl_flags & FL_POSIX) && 4187 + !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags)) 4188 + goto out; 4221 4189 /* Is this a delegated open? */ 4222 4190 status = nfs4_set_lock_state(state, request); 4223 4191 if (status != 0)
+1 -1
fs/nfs/nfs4state.c
··· 901 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 907 set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
+9 -8
fs/nfs/pagelist.c
··· 176 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 186 * nfs_wait_on_request - Wait for a request to complete. 181 187 * @req: request to wait upon. ··· 192 186 int 193 187 nfs_wait_on_request(struct nfs_page *req) 194 188 { 195 - int ret = 0; 196 - 197 - if (!test_bit(PG_BUSY, &req->wb_flags)) 198 - goto out; 199 - ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY, 200 - nfs_wait_bit_killable, TASK_KILLABLE); 201 - out: 202 - return ret; 189 + return wait_on_bit(&req->wb_flags, PG_BUSY, 190 + nfs_wait_bit_uninterruptible, 191 + TASK_UNINTERRUPTIBLE); 203 192 } 204 193 205 194 /**
+14 -1
fs/nfs/super.c
··· 243 243 static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); 244 244 static int nfs_xdev_get_sb(struct file_system_type *fs_type, 245 245 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); 246 + static void nfs_put_super(struct super_block *); 246 247 static void nfs_kill_super(struct super_block *); 247 248 static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); 248 249 ··· 267 266 .alloc_inode = nfs_alloc_inode, 268 267 .destroy_inode = nfs_destroy_inode, 269 268 .write_inode = nfs_write_inode, 269 + .put_super = nfs_put_super, 270 270 .statfs = nfs_statfs, 271 271 .clear_inode = nfs_clear_inode, 272 272 .umount_begin = nfs_umount_begin, ··· 337 335 .alloc_inode = nfs_alloc_inode, 338 336 .destroy_inode = nfs_destroy_inode, 339 337 .write_inode = nfs_write_inode, 338 + .put_super = nfs_put_super, 340 339 .statfs = nfs_statfs, 341 340 .clear_inode = nfs4_clear_inode, 342 341 .umount_begin = nfs_umount_begin, ··· 2261 2258 } 2262 2259 2263 2260 /* 2261 + * Ensure that we unregister the bdi before kill_anon_super 2262 + * releases the device name 2263 + */ 2264 + static void nfs_put_super(struct super_block *s) 2265 + { 2266 + struct nfs_server *server = NFS_SB(s); 2267 + 2268 + bdi_unregister(&server->backing_dev_info); 2269 + } 2270 + 2271 + /* 2264 2272 * Destroy an NFS2/3 superblock 2265 2273 */ 2266 2274 static void nfs_kill_super(struct super_block *s) ··· 2279 2265 struct nfs_server *server = NFS_SB(s); 2280 2266 2281 2267 kill_anon_super(s); 2282 - bdi_unregister(&server->backing_dev_info); 2283 2268 nfs_fscache_release_super_cookie(s); 2284 2269 nfs_free_server(server); 2285 2270 }
+2
fs/nfs/sysctl.c
··· 15 15 16 16 #include "callback.h" 17 17 18 + #ifdef CONFIG_NFS_V4 18 19 static const int nfs_set_port_min = 0; 19 20 static const int nfs_set_port_max = 65535; 21 + #endif 20 22 static struct ctl_table_header *nfs_callback_sysctl_table; 21 23 22 24 static ctl_table nfs_cb_sysctls[] = {
+2 -1
fs/nfs/write.c
··· 1233 1233 1234 1234 1235 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 1238 struct nfs_write_data *wdata = data; 1239 1239 ··· 1541 1541 break; 1542 1542 } 1543 1543 ret = nfs_wait_on_request(req); 1544 + nfs_release_request(req); 1544 1545 if (ret < 0) 1545 1546 goto out; 1546 1547 }