History

Merge tag 'nfs-for-4.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull more NFS client updates from Trond Myklebust: "Highlights include: - further attribute cache improvements to make revalidation more fine grained - NFSv4 locking improvements Bugfixes: - nfs4_fl_prepare_ds must be careful about reporting success in files layout - pNFS/flexfiles: Instead of marking a device inactive, remove it from the cache" * tag 'nfs-for-4.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFSv4: Retry the DELEGRETURN if the embedded GETATTR is rejected with EACCES NFS: Retry the CLOSE if the embedded GETATTR is rejected with EACCES NFSv4: Place the GETATTR operation before the CLOSE NFSv4: Also ask for attributes when downgrading to a READ-only state NFS: Don't abuse NFS_INO_REVAL_FORCED in nfs_post_op_update_inode_locked() pNFS: Return RW layouts on OPEN_DOWNGRADE NFSv4: Add encode/decode of the layoutreturn op in OPEN_DOWNGRADE NFS: Don't disconnect open-owner on NFS4ERR_BAD_SEQID NFSv4: ensure __nfs4_find_lock_state returns consistent result. NFSv4.1: nfs4_fl_prepare_ds must be careful about reporting success. pNFS/flexfiles: delete deviceid, don't mark inactive NFS: Clean up nfs_attribute_timeout() NFS: Remove unused function nfs_revalidate_inode_rcu() NFS: Fix and clean up the access cache validity checking NFS: Only look at the change attribute cache state in nfs_weak_revalidate() NFS: Clean up cache validity checking NFS: Don't revalidate the file on close if we hold a delegation NFSv4: Don't discard the attributes returned by asynchronous DELEGRETURN NFSv4: Update the attribute cache info in update_changeattr

Linus Torvalds committed 9 years ago

Commit bc1ecd62 parents d5db84a 8ac2b4212 files · +166 −111Browse files

Unified · Split

12 files
  1. fs/nfs/dir.c +12 −11
  2. fs/nfs/file.c +1 −11
  3. fs/nfs/filelayout/filelayoutdev.c +2 −1
  4. fs/nfs/flexfilelayout/flexfilelayout.c +4 −2
  5. fs/nfs/flexfilelayout/flexfilelayoutdev.c +1 −1
  6. fs/nfs/inode.c +41 −34
  7. fs/nfs/internal.h +1 −0
  8. fs/nfs/nfs4proc.c +35 −8
  9. fs/nfs/nfs4state.c +33 −24
  10. fs/nfs/nfs4xdr.c +23 −14
  11. fs/nfs/pnfs.c +13 −3
  12. include/linux/nfs_fs.h +0 −2
fs/nfs/dir.c+12−11
@@ -1273,8 +1273,8 @@ out_error: · 1272 unmodified lines
1273 */1273 */
1274static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags)1274static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags)
1275{1275{
1276 int error;
1277 struct inode *inode = d_inode(dentry);1276 struct inode *inode = d_inode(dentry);
1277 int error = 0;
1278 1278
1279 /*1279 /*
1280 * I believe we can only get a negative dentry here in the case of a1280 * I believe we can only get a negative dentry here in the case of a
@@ -1293,7 +1293,8 @@ static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags) · 12 unmodified lines
1293 return 0;1293 return 0;
1294 }1294 }
1295 1295
1296 error = nfs_revalidate_inode(NFS_SERVER(inode), inode);1296 if (nfs_mapping_need_revalidate_inode(inode))
1297 error = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
1297 dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",1298 dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",
1298 __func__, inode->i_ino, error ? "invalid" : "valid");1299 __func__, inode->i_ino, error ? "invalid" : "valid");
1299 return !error;1300 return !error;
@@ -2285,8 +2286,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str · 985 unmodified lines
2285 if (cache == NULL)2286 if (cache == NULL)
2286 goto out;2287 goto out;
2287 /* Found an entry, is our attribute cache valid? */2288 /* Found an entry, is our attribute cache valid? */
2288 if (!nfs_attribute_cache_expired(inode) &&2289 if (!nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
2289 !(nfsi->cache_validity & NFS_INO_INVALID_ATTR))
2290 break;2290 break;
2291 err = -ECHILD;2291 err = -ECHILD;
2292 if (!may_block)2292 if (!may_block)
@@ -2334,12 +2334,12 @@ static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred, · 41 unmodified lines
2334 cache = NULL;2334 cache = NULL;
2335 if (cache == NULL)2335 if (cache == NULL)
2336 goto out;2336 goto out;
2337 err = nfs_revalidate_inode_rcu(NFS_SERVER(inode), inode);2337 if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
2338 if (err)
2339 goto out;2338 goto out;
2340 res->jiffies = cache->jiffies;2339 res->jiffies = cache->jiffies;
2341 res->cred = cache->cred;2340 res->cred = cache->cred;
2342 res->mask = cache->mask;2341 res->mask = cache->mask;
2342 err = 0;
2343out:2343out:
2344 rcu_read_unlock();2344 rcu_read_unlock();
2345 return err;2345 return err;
@@ -2491,12 +2491,13 @@ EXPORT_SYMBOL_GPL(nfs_may_open); · 145 unmodified lines
2491static int nfs_execute_ok(struct inode *inode, int mask)2491static int nfs_execute_ok(struct inode *inode, int mask)
2492{2492{
2493 struct nfs_server *server = NFS_SERVER(inode);2493 struct nfs_server *server = NFS_SERVER(inode);
2494 int ret;2494 int ret = 0;
2495 2495
2496 if (mask & MAY_NOT_BLOCK)2496 if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS)) {
2497 ret = nfs_revalidate_inode_rcu(server, inode);2497 if (mask & MAY_NOT_BLOCK)
2498 else2498 return -ECHILD;
2499 ret = nfs_revalidate_inode(server, inode);2499 ret = __nfs_revalidate_inode(server, inode);
2500 }
2500 if (ret == 0 && !execute_ok(inode))2501 if (ret == 0 && !execute_ok(inode))
2501 ret = -EACCES;2502 ret = -EACCES;
2502 return ret;2503 return ret;
fs/nfs/file.c+1−11
@@ -101,21 +101,11 @@ EXPORT_SYMBOL_GPL(nfs_file_release); · 100 unmodified lines
101static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)101static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
102{102{
103 struct nfs_server *server = NFS_SERVER(inode);103 struct nfs_server *server = NFS_SERVER(inode);
104 struct nfs_inode *nfsi = NFS_I(inode);
105 const unsigned long force_reval = NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED;
106 unsigned long cache_validity = nfsi->cache_validity;
107
108 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) &&
109 (cache_validity & force_reval) != force_reval)
110 goto out_noreval;
111 104
112 if (filp->f_flags & O_DIRECT)105 if (filp->f_flags & O_DIRECT)
113 goto force_reval;106 goto force_reval;
114 if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)107 if (nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE))
115 goto force_reval;
116 if (nfs_attribute_timeout(inode))
117 goto force_reval;108 goto force_reval;
118out_noreval:
119 return 0;109 return 0;
120force_reval:110force_reval:
121 return __nfs_revalidate_inode(server, inode);111 return __nfs_revalidate_inode(server, inode);
fs/nfs/filelayout/filelayoutdev.c+2−1
@@ -282,7 +282,8 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) · 281 unmodified lines
282 s->nfs_client->cl_minorversion);282 s->nfs_client->cl_minorversion);
283 283
284out_test_devid:284out_test_devid:
285 if (filelayout_test_devid_unavailable(devid))285 if (ret->ds_clp == NULL ||
286 filelayout_test_devid_unavailable(devid))
286 ret = NULL;287 ret = NULL;
287out:288out:
288 return ret;289 return ret;
fs/nfs/flexfilelayout/flexfilelayout.c+4−2
@@ -1126,7 +1126,8 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, · 1125 unmodified lines
1126 case -EPIPE:1126 case -EPIPE:
1127 dprintk("%s DS connection error %d\n", __func__,1127 dprintk("%s DS connection error %d\n", __func__,
1128 task->tk_status);1128 task->tk_status);
1129 nfs4_mark_deviceid_unavailable(devid);1129 nfs4_delete_deviceid(devid->ld, devid->nfs_client,
1130 &devid->deviceid);
1130 rpc_wake_up(&tbl->slot_tbl_waitq);1131 rpc_wake_up(&tbl->slot_tbl_waitq);
1131 /* fall through */1132 /* fall through */
1132 default:1133 default:
@@ -1175,7 +1176,8 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task, · 42 unmodified lines
1175 default:1176 default:
1176 dprintk("%s DS connection error %d\n", __func__,1177 dprintk("%s DS connection error %d\n", __func__,
1177 task->tk_status);1178 task->tk_status);
1178 nfs4_mark_deviceid_unavailable(devid);1179 nfs4_delete_deviceid(devid->ld, devid->nfs_client,
1180 &devid->deviceid);
1179 }1181 }
1180 /* FIXME: Need to prevent infinite looping here. */1182 /* FIXME: Need to prevent infinite looping here. */
1181 return -NFS4ERR_RESET_TO_PNFS;1183 return -NFS4ERR_RESET_TO_PNFS;
fs/nfs/flexfilelayout/flexfilelayoutdev.c+1−1
@@ -177,7 +177,7 @@ out_err: · 176 unmodified lines
177static void ff_layout_mark_devid_invalid(struct pnfs_layout_segment *lseg,177static void ff_layout_mark_devid_invalid(struct pnfs_layout_segment *lseg,
178 struct nfs4_deviceid_node *devid)178 struct nfs4_deviceid_node *devid)
179{179{
180 nfs4_mark_deviceid_unavailable(devid);180 nfs4_delete_deviceid(devid->ld, devid->nfs_client, &devid->deviceid);
181 if (!ff_layout_has_available_ds(lseg))181 if (!ff_layout_has_available_ds(lseg))
182 pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,182 pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,
183 lseg);183 lseg);
fs/nfs/inode.c+41−34
@@ -160,6 +160,43 @@ int nfs_sync_mapping(struct address_space *mapping) · 159 unmodified lines
160 return ret;160 return ret;
161}161}
162 162
163static int nfs_attribute_timeout(struct inode *inode)
164{
165 struct nfs_inode *nfsi = NFS_I(inode);
166
167 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
168}
169
170static bool nfs_check_cache_invalid_delegated(struct inode *inode, unsigned long flags)
171{
172 unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
173
174 /* Special case for the pagecache or access cache */
175 if (flags == NFS_INO_REVAL_PAGECACHE &&
176 !(cache_validity & NFS_INO_REVAL_FORCED))
177 return false;
178 return (cache_validity & flags) != 0;
179}
180
181static bool nfs_check_cache_invalid_not_delegated(struct inode *inode, unsigned long flags)
182{
183 unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
184
185 if ((cache_validity & flags) != 0)
186 return true;
187 if (nfs_attribute_timeout(inode))
188 return true;
189 return false;
190}
191
192bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
193{
194 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
195 return nfs_check_cache_invalid_delegated(inode, flags);
196
197 return nfs_check_cache_invalid_not_delegated(inode, flags);
198}
199
163static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)200static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
164{201{
165 struct nfs_inode *nfsi = NFS_I(inode);202 struct nfs_inode *nfsi = NFS_I(inode);
@@ -795,6 +832,8 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync) · 629 unmodified lines
795 if (!is_sync)832 if (!is_sync)
796 return;833 return;
797 inode = d_inode(ctx->dentry);834 inode = d_inode(ctx->dentry);
835 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
836 return;
798 nfsi = NFS_I(inode);837 nfsi = NFS_I(inode);
799 if (inode->i_mapping->nrpages == 0)838 if (inode->i_mapping->nrpages == 0)
800 return;839 return;
@@ -1044,13 +1083,6 @@ out: · 243 unmodified lines
1044 return status;1083 return status;
1045}1084}
1046 1085
1047int nfs_attribute_timeout(struct inode *inode)
1048{
1049 struct nfs_inode *nfsi = NFS_I(inode);
1050
1051 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
1052}
1053
1054int nfs_attribute_cache_expired(struct inode *inode)1086int nfs_attribute_cache_expired(struct inode *inode)
1055{1087{
1056 if (nfs_have_delegated_attributes(inode))1088 if (nfs_have_delegated_attributes(inode))
@@ -1073,15 +1105,6 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) · 16 unmodified lines
1073}1105}
1074EXPORT_SYMBOL_GPL(nfs_revalidate_inode);1106EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
1075 1107
1076int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode)
1077{
1078 if (!(NFS_I(inode)->cache_validity &
1079 (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
1080 && !nfs_attribute_cache_expired(inode))
1081 return NFS_STALE(inode) ? -ESTALE : 0;
1082 return -ECHILD;
1083}
1084
1085static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)1108static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
1086{1109{
1087 struct nfs_inode *nfsi = NFS_I(inode);1110 struct nfs_inode *nfsi = NFS_I(inode);
@@ -1114,17 +1137,8 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map · 26 unmodified lines
1114 1137
1115bool nfs_mapping_need_revalidate_inode(struct inode *inode)1138bool nfs_mapping_need_revalidate_inode(struct inode *inode)
1116{1139{
1117 unsigned long cache_validity = NFS_I(inode)->cache_validity;1140 return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
1118 1141 NFS_STALE(inode);
1119 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) {
1120 const unsigned long force_reval =
1121 NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED;
1122 return (cache_validity & force_reval) == force_reval;
1123 }
1124
1125 return (cache_validity & NFS_INO_REVAL_PAGECACHE)
1126 || nfs_attribute_timeout(inode)
1127 || NFS_STALE(inode);
1128}1142}
1129 1143
1130int nfs_revalidate_mapping_rcu(struct inode *inode)1144int nfs_revalidate_mapping_rcu(struct inode *inode)
@@ -1536,13 +1550,6 @@ static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr · 405 unmodified lines
1536{1550{
1537 unsigned long invalid = NFS_INO_INVALID_ATTR;1551 unsigned long invalid = NFS_INO_INVALID_ATTR;
1538 1552
1539 /*
1540 * Don't revalidate the pagecache if we hold a delegation, but do
1541 * force an attribute update
1542 */
1543 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
1544 invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_FORCED;
1545
1546 if (S_ISDIR(inode->i_mode))1553 if (S_ISDIR(inode->i_mode))
1547 invalid |= NFS_INO_INVALID_DATA;1554 invalid |= NFS_INO_INVALID_DATA;
1548 nfs_set_cache_invalid(inode, invalid);1555 nfs_set_cache_invalid(inode, invalid);
fs/nfs/internal.h+1−0
@@ -381,6 +381,7 @@ extern int nfs_drop_inode(struct inode *); · 380 unmodified lines
381extern void nfs_clear_inode(struct inode *);381extern void nfs_clear_inode(struct inode *);
382extern void nfs_evict_inode(struct inode *);382extern void nfs_evict_inode(struct inode *);
383void nfs_zap_acl_cache(struct inode *inode);383void nfs_zap_acl_cache(struct inode *inode);
384extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
384extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);385extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
385extern int nfs_wait_atomic_killable(atomic_t *p);386extern int nfs_wait_atomic_killable(atomic_t *p);
386 387
fs/nfs/nfs4proc.c+35−8
@@ -1089,8 +1089,15 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) · 1088 unmodified lines
1089 1089
1090 spin_lock(&dir->i_lock);1090 spin_lock(&dir->i_lock);
1091 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;1091 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1092 if (!cinfo->atomic || cinfo->before != dir->i_version)1092 if (cinfo->atomic && cinfo->before == dir->i_version) {
1093 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
1094 nfsi->attrtimeo_timestamp = jiffies;
1095 } else {
1093 nfs_force_lookup_revalidate(dir);1096 nfs_force_lookup_revalidate(dir);
1097 if (cinfo->before != dir->i_version)
1098 nfsi->cache_validity |= NFS_INO_INVALID_ACCESS |
1099 NFS_INO_INVALID_ACL;
1100 }
1094 dir->i_version = cinfo->after;1101 dir->i_version = cinfo->after;
1095 nfsi->attr_gencount = nfs_inc_attr_generation_counter();1102 nfsi->attr_gencount = nfs_inc_attr_generation_counter();
1096 nfs_fscache_invalidate(dir);1103 nfs_fscache_invalidate(dir);
@@ -3115,6 +3122,16 @@ static void nfs4_close_done(struct rpc_task *task, void *data) · 2018 unmodified lines
3115 res_stateid = &calldata->res.stateid;3122 res_stateid = &calldata->res.stateid;
3116 renew_lease(server, calldata->timestamp);3123 renew_lease(server, calldata->timestamp);
3117 break;3124 break;
3125 case -NFS4ERR_ACCESS:
3126 if (calldata->arg.bitmask != NULL) {
3127 calldata->arg.bitmask = NULL;
3128 calldata->res.fattr = NULL;
3129 task->tk_status = 0;
3130 rpc_restart_call_prepare(task);
3131 goto out_release;
3132
3133 }
3134 break;
3118 case -NFS4ERR_ADMIN_REVOKED:3135 case -NFS4ERR_ADMIN_REVOKED:
3119 case -NFS4ERR_STALE_STATEID:3136 case -NFS4ERR_STALE_STATEID:
3120 case -NFS4ERR_EXPIRED:3137 case -NFS4ERR_EXPIRED:
@@ -3140,7 +3157,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) · 19 unmodified lines
3140 res_stateid, calldata->arg.fmode);3157 res_stateid, calldata->arg.fmode);
3141out_release:3158out_release:
3142 nfs_release_seqid(calldata->arg.seqid);3159 nfs_release_seqid(calldata->arg.seqid);
3143 nfs_refresh_inode(calldata->inode, calldata->res.fattr);3160 nfs_refresh_inode(calldata->inode, &calldata->fattr);
3144 dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);3161 dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
3145}3162}
3146 3163
@@ -3193,9 +3210,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) · 46 unmodified lines
3193 goto out_wait;3210 goto out_wait;
3194 }3211 }
3195 3212
3196 if (calldata->arg.fmode == 0) {3213 if (calldata->arg.fmode == 0)
3197 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];3214 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
3198 3215
3216 if (calldata->arg.fmode == 0 || calldata->arg.fmode == FMODE_READ) {
3199 /* Close-to-open cache consistency revalidation */3217 /* Close-to-open cache consistency revalidation */
3200 if (!nfs4_have_delegation(inode, FMODE_READ))3218 if (!nfs4_have_delegation(inode, FMODE_READ))
3201 calldata->arg.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;3219 calldata->arg.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
@@ -3207,7 +3225,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) · 5 unmodified lines
3207 nfs4_map_atomic_open_share(NFS_SERVER(inode),3225 nfs4_map_atomic_open_share(NFS_SERVER(inode),
3208 calldata->arg.fmode, 0);3226 calldata->arg.fmode, 0);
3209 3227
3210 nfs_fattr_init(calldata->res.fattr);3228 if (calldata->res.fattr == NULL)
3229 calldata->arg.bitmask = NULL;
3230 else if (calldata->arg.bitmask == NULL)
3231 calldata->res.fattr = NULL;
3211 calldata->timestamp = jiffies;3232 calldata->timestamp = jiffies;
3212 if (nfs4_setup_sequence(NFS_SERVER(inode),3233 if (nfs4_setup_sequence(NFS_SERVER(inode),
3213 &calldata->arg.seq_args,3234 &calldata->arg.seq_args,
@@ -3274,6 +3295,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait) · 60 unmodified lines
3274 calldata->arg.seqid = alloc_seqid(&state->owner->so_seqid, gfp_mask);3295 calldata->arg.seqid = alloc_seqid(&state->owner->so_seqid, gfp_mask);
3275 if (IS_ERR(calldata->arg.seqid))3296 if (IS_ERR(calldata->arg.seqid))
3276 goto out_free_calldata;3297 goto out_free_calldata;
3298 nfs_fattr_init(&calldata->fattr);
3277 calldata->arg.fmode = 0;3299 calldata->arg.fmode = 0;
3278 calldata->lr.arg.ld_private = &calldata->lr.ld_private;3300 calldata->lr.arg.ld_private = &calldata->lr.ld_private;
3279 calldata->res.fattr = &calldata->fattr;3301 calldata->res.fattr = &calldata->fattr;
@@ -5673,6 +5695,14 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) · 2393 unmodified lines
5673 case -NFS4ERR_STALE_STATEID:5695 case -NFS4ERR_STALE_STATEID:
5674 task->tk_status = 0;5696 task->tk_status = 0;
5675 break;5697 break;
5698 case -NFS4ERR_ACCESS:
5699 if (data->args.bitmask) {
5700 data->args.bitmask = NULL;
5701 data->res.fattr = NULL;
5702 task->tk_status = 0;
5703 rpc_restart_call_prepare(task);
5704 return;
5705 }
5676 default:5706 default:
5677 if (nfs4_async_handle_error(task, data->res.server,5707 if (nfs4_async_handle_error(task, data->res.server,
5678 NULL, NULL) == -EAGAIN) {5708 NULL, NULL) == -EAGAIN) {
@@ -5692,6 +5722,7 @@ static void nfs4_delegreturn_release(void *calldata) · 13 unmodified lines
5692 if (data->lr.roc)5722 if (data->lr.roc)
5693 pnfs_roc_release(&data->lr.arg, &data->lr.res,5723 pnfs_roc_release(&data->lr.arg, &data->lr.res,
5694 data->res.lr_ret);5724 data->res.lr_ret);
5725 nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
5695 nfs_iput_and_deactive(inode);5726 nfs_iput_and_deactive(inode);
5696 }5727 }
5697 kfree(calldata);5728 kfree(calldata);
@@ -5780,10 +5811,6 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co · 82 unmodified lines
5780 if (status != 0)5811 if (status != 0)
5781 goto out;5812 goto out;
5782 status = data->rpc_status;5813 status = data->rpc_status;
5783 if (status == 0)
5784 nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
5785 else
5786 nfs_refresh_inode(inode, &data->fattr);
5787out:5814out:
5788 rpc_put_task(task);5815 rpc_put_task(task);
5789 return status;5816 return status;
fs/nfs/nfs4state.c+33−24
@@ -494,21 +494,18 @@ nfs4_alloc_state_owner(struct nfs_server *server, · 493 unmodified lines
494}494}
495 495
496static void496static void
497nfs4_drop_state_owner(struct nfs4_state_owner *sp)497nfs4_reset_state_owner(struct nfs4_state_owner *sp)
498{498{
499 struct rb_node *rb_node = &sp->so_server_node;499 /* This state_owner is no longer usable, but must
500 500 * remain in place so that state recovery can find it
501 if (!RB_EMPTY_NODE(rb_node)) {501 * and the opens associated with it.
502 struct nfs_server *server = sp->so_server;502 * It may also be used for new 'open' request to
503 struct nfs_client *clp = server->nfs_client;503 * return a delegation to the server.
504 504 * So update the 'create_time' so that it looks like
505 spin_lock(&clp->cl_lock);505 * a new state_owner. This will cause the server to
506 if (!RB_EMPTY_NODE(rb_node)) {506 * request an OPEN_CONFIRM to start a new sequence.
507 rb_erase(rb_node, &server->state_owners);507 */
508 RB_CLEAR_NODE(rb_node);508 sp->so_seqid.create_time = ktime_get();
509 }
510 spin_unlock(&clp->cl_lock);
511 }
512}509}
513 510
514static void nfs4_free_state_owner(struct nfs4_state_owner *sp)511static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
@@ -797,21 +794,33 @@ void nfs4_close_sync(struct nfs4_state *state, fmode_t fmode) · 282 unmodified lines
797 794
798/*795/*
799 * Search the state->lock_states for an existing lock_owner796 * Search the state->lock_states for an existing lock_owner
800 * that is compatible with current->files797 * that is compatible with either of the given owners.
798 * If the second is non-zero, then the first refers to a Posix-lock
799 * owner (current->files) and the second refers to a flock/OFD
800 * owner (struct file*). In that case, prefer a match for the first
801 * owner.
802 * If both sorts of locks are held on the one file we cannot know
803 * which stateid was intended to be used, so a "correct" choice cannot
804 * be made. Failing that, a "consistent" choice is preferable. The
805 * consistent choice we make is to prefer the first owner, that of a
806 * Posix lock.
801 */807 */
802static struct nfs4_lock_state *808static struct nfs4_lock_state *
803__nfs4_find_lock_state(struct nfs4_state *state,809__nfs4_find_lock_state(struct nfs4_state *state,
804 fl_owner_t fl_owner, fl_owner_t fl_owner2)810 fl_owner_t fl_owner, fl_owner_t fl_owner2)
805{811{
806 struct nfs4_lock_state *pos;812 struct nfs4_lock_state *pos, *ret = NULL;
807 list_for_each_entry(pos, &state->lock_states, ls_locks) {813 list_for_each_entry(pos, &state->lock_states, ls_locks) {
808 if (pos->ls_owner != fl_owner &&814 if (pos->ls_owner == fl_owner) {
809 pos->ls_owner != fl_owner2)815 ret = pos;
810 continue;816 break;
811 atomic_inc(&pos->ls_count);817 }
812 return pos;818 if (pos->ls_owner == fl_owner2)
819 ret = pos;
813 }820 }
814 return NULL;821 if (ret)
822 atomic_inc(&ret->ls_count);
823 return ret;
815}824}
816 825
817/*826/*
@@ -1101,7 +1110,7 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid) · 283 unmodified lines
1101 1110
1102 sp = container_of(seqid->sequence, struct nfs4_state_owner, so_seqid);1111 sp = container_of(seqid->sequence, struct nfs4_state_owner, so_seqid);
1103 if (status == -NFS4ERR_BAD_SEQID)1112 if (status == -NFS4ERR_BAD_SEQID)
1104 nfs4_drop_state_owner(sp);1113 nfs4_reset_state_owner(sp);
1105 if (!nfs4_has_session(sp->so_server->nfs_client))1114 if (!nfs4_has_session(sp->so_server->nfs_client))
1106 nfs_increment_seqid(status, seqid);1115 nfs_increment_seqid(status, seqid);
1107}1116}
fs/nfs/nfs4xdr.c+23−14
@@ -502,11 +502,13 @@ static int nfs4_stat_to_errno(int); · 501 unmodified lines
502 (compound_encode_hdr_maxsz + \502 (compound_encode_hdr_maxsz + \
503 encode_sequence_maxsz + \503 encode_sequence_maxsz + \
504 encode_putfh_maxsz + \504 encode_putfh_maxsz + \
505 encode_layoutreturn_maxsz + \
505 encode_open_downgrade_maxsz)506 encode_open_downgrade_maxsz)
506#define NFS4_dec_open_downgrade_sz \507#define NFS4_dec_open_downgrade_sz \
507 (compound_decode_hdr_maxsz + \508 (compound_decode_hdr_maxsz + \
508 decode_sequence_maxsz + \509 decode_sequence_maxsz + \
509 decode_putfh_maxsz + \510 decode_putfh_maxsz + \
511 decode_layoutreturn_maxsz + \
510 decode_open_downgrade_maxsz)512 decode_open_downgrade_maxsz)
511#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \513#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
512 encode_sequence_maxsz + \514 encode_sequence_maxsz + \
@@ -2277,9 +2279,9 @@ static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr, · 1764 unmodified lines
2277 encode_putfh(xdr, args->fh, &hdr);2279 encode_putfh(xdr, args->fh, &hdr);
2278 if (args->lr_args)2280 if (args->lr_args)
2279 encode_layoutreturn(xdr, args->lr_args, &hdr);2281 encode_layoutreturn(xdr, args->lr_args, &hdr);
2280 encode_close(xdr, args, &hdr);
2281 if (args->bitmask != NULL)2282 if (args->bitmask != NULL)
2282 encode_getfattr(xdr, args->bitmask, &hdr);2283 encode_getfattr(xdr, args->bitmask, &hdr);
2284 encode_close(xdr, args, &hdr);
2283 encode_nops(&hdr);2285 encode_nops(&hdr);
2284}2286}
2285 2287
@@ -2356,6 +2358,8 @@ static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, · 70 unmodified lines
2356 encode_compound_hdr(xdr, req, &hdr);2358 encode_compound_hdr(xdr, req, &hdr);
2357 encode_sequence(xdr, &args->seq_args, &hdr);2359 encode_sequence(xdr, &args->seq_args, &hdr);
2358 encode_putfh(xdr, args->fh, &hdr);2360 encode_putfh(xdr, args->fh, &hdr);
2361 if (args->lr_args)
2362 encode_layoutreturn(xdr, args->lr_args, &hdr);
2359 encode_open_downgrade(xdr, args, &hdr);2363 encode_open_downgrade(xdr, args, &hdr);
2360 encode_nops(&hdr);2364 encode_nops(&hdr);
2361}2365}
@@ -2701,7 +2705,8 @@ static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, · 339 unmodified lines
2701 encode_putfh(xdr, args->fhandle, &hdr);2705 encode_putfh(xdr, args->fhandle, &hdr);
2702 if (args->lr_args)2706 if (args->lr_args)
2703 encode_layoutreturn(xdr, args->lr_args, &hdr);2707 encode_layoutreturn(xdr, args->lr_args, &hdr);
2704 encode_getfattr(xdr, args->bitmask, &hdr);2708 if (args->bitmask)
2709 encode_getfattr(xdr, args->bitmask, &hdr);
2705 encode_delegreturn(xdr, args->stateid, &hdr);2710 encode_delegreturn(xdr, args->stateid, &hdr);
2706 encode_nops(&hdr);2711 encode_nops(&hdr);
2707}2712}
@@ -6151,6 +6156,12 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, · 3443 unmodified lines
6151 status = decode_putfh(xdr);6156 status = decode_putfh(xdr);
6152 if (status)6157 if (status)
6153 goto out;6158 goto out;
6159 if (res->lr_res) {
6160 status = decode_layoutreturn(xdr, res->lr_res);
6161 res->lr_ret = status;
6162 if (status)
6163 goto out;
6164 }
6154 status = decode_open_downgrade(xdr, res);6165 status = decode_open_downgrade(xdr, res);
6155out:6166out:
6156 return status;6167 return status;
@@ -6484,16 +6495,12 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr, · 327 unmodified lines
6484 if (status)6495 if (status)
6485 goto out;6496 goto out;
6486 }6497 }
6498 if (res->fattr != NULL) {
6499 status = decode_getfattr(xdr, res->fattr, res->server);
6500 if (status != 0)
6501 goto out;
6502 }
6487 status = decode_close(xdr, res);6503 status = decode_close(xdr, res);
6488 if (status != 0)
6489 goto out;
6490 /*
6491 * Note: Server may do delete on close for this file
6492 * in which case the getattr call will fail with
6493 * an ESTALE error. Shouldn't be a problem,
6494 * though, since fattr->valid will remain unset.
6495 */
6496 decode_getfattr(xdr, res->fattr, res->server);
6497out:6504out:
6498 return status;6505 return status;
6499}6506}
@@ -6966,9 +6973,11 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, · 466 unmodified lines
6966 if (status)6973 if (status)
6967 goto out;6974 goto out;
6968 }6975 }
6969 status = decode_getfattr(xdr, res->fattr, res->server);6976 if (res->fattr) {
6970 if (status != 0)6977 status = decode_getfattr(xdr, res->fattr, res->server);
6971 goto out;6978 if (status != 0)
6979 goto out;
6980 }
6972 status = decode_delegreturn(xdr);6981 status = decode_delegreturn(xdr);
6973out:6982out:
6974 return status;6983 return status;
fs/nfs/pnfs.c+13−3
@@ -1251,6 +1251,7 @@ bool pnfs_roc(struct inode *ino, · 1250 unmodified lines
1251 nfs4_stateid stateid;1251 nfs4_stateid stateid;
1252 enum pnfs_iomode iomode = 0;1252 enum pnfs_iomode iomode = 0;
1253 bool layoutreturn = false, roc = false;1253 bool layoutreturn = false, roc = false;
1254 bool skip_read = false;
1254 1255
1255 if (!nfs_have_layout(ino))1256 if (!nfs_have_layout(ino))
1256 return false;1257 return false;
@@ -1270,18 +1271,27 @@ retry: · 13 unmodified lines
1270 }1271 }
1271 1272
1272 /* no roc if we hold a delegation */1273 /* no roc if we hold a delegation */
1273 if (nfs4_check_delegation(ino, FMODE_READ))1274 if (nfs4_check_delegation(ino, FMODE_READ)) {
1274 goto out_noroc;1275 if (nfs4_check_delegation(ino, FMODE_WRITE))
1276 goto out_noroc;
1277 skip_read = true;
1278 }
1275 1279
1276 list_for_each_entry(ctx, &nfsi->open_files, list) {1280 list_for_each_entry(ctx, &nfsi->open_files, list) {
1277 state = ctx->state;1281 state = ctx->state;
1282 if (state == NULL)
1283 continue;
1278 /* Don't return layout if there is open file state */1284 /* Don't return layout if there is open file state */
1279 if (state != NULL && state->state != 0)1285 if (state->state & FMODE_WRITE)
1280 goto out_noroc;1286 goto out_noroc;
1287 if (state->state & FMODE_READ)
1288 skip_read = true;
1281 }1289 }
1282 1290
1283 1291
1284 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) {1292 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) {
1293 if (skip_read && lseg->pls_range.iomode == IOMODE_READ)
1294 continue;
1285 /* If we are sending layoutreturn, invalidate all valid lsegs */1295 /* If we are sending layoutreturn, invalidate all valid lsegs */
1286 if (!test_and_clear_bit(NFS_LSEG_ROC, &lseg->pls_flags))1296 if (!test_and_clear_bit(NFS_LSEG_ROC, &lseg->pls_flags))
1287 continue;1297 continue;
include/linux/nfs_fs.h+0−2
@@ -340,10 +340,8 @@ extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); · 339 unmodified lines
340extern void nfs_access_set_mask(struct nfs_access_entry *, u32);340extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
341extern int nfs_permission(struct inode *, int);341extern int nfs_permission(struct inode *, int);
342extern int nfs_open(struct inode *, struct file *);342extern int nfs_open(struct inode *, struct file *);
343extern int nfs_attribute_timeout(struct inode *inode);
344extern int nfs_attribute_cache_expired(struct inode *inode);343extern int nfs_attribute_cache_expired(struct inode *inode);
345extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);344extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
346extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode);
347extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);345extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
348extern bool nfs_mapping_need_revalidate_inode(struct inode *inode);346extern bool nfs_mapping_need_revalidate_inode(struct inode *inode);
349extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);347extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t