summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/afs/fsclient.c2
-rw-r--r--fs/afs/internal.h9
-rw-r--r--fs/afs/security.c7
-rw-r--r--fs/afs/yfsclient.c2
4 files changed, 12 insertions, 8 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 3975969719de..7c75a1813321 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -269,7 +269,7 @@ static void xdr_decode_AFSCallBack(struct afs_call *call,
269 269
270 write_seqlock(&vnode->cb_lock); 270 write_seqlock(&vnode->cb_lock);
271 271
272 if (call->cb_break == afs_cb_break_sum(vnode, cbi)) { 272 if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
273 vnode->cb_version = ntohl(*bp++); 273 vnode->cb_version = ntohl(*bp++);
274 cb_expiry = ntohl(*bp++); 274 cb_expiry = ntohl(*bp++);
275 vnode->cb_type = ntohl(*bp++); 275 vnode->cb_type = ntohl(*bp++);
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index e5b596bd8acf..b60d15212975 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -776,10 +776,13 @@ static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode)
776 return vnode->cb_break + vnode->cb_s_break + vnode->cb_v_break; 776 return vnode->cb_break + vnode->cb_s_break + vnode->cb_v_break;
777} 777}
778 778
779static inline unsigned int afs_cb_break_sum(struct afs_vnode *vnode, 779static inline bool afs_cb_is_broken(unsigned int cb_break,
780 struct afs_cb_interest *cbi) 780 const struct afs_vnode *vnode,
781 const struct afs_cb_interest *cbi)
781{ 782{
782 return vnode->cb_break + cbi->server->cb_s_break + vnode->volume->cb_v_break; 783 return !cbi || cb_break != (vnode->cb_break +
784 cbi->server->cb_s_break +
785 vnode->volume->cb_v_break);
783} 786}
784 787
785/* 788/*
diff --git a/fs/afs/security.c b/fs/afs/security.c
index d1ae53fd3739..5f58a9a17e69 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -147,7 +147,8 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
147 break; 147 break;
148 } 148 }
149 149
150 if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) { 150 if (afs_cb_is_broken(cb_break, vnode,
151 vnode->cb_interest)) {
151 changed = true; 152 changed = true;
152 break; 153 break;
153 } 154 }
@@ -177,7 +178,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
177 } 178 }
178 } 179 }
179 180
180 if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) 181 if (afs_cb_is_broken(cb_break, vnode, vnode->cb_interest))
181 goto someone_else_changed_it; 182 goto someone_else_changed_it;
182 183
183 /* We need a ref on any permits list we want to copy as we'll have to 184 /* We need a ref on any permits list we want to copy as we'll have to
@@ -256,7 +257,7 @@ found:
256 257
257 spin_lock(&vnode->lock); 258 spin_lock(&vnode->lock);
258 zap = rcu_access_pointer(vnode->permit_cache); 259 zap = rcu_access_pointer(vnode->permit_cache);
259 if (cb_break == afs_cb_break_sum(vnode, vnode->cb_interest) && 260 if (!afs_cb_is_broken(cb_break, vnode, vnode->cb_interest) &&
260 zap == permits) 261 zap == permits)
261 rcu_assign_pointer(vnode->permit_cache, replacement); 262 rcu_assign_pointer(vnode->permit_cache, replacement);
262 else 263 else
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
index d5e3f0095040..12658c1363ae 100644
--- a/fs/afs/yfsclient.c
+++ b/fs/afs/yfsclient.c
@@ -324,7 +324,7 @@ static void xdr_decode_YFSCallBack(struct afs_call *call,
324 324
325 write_seqlock(&vnode->cb_lock); 325 write_seqlock(&vnode->cb_lock);
326 326
327 if (call->cb_break == afs_cb_break_sum(vnode, cbi)) { 327 if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
328 cb_expiry = xdr_to_u64(xdr->expiration_time); 328 cb_expiry = xdr_to_u64(xdr->expiration_time);
329 do_div(cb_expiry, 10 * 1000 * 1000); 329 do_div(cb_expiry, 10 * 1000 * 1000);
330 vnode->cb_version = ntohl(xdr->version); 330 vnode->cb_version = ntohl(xdr->version);