diff options
Diffstat (limited to 'fs/afs/yfsclient.c')
-rw-r--r-- | fs/afs/yfsclient.c | 534 |
1 files changed, 149 insertions, 385 deletions
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c index b3ee99972d2f..80f579594660 100644 --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c @@ -183,24 +183,18 @@ static void xdr_dump_bad(const __be32 *bp) /* * Decode a YFSFetchStatus block */ -static int xdr_decode_YFSFetchStatus(struct afs_call *call, - const __be32 **_bp, - struct afs_file_status *status, - struct afs_vnode *vnode, - const afs_dataversion_t *expected_version, - struct afs_read *read_req) +static int xdr_decode_YFSFetchStatus(const __be32 **_bp, + struct afs_call *call, + struct afs_status_cb *scb) { const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp; + struct afs_file_status *status = &scb->status; u32 type; - u8 flags = 0; status->abort_code = ntohl(xdr->abort_code); if (status->abort_code != 0) { - if (vnode && status->abort_code == VNOVNODE) { - set_bit(AFS_VNODE_DELETED, &vnode->flags); + if (status->abort_code == VNOVNODE) status->nlink = 0; - __afs_break_callback(vnode); - } return 0; } @@ -209,77 +203,27 @@ static int xdr_decode_YFSFetchStatus(struct afs_call *call, case AFS_FTYPE_FILE: case AFS_FTYPE_DIR: case AFS_FTYPE_SYMLINK: - if (type != status->type && - vnode && - !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { - pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n", - vnode->fid.vid, - vnode->fid.vnode, - vnode->fid.unique, - status->type, type); - goto bad; - } status->type = type; break; default: goto bad; } -#define EXTRACT_M4(FIELD) \ - do { \ - u32 x = ntohl(xdr->FIELD); \ - if (status->FIELD != x) { \ - flags |= AFS_VNODE_META_CHANGED; \ - status->FIELD = x; \ - } \ - } while (0) - -#define EXTRACT_M8(FIELD) \ - do { \ - u64 x = xdr_to_u64(xdr->FIELD); \ - if (status->FIELD != x) { \ - flags |= AFS_VNODE_META_CHANGED; \ - status->FIELD = x; \ - } \ - } while (0) - -#define EXTRACT_D8(FIELD) \ - do { \ - u64 x = xdr_to_u64(xdr->FIELD); \ - if (status->FIELD != x) { \ - flags |= AFS_VNODE_DATA_CHANGED; \ - status->FIELD = x; \ - } \ - } while (0) - - EXTRACT_M4(nlink); - EXTRACT_D8(size); - EXTRACT_D8(data_version); - EXTRACT_M8(author); - EXTRACT_M8(owner); - EXTRACT_M8(group); - EXTRACT_M4(mode); - EXTRACT_M4(caller_access); /* call ticket dependent */ - EXTRACT_M4(anon_access); - - status->mtime_client = xdr_to_time(xdr->mtime_client); - status->mtime_server = xdr_to_time(xdr->mtime_server); - status->lock_count = ntohl(xdr->lock_count); - - if (read_req) { - read_req->data_version = status->data_version; - read_req->file_size = status->size; - } - - *_bp += xdr_size(xdr); + status->nlink = ntohl(xdr->nlink); + status->author = xdr_to_u64(xdr->author); + status->owner = xdr_to_u64(xdr->owner); + status->caller_access = ntohl(xdr->caller_access); /* Ticket dependent */ + status->anon_access = ntohl(xdr->anon_access); + status->mode = ntohl(xdr->mode) & S_IALLUGO; + status->group = xdr_to_u64(xdr->group); + status->lock_count = ntohl(xdr->lock_count); - if (vnode) { - if (test_bit(AFS_VNODE_UNSET, &vnode->flags)) - flags |= AFS_VNODE_NOT_YET_SET; - afs_update_inode_from_status(vnode, status, expected_version, - flags); - } + status->mtime_client = xdr_to_time(xdr->mtime_client); + status->mtime_server = xdr_to_time(xdr->mtime_server); + status->size = xdr_to_u64(xdr->size); + status->data_version = xdr_to_u64(xdr->data_version); + *_bp += xdr_size(xdr); return 0; bad: @@ -288,34 +232,14 @@ bad: } /* - * Decode the file status. We need to lock the target vnode if we're going to - * update its status so that stat() sees the attributes update atomically. + * Decode a YFSCallBack block */ -static int yfs_decode_status(struct afs_call *call, - const __be32 **_bp, - struct afs_file_status *status, - struct afs_vnode *vnode, - const afs_dataversion_t *expected_version, - struct afs_read *read_req) -{ - int ret; - - if (!vnode) - return xdr_decode_YFSFetchStatus(call, _bp, status, vnode, - expected_version, read_req); - - write_seqlock(&vnode->cb_lock); - ret = xdr_decode_YFSFetchStatus(call, _bp, status, vnode, - expected_version, read_req); - write_sequnlock(&vnode->cb_lock); - return ret; -} - -static void xdr_decode_YFSCallBack_raw(struct afs_call *call, - struct afs_callback *cb, - const __be32 **_bp) +static void xdr_decode_YFSCallBack(const __be32 **_bp, + struct afs_call *call, + struct afs_status_cb *scb) { struct yfs_xdr_YFSCallBack *x = (void *)*_bp; + struct afs_callback *cb = &scb->callback; ktime_t cb_expiry; cb_expiry = call->reply_time; @@ -323,41 +247,11 @@ static void xdr_decode_YFSCallBack_raw(struct afs_call *call, cb->expires_at = ktime_divns(cb_expiry, NSEC_PER_SEC); cb->version = ntohl(x->version); cb->type = ntohl(x->type); - + scb->have_cb = true; *_bp += xdr_size(x); } /* - * Decode a YFSCallBack block - */ -static void xdr_decode_YFSCallBack(struct afs_call *call, - struct afs_vnode *vnode, - const __be32 **_bp) -{ - struct afs_cb_interest *old, *cbi = call->cbi; - struct afs_callback cb; - - xdr_decode_YFSCallBack_raw(call, &cb, _bp); - - write_seqlock(&vnode->cb_lock); - - if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) { - vnode->cb_version = cb.version; - vnode->cb_type = cb.type; - vnode->cb_expires_at = cb.expires_at; - old = vnode->cb_interest; - if (old != call->cbi) { - vnode->cb_interest = cbi; - cbi = old; - } - set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); - } - - write_sequnlock(&vnode->cb_lock); - call->cbi = cbi; -} - -/* * Decode a YFSVolSync block */ static void xdr_decode_YFSVolSync(const __be32 **_bp, @@ -441,11 +335,10 @@ static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp, } /* - * deliver reply data to an FS.FetchStatus + * Deliver a reply that's a status, callback and volsync. */ -static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call) +static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call) { - struct afs_vnode *vnode = call->xvnode; const __be32 *bp; int ret; @@ -453,15 +346,35 @@ static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call) if (ret < 0) return ret; - _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); - /* unmarshall the reply once we've received all of it */ bp = call->buffer; - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); + if (ret < 0) + return ret; + xdr_decode_YFSCallBack(&bp, call, call->out_scb); + xdr_decode_YFSVolSync(&bp, call->out_volsync); + + _leave(" = 0 [done]"); + return 0; +} + +/* + * Deliver reply data to operations that just return a file status and a volume + * sync record. + */ +static int yfs_deliver_status_and_volsync(struct afs_call *call) +{ + const __be32 *bp; + int ret; + + ret = afs_transfer_reply(call); + if (ret < 0) + return ret; + + bp = call->buffer; + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; - xdr_decode_YFSCallBack(call, vnode, &bp); xdr_decode_YFSVolSync(&bp, call->out_volsync); _leave(" = 0 [done]"); @@ -474,15 +387,15 @@ static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call) static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = { .name = "YFS.FetchStatus(vnode)", .op = yfs_FS_FetchStatus, - .deliver = yfs_deliver_fs_fetch_status_vnode, + .deliver = yfs_deliver_fs_status_cb_and_volsync, .destructor = afs_flat_call_destructor, }; /* * Fetch the status information for a file. */ -int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync, - bool new_inode) +int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb, + struct afs_volsync *volsync) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -504,9 +417,8 @@ int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy } call->key = fc->key; - call->xvnode = vnode; + call->out_scb = scb; call->out_volsync = volsync; - call->expected_version = new_inode ? 1 : vnode->status.data_version; /* marshall the parameters */ bp = call->request; @@ -515,7 +427,6 @@ int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy bp = xdr_encode_YFSFid(bp, &vnode->fid); yfs_check_req(call, bp); - call->cb_break = fc->cb_break; afs_use_fs_server(call, fc->cbi); trace_afs_make_fs_call(call, &vnode->fid); afs_set_fc_call(call, fc); @@ -528,7 +439,6 @@ int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy */ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) { - struct afs_vnode *vnode = call->xvnode; struct afs_read *req = call->read_request; const __be32 *bp; unsigned int size; @@ -586,7 +496,7 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) if (req->offset == PAGE_SIZE) { req->offset = 0; if (req->page_done) - req->page_done(call, req); + req->page_done(req); req->index++; if (req->remain > 0) goto begin_page; @@ -623,13 +533,15 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) return ret; bp = call->buffer; - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, - &vnode->status.data_version, req); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; - xdr_decode_YFSCallBack(call, vnode, &bp); + xdr_decode_YFSCallBack(&bp, call, call->out_scb); xdr_decode_YFSVolSync(&bp, call->out_volsync); + req->data_version = call->out_scb->status.data_version; + req->file_size = call->out_scb->status.size; + call->unmarshall++; /* Fall through */ @@ -642,7 +554,7 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) zero_user_segment(req->pages[req->index], req->offset, PAGE_SIZE); if (req->page_done) - req->page_done(call, req); + req->page_done(req); req->offset = 0; } @@ -669,7 +581,8 @@ static const struct afs_call_type yfs_RXYFSFetchData64 = { /* * Fetch data from a file. */ -int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) +int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb, + struct afs_read *req) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -691,10 +604,9 @@ int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) return -ENOMEM; call->key = fc->key; - call->xvnode = vnode; + call->out_scb = scb; call->out_volsync = NULL; call->read_request = req; - call->expected_version = vnode->status.data_version; /* marshall the parameters */ bp = call->request; @@ -706,7 +618,6 @@ int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) yfs_check_req(call, bp); refcount_inc(&req->usage); - call->cb_break = fc->cb_break; afs_use_fs_server(call, fc->cbi); trace_afs_make_fs_call(call, &vnode->fid); afs_set_fc_call(call, fc); @@ -719,7 +630,6 @@ int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) */ static int yfs_deliver_fs_create_vnode(struct afs_call *call) { - struct afs_vnode *dvnode = call->dvnode; const __be32 *bp; int ret; @@ -732,15 +642,14 @@ static int yfs_deliver_fs_create_vnode(struct afs_call *call) /* unmarshall the reply once we've received all of it */ bp = call->buffer; xdr_decode_YFSFid(&bp, call->out_fid); - ret = yfs_decode_status(call, &bp, call->out_extra_status, NULL, NULL, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; - ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - xdr_decode_YFSCallBack_raw(call, call->out_cb, &bp); - xdr_decode_YFSVolSync(&bp, NULL); + xdr_decode_YFSCallBack(&bp, call, call->out_scb); + xdr_decode_YFSVolSync(&bp, call->out_volsync); _leave(" = 0 [done]"); return 0; @@ -762,10 +671,9 @@ static const struct afs_call_type afs_RXFSCreateFile = { int yfs_fs_create_file(struct afs_fs_cursor *fc, const char *name, umode_t mode, - u64 current_data_version, + struct afs_status_cb *dvnode_scb, struct afs_fid *newfid, - struct afs_file_status *newstatus, - struct afs_callback *newcb) + struct afs_status_cb *new_scb) { struct afs_vnode *dvnode = fc->vnode; struct afs_call *call; @@ -793,11 +701,9 @@ int yfs_fs_create_file(struct afs_fs_cursor *fc, return -ENOMEM; call->key = fc->key; - call->dvnode = dvnode; + call->out_dir_scb = dvnode_scb; call->out_fid = newfid; - call->out_extra_status = newstatus; - call->out_cb = newcb; - call->expected_version = current_data_version + 1; + call->out_scb = new_scb; /* marshall the parameters */ bp = call->request; @@ -829,10 +735,9 @@ static const struct afs_call_type yfs_RXFSMakeDir = { int yfs_fs_make_dir(struct afs_fs_cursor *fc, const char *name, umode_t mode, - u64 current_data_version, + struct afs_status_cb *dvnode_scb, struct afs_fid *newfid, - struct afs_file_status *newstatus, - struct afs_callback *newcb) + struct afs_status_cb *new_scb) { struct afs_vnode *dvnode = fc->vnode; struct afs_call *call; @@ -859,11 +764,9 @@ int yfs_fs_make_dir(struct afs_fs_cursor *fc, return -ENOMEM; call->key = fc->key; - call->dvnode = dvnode; + call->out_dir_scb = dvnode_scb; call->out_fid = newfid; - call->out_extra_status = newstatus; - call->out_cb = newcb; - call->expected_version = current_data_version + 1; + call->out_scb = new_scb; /* marshall the parameters */ bp = call->request; @@ -886,8 +789,6 @@ int yfs_fs_make_dir(struct afs_fs_cursor *fc, */ static int yfs_deliver_fs_remove_file2(struct afs_call *call) { - struct afs_vnode *dvnode = call->dvnode; - struct afs_vnode *vnode = call->xvnode; struct afs_fid fid; const __be32 *bp; int ret; @@ -898,20 +799,18 @@ static int yfs_deliver_fs_remove_file2(struct afs_call *call) if (ret < 0) return ret; - /* unmarshall the reply once we've received all of it */ bp = call->buffer; - ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; xdr_decode_YFSFid(&bp, &fid); - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; /* Was deleted if vnode->status.abort_code == VNOVNODE. */ - xdr_decode_YFSVolSync(&bp, NULL); + xdr_decode_YFSVolSync(&bp, call->out_volsync); return 0; } @@ -929,7 +828,8 @@ static const struct afs_call_type yfs_RXYFSRemoveFile2 = { * Remove a file and retrieve new file status. */ int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, - const char *name, u64 current_data_version) + const char *name, struct afs_status_cb *dvnode_scb, + struct afs_status_cb *vnode_scb) { struct afs_vnode *dvnode = fc->vnode; struct afs_call *call; @@ -954,9 +854,8 @@ int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, return -ENOMEM; call->key = fc->key; - call->dvnode = dvnode; - call->xvnode = vnode; - call->expected_version = current_data_version + 1; + call->out_dir_scb = dvnode_scb; + call->out_scb = vnode_scb; /* marshall the parameters */ bp = call->request; @@ -978,7 +877,6 @@ int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, */ static int yfs_deliver_fs_remove(struct afs_call *call) { - struct afs_vnode *dvnode = call->dvnode; const __be32 *bp; int ret; @@ -988,14 +886,12 @@ static int yfs_deliver_fs_remove(struct afs_call *call) if (ret < 0) return ret; - /* unmarshall the reply once we've received all of it */ bp = call->buffer; - ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - xdr_decode_YFSVolSync(&bp, NULL); + xdr_decode_YFSVolSync(&bp, call->out_volsync); return 0; } @@ -1020,7 +916,8 @@ static const struct afs_call_type yfs_RXYFSRemoveDir = { * remove a file or directory */ int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, - const char *name, bool isdir, u64 current_data_version) + const char *name, bool isdir, + struct afs_status_cb *dvnode_scb) { struct afs_vnode *dvnode = fc->vnode; struct afs_call *call; @@ -1043,9 +940,7 @@ int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, return -ENOMEM; call->key = fc->key; - call->dvnode = dvnode; - call->xvnode = vnode; - call->expected_version = current_data_version + 1; + call->out_dir_scb = dvnode_scb; /* marshall the parameters */ bp = call->request; @@ -1067,7 +962,6 @@ int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, */ static int yfs_deliver_fs_link(struct afs_call *call) { - struct afs_vnode *dvnode = call->dvnode, *vnode = call->xvnode; const __be32 *bp; int ret; @@ -1077,16 +971,14 @@ static int yfs_deliver_fs_link(struct afs_call *call) if (ret < 0) return ret; - /* unmarshall the reply once we've received all of it */ bp = call->buffer; - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; - ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - xdr_decode_YFSVolSync(&bp, NULL); + xdr_decode_YFSVolSync(&bp, call->out_volsync); _leave(" = 0 [done]"); return 0; } @@ -1105,7 +997,9 @@ static const struct afs_call_type yfs_RXYFSLink = { * Make a hard link. */ int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, - const char *name, u64 current_data_version) + const char *name, + struct afs_status_cb *dvnode_scb, + struct afs_status_cb *vnode_scb) { struct afs_vnode *dvnode = fc->vnode; struct afs_call *call; @@ -1129,9 +1023,8 @@ int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, return -ENOMEM; call->key = fc->key; - call->dvnode = dvnode; - call->xvnode = vnode; - call->expected_version = current_data_version + 1; + call->out_dir_scb = dvnode_scb; + call->out_scb = vnode_scb; /* marshall the parameters */ bp = call->request; @@ -1154,7 +1047,6 @@ int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, */ static int yfs_deliver_fs_symlink(struct afs_call *call) { - struct afs_vnode *dvnode = call->dvnode; const __be32 *bp; int ret; @@ -1167,14 +1059,13 @@ static int yfs_deliver_fs_symlink(struct afs_call *call) /* unmarshall the reply once we've received all of it */ bp = call->buffer; xdr_decode_YFSFid(&bp, call->out_fid); - ret = yfs_decode_status(call, &bp, call->out_extra_status, NULL, NULL, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; - ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - xdr_decode_YFSVolSync(&bp, NULL); + xdr_decode_YFSVolSync(&bp, call->out_volsync); _leave(" = 0 [done]"); return 0; @@ -1196,9 +1087,9 @@ static const struct afs_call_type yfs_RXYFSSymlink = { int yfs_fs_symlink(struct afs_fs_cursor *fc, const char *name, const char *contents, - u64 current_data_version, + struct afs_status_cb *dvnode_scb, struct afs_fid *newfid, - struct afs_file_status *newstatus) + struct afs_status_cb *vnode_scb) { struct afs_vnode *dvnode = fc->vnode; struct afs_call *call; @@ -1225,10 +1116,9 @@ int yfs_fs_symlink(struct afs_fs_cursor *fc, return -ENOMEM; call->key = fc->key; - call->dvnode = dvnode; + call->out_dir_scb = dvnode_scb; call->out_fid = newfid; - call->out_extra_status = newstatus; - call->expected_version = current_data_version + 1; + call->out_scb = vnode_scb; /* marshall the parameters */ bp = call->request; @@ -1252,8 +1142,6 @@ int yfs_fs_symlink(struct afs_fs_cursor *fc, */ static int yfs_deliver_fs_rename(struct afs_call *call) { - struct afs_vnode *orig_dvnode = call->dvnode; - struct afs_vnode *new_dvnode = call->xvnode; const __be32 *bp; int ret; @@ -1263,20 +1151,17 @@ static int yfs_deliver_fs_rename(struct afs_call *call) if (ret < 0) return ret; - /* unmarshall the reply once we've received all of it */ bp = call->buffer; - ret = yfs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - if (new_dvnode != orig_dvnode) { - ret = yfs_decode_status(call, &bp, &new_dvnode->status, new_dvnode, - &call->expected_version_2, NULL); + if (call->out_dir_scb != call->out_scb) { + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; } - xdr_decode_YFSVolSync(&bp, NULL); + xdr_decode_YFSVolSync(&bp, call->out_volsync); _leave(" = 0 [done]"); return 0; } @@ -1298,8 +1183,8 @@ int yfs_fs_rename(struct afs_fs_cursor *fc, const char *orig_name, struct afs_vnode *new_dvnode, const char *new_name, - u64 current_orig_data_version, - u64 current_new_data_version) + struct afs_status_cb *orig_dvnode_scb, + struct afs_status_cb *new_dvnode_scb) { struct afs_vnode *orig_dvnode = fc->vnode; struct afs_call *call; @@ -1325,10 +1210,8 @@ int yfs_fs_rename(struct afs_fs_cursor *fc, return -ENOMEM; call->key = fc->key; - call->dvnode = orig_dvnode; - call->xvnode = new_dvnode; - call->expected_version = current_orig_data_version + 1; - call->expected_version_2 = current_new_data_version + 1; + call->out_dir_scb = orig_dvnode_scb; + call->out_scb = new_dvnode_scb; /* marshall the parameters */ bp = call->request; @@ -1348,41 +1231,12 @@ int yfs_fs_rename(struct afs_fs_cursor *fc, } /* - * Deliver reply data to a YFS.StoreData64 operation. - */ -static int yfs_deliver_fs_store_data(struct afs_call *call) -{ - struct afs_vnode *vnode = call->xvnode; - const __be32 *bp; - int ret; - - _enter(""); - - ret = afs_transfer_reply(call); - if (ret < 0) - return ret; - - /* unmarshall the reply once we've received all of it */ - bp = call->buffer; - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, - &call->expected_version, NULL); - if (ret < 0) - return ret; - xdr_decode_YFSVolSync(&bp, NULL); - - afs_pages_written_back(vnode, call); - - _leave(" = 0 [done]"); - return 0; -} - -/* * YFS.StoreData64 operation type. */ static const struct afs_call_type yfs_RXYFSStoreData64 = { .name = "YFS.StoreData64", .op = yfs_FS_StoreData64, - .deliver = yfs_deliver_fs_store_data, + .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; @@ -1391,7 +1245,8 @@ static const struct afs_call_type yfs_RXYFSStoreData64 = { */ int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, pgoff_t first, pgoff_t last, - unsigned offset, unsigned to) + unsigned offset, unsigned to, + struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -1429,13 +1284,12 @@ int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, call->key = fc->key; call->mapping = mapping; - call->xvnode = vnode; call->first = first; call->last = last; call->first_offset = offset; call->last_to = to; call->send_pages = true; - call->expected_version = vnode->status.data_version + 1; + call->out_scb = scb; /* marshall the parameters */ bp = call->request; @@ -1456,46 +1310,19 @@ int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, } /* - * deliver reply data to an FS.StoreStatus - */ -static int yfs_deliver_fs_store_status(struct afs_call *call) -{ - struct afs_vnode *vnode = call->xvnode; - const __be32 *bp; - int ret; - - _enter(""); - - ret = afs_transfer_reply(call); - if (ret < 0) - return ret; - - /* unmarshall the reply once we've received all of it */ - bp = call->buffer; - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, - &call->expected_version, NULL); - if (ret < 0) - return ret; - xdr_decode_YFSVolSync(&bp, NULL); - - _leave(" = 0 [done]"); - return 0; -} - -/* * YFS.StoreStatus operation type */ static const struct afs_call_type yfs_RXYFSStoreStatus = { .name = "YFS.StoreStatus", .op = yfs_FS_StoreStatus, - .deliver = yfs_deliver_fs_store_status, + .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = { .name = "YFS.StoreData64", .op = yfs_FS_StoreData64, - .deliver = yfs_deliver_fs_store_status, + .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; @@ -1503,7 +1330,8 @@ static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = { * Set the attributes on a file, using YFS.StoreData64 rather than * YFS.StoreStatus so as to alter the file size also. */ -static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr) +static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr, + struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -1524,8 +1352,7 @@ static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr) return -ENOMEM; call->key = fc->key; - call->xvnode = vnode; - call->expected_version = vnode->status.data_version + 1; + call->out_scb = scb; /* marshall the parameters */ bp = call->request; @@ -1549,7 +1376,8 @@ static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr) * Set the attributes on a file, using YFS.StoreData64 if there's a change in * file size, and YFS.StoreStatus otherwise. */ -int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr) +int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr, + struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -1557,7 +1385,7 @@ int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr) __be32 *bp; if (attr->ia_valid & ATTR_SIZE) - return yfs_fs_setattr_size(fc, attr); + return yfs_fs_setattr_size(fc, attr, scb); _enter(",%x,{%llx:%llu},,", key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); @@ -1572,8 +1400,7 @@ int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr) return -ENOMEM; call->key = fc->key; - call->xvnode = vnode; - call->expected_version = vnode->status.data_version; + call->out_scb = scb; /* marshall the parameters */ bp = call->request; @@ -1764,34 +1591,6 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, } /* - * Deliver reply data to operations that just return a file status and a volume - * sync record. - */ -static int yfs_deliver_status_and_volsync(struct afs_call *call) -{ - struct afs_vnode *vnode = call->xvnode; - const __be32 *bp; - int ret; - - _enter("{%u}", call->unmarshall); - - ret = afs_transfer_reply(call); - if (ret < 0) - return ret; - - /* unmarshall the reply once we've received all of it */ - bp = call->buffer; - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, - &call->expected_version, NULL); - if (ret < 0) - return ret; - xdr_decode_YFSVolSync(&bp, NULL); - - _leave(" = 0 [done]"); - return 0; -} - -/* * YFS.SetLock operation type */ static const struct afs_call_type yfs_RXYFSSetLock = { @@ -1826,7 +1625,8 @@ static const struct afs_call_type yfs_RXYFSReleaseLock = { /* * Set a lock on a file */ -int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) +int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type, + struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -1845,7 +1645,8 @@ int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) return -ENOMEM; call->key = fc->key; - call->xvnode = vnode; + call->lvnode = vnode; + call->out_scb = scb; /* marshall the parameters */ bp = call->request; @@ -1865,7 +1666,7 @@ int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) /* * extend a lock on a file */ -int yfs_fs_extend_lock(struct afs_fs_cursor *fc) +int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -1883,7 +1684,8 @@ int yfs_fs_extend_lock(struct afs_fs_cursor *fc) return -ENOMEM; call->key = fc->key; - call->xvnode = vnode; + call->lvnode = vnode; + call->out_scb = scb; /* marshall the parameters */ bp = call->request; @@ -1902,7 +1704,7 @@ int yfs_fs_extend_lock(struct afs_fs_cursor *fc) /* * release a lock on a file */ -int yfs_fs_release_lock(struct afs_fs_cursor *fc) +int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -1920,7 +1722,8 @@ int yfs_fs_release_lock(struct afs_fs_cursor *fc) return -ENOMEM; call->key = fc->key; - call->xvnode = vnode; + call->lvnode = vnode; + call->out_scb = scb; /* marshall the parameters */ bp = call->request; @@ -1937,42 +1740,12 @@ int yfs_fs_release_lock(struct afs_fs_cursor *fc) } /* - * Deliver reply data to an FS.FetchStatus with no vnode. - */ -static int yfs_deliver_fs_fetch_status(struct afs_call *call) -{ - struct afs_file_status *status = call->out_extra_status; - struct afs_callback *callback = call->out_cb; - struct afs_volsync *volsync = call->out_volsync; - const __be32 *bp; - int ret; - - ret = afs_transfer_reply(call); - if (ret < 0) - return ret; - - _enter(""); - - /* unmarshall the reply once we've received all of it */ - bp = call->buffer; - ret = yfs_decode_status(call, &bp, status, NULL, - &call->expected_version, NULL); - if (ret < 0) - return ret; - xdr_decode_YFSCallBack_raw(call, callback, &bp); - xdr_decode_YFSVolSync(&bp, volsync); - - _leave(" = 0 [done]"); - return 0; -} - -/* * YFS.FetchStatus operation type */ static const struct afs_call_type yfs_RXYFSFetchStatus = { .name = "YFS.FetchStatus", .op = yfs_FS_FetchStatus, - .deliver = yfs_deliver_fs_fetch_status, + .deliver = yfs_deliver_fs_status_cb_and_volsync, .destructor = afs_flat_call_destructor, }; @@ -1982,8 +1755,7 @@ static const struct afs_call_type yfs_RXYFSFetchStatus = { int yfs_fs_fetch_status(struct afs_fs_cursor *fc, struct afs_net *net, struct afs_fid *fid, - struct afs_file_status *status, - struct afs_callback *callback, + struct afs_status_cb *scb, struct afs_volsync *volsync) { struct afs_call *call; @@ -2004,10 +1776,8 @@ int yfs_fs_fetch_status(struct afs_fs_cursor *fc, } call->key = fc->key; - call->out_extra_status = status; - call->out_cb = callback; + call->out_scb = scb; call->out_volsync = volsync; - call->expected_version = 1; /* vnode->status.data_version */ /* marshall the parameters */ bp = call->request; @@ -2016,7 +1786,6 @@ int yfs_fs_fetch_status(struct afs_fs_cursor *fc, bp = xdr_encode_YFSFid(bp, fid); yfs_check_req(call, bp); - call->cb_break = fc->cb_break; afs_use_fs_server(call, fc->cbi); trace_afs_make_fs_call(call, fid); afs_set_fc_call(call, fc); @@ -2069,8 +1838,7 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) bp = call->buffer; scb = &call->out_scb[call->count]; - ret = yfs_decode_status(call, &bp, &scb->status, - NULL, NULL, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, scb); if (ret < 0) return ret; @@ -2110,8 +1878,7 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) _debug("unmarshall CB array"); bp = call->buffer; scb = &call->out_scb[call->count]; - xdr_decode_YFSCallBack_raw(call, &scb->callback, &bp); - scb->have_cb = true; + xdr_decode_YFSCallBack(&bp, call, scb); call->count++; if (call->count < call->count2) goto more_cbs; @@ -2191,7 +1958,6 @@ int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc, bp = xdr_encode_YFSFid(bp, &fids[i]); yfs_check_req(call, bp); - call->cb_break = fc->cb_break; afs_use_fs_server(call, fc->cbi); trace_afs_make_fs_call(call, &fids[0]); afs_set_fc_call(call, fc); @@ -2204,8 +1970,6 @@ int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc, */ static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) { - struct afs_volsync *volsync = call->out_volsync; - struct afs_vnode *vnode = call->xvnode; struct yfs_acl *yacl = call->out_yacl; struct afs_acl *acl; const __be32 *bp; @@ -2291,11 +2055,10 @@ static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) bp = call->buffer; yacl->inherit_flag = ntohl(*bp++); yacl->num_cleaned = ntohl(*bp++); - ret = yfs_decode_status(call, &bp, &vnode->status, vnode, - &call->expected_version, NULL); + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); if (ret < 0) return ret; - xdr_decode_YFSVolSync(&bp, volsync); + xdr_decode_YFSVolSync(&bp, call->out_volsync); call->unmarshall++; @@ -2330,7 +2093,8 @@ static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = { * Fetch the YFS advanced ACLs for a file. */ struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, - struct yfs_acl *yacl) + struct yfs_acl *yacl, + struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -2353,8 +2117,8 @@ struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, call->key = fc->key; call->out_yacl = yacl; - call->xvnode = vnode; - call->out_volsync = NULL; /* volsync */ + call->out_scb = scb; + call->out_volsync = NULL; /* marshall the parameters */ bp = call->request; @@ -2363,7 +2127,6 @@ struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, bp = xdr_encode_YFSFid(bp, &vnode->fid); yfs_check_req(call, bp); - call->cb_break = fc->cb_break; afs_use_fs_server(call, fc->cbi); trace_afs_make_fs_call(call, &vnode->fid); afs_make_call(&fc->ac, call, GFP_KERNEL); @@ -2383,7 +2146,8 @@ static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = { /* * Fetch the YFS ACL for a file. */ -int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl) +int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl, + struct afs_status_cb *scb) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; @@ -2407,7 +2171,7 @@ int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl } call->key = fc->key; - call->xvnode = vnode; + call->out_scb = scb; call->out_volsync = NULL; /* marshall the parameters */ |