static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
struct afs_file_status *status,
struct afs_vnode *vnode,
- afs_dataversion_t *store_version)
+ const afs_dataversion_t *expected_version,
+ afs_dataversion_t *_version)
{
- afs_dataversion_t expected_version;
const __be32 *bp = *_bp;
umode_t mode;
u64 data_version, size;
changed |= true;
}
status->mode &= S_IALLUGO;
+ if (_version)
+ *_version = data_version;
_debug("vnode time %lx, %lx",
status->mtime_client, status->mtime_server);
inode_set_iversion_raw(&vnode->vfs_inode, data_version);
}
- expected_version = status->data_version;
- if (store_version)
- expected_version = *store_version;
-
- if (expected_version != data_version) {
- status->data_version = data_version;
+ status->data_version = data_version;
+ if (expected_version && *expected_version != data_version) {
if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
_debug("vnode modified %llx on {%x:%u}",
(unsigned long long) data_version,
set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
}
- } else if (store_version) {
- status->data_version = data_version;
}
out:
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
+ &call->expected_version, NULL);
xdr_decode_AFSCallBack(call, vnode, &bp);
if (call->reply[1])
xdr_decode_AFSVolSync(&bp, call->reply[1]);
/*
* fetch the status information for a file
*/
-int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync)
+int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
+ bool new_inode)
{
struct afs_vnode *vnode = fc->vnode;
struct afs_call *call;
call->key = fc->key;
call->reply[0] = vnode;
call->reply[1] = volsync;
+ call->expected_version = new_inode ? 1 : vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
return ret;
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
+ &vnode->status.data_version,
+ &req->new_version);
xdr_decode_AFSCallBack(call, vnode, &bp);
if (call->reply[1])
xdr_decode_AFSVolSync(&bp, call->reply[1]);
call->reply[0] = vnode;
call->reply[1] = NULL; /* volsync */
call->reply[2] = req;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
call->reply[0] = vnode;
call->reply[1] = NULL; /* volsync */
call->reply[2] = req;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
xdr_decode_AFSFid(&bp, call->reply[1]);
- xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
+ &call->expected_version, NULL);
xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
call->reply[1] = newfid;
call->reply[2] = newstatus;
call->reply[3] = newcb;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
+ &call->expected_version, NULL);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
_leave(" = 0 [done]");
call->key = fc->key;
call->reply[0] = vnode;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
- xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode,
+ &call->expected_version, NULL);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
_leave(" = 0 [done]");
call->key = fc->key;
call->reply[0] = dvnode;
call->reply[1] = vnode;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
xdr_decode_AFSFid(&bp, call->reply[1]);
- xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
+ &call->expected_version, NULL);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
_leave(" = 0 [done]");
call->reply[0] = vnode;
call->reply[1] = newfid;
call->reply[2] = newstatus;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode,
+ &call->expected_version, NULL);
if (new_dvnode != orig_dvnode)
xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
- NULL);
+ &call->expected_version_2, NULL);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
_leave(" = 0 [done]");
call->key = fc->key;
call->reply[0] = orig_dvnode;
call->reply[1] = new_dvnode;
+ call->expected_version = orig_dvnode->status.data_version;
+ call->expected_version_2 = new_dvnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
- &call->store_version);
+ &call->expected_version, NULL);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
afs_pages_written_back(vnode, call);
call->first_offset = offset;
call->last_to = to;
call->send_pages = true;
- call->store_version = vnode->status.data_version + 1;
+ call->expected_version = vnode->status.data_version + 1;
/* marshall the parameters */
bp = call->request;
call->first_offset = offset;
call->last_to = to;
call->send_pages = true;
- call->store_version = vnode->status.data_version + 1;
+ call->expected_version = vnode->status.data_version + 1;
/* marshall the parameters */
bp = call->request;
*/
static int afs_deliver_fs_store_status(struct afs_call *call)
{
- afs_dataversion_t *store_version;
struct afs_vnode *vnode = call->reply[0];
const __be32 *bp;
int ret;
return ret;
/* unmarshall the reply once we've received all of it */
- store_version = NULL;
- if (call->operation_ID == FSSTOREDATA)
- store_version = &call->store_version;
-
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
+ xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
+ &call->expected_version, NULL);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
_leave(" = 0 [done]");
call->key = fc->key;
call->reply[0] = vnode;
- call->store_version = vnode->status.data_version + 1;
+ call->expected_version = vnode->status.data_version + 1;
/* marshall the parameters */
bp = call->request;
call->key = fc->key;
call->reply[0] = vnode;
- call->store_version = vnode->status.data_version + 1;
+ call->expected_version = vnode->status.data_version + 1;
/* marshall the parameters */
bp = call->request;
call->key = fc->key;
call->reply[0] = vnode;
+ call->expected_version = vnode->status.data_version;
/* marshall the parameters */
bp = call->request;
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
- xdr_decode_AFSFetchStatus(&bp, status, vnode, NULL);
+ xdr_decode_AFSFetchStatus(&bp, status, vnode,
+ &call->expected_version, NULL);
callback[call->count].version = ntohl(bp[0]);
callback[call->count].expiry = ntohl(bp[1]);
callback[call->count].type = ntohl(bp[2]);
call->reply[1] = status;
call->reply[2] = callback;
call->reply[3] = volsync;
+ call->expected_version = 1; /* vnode->status.data_version */
/* marshall the parameters */
bp = call->request;
statuses = call->reply[1];
xdr_decode_AFSFetchStatus(&bp, &statuses[call->count],
call->count == 0 ? vnode : NULL,
- NULL);
+ NULL, NULL);
call->count++;
if (call->count < call->count2)