propagating file change attr on writes

This commit is contained in:
Olga Kornievskaia 2012-02-08 16:29:25 -05:00
parent ec034e7fd9
commit aa7a680a40
8 changed files with 63 additions and 35 deletions

View file

@ -700,7 +700,8 @@ int nfs41_write(
IN uint64_t offset,
IN enum stable_how4 stable,
OUT uint32_t *bytes_written,
OUT nfs41_write_verf *verf)
OUT nfs41_write_verf *verf,
OUT nfs41_file_info *cinfo)
{
int status;
nfs41_compound compound;
@ -715,7 +716,7 @@ int nfs41_write(
nfs41_getattr_args getattr_args;
nfs41_getattr_res getattr_res = {0};
bitmap4 attr_request;
nfs41_file_info info = { 0 };
nfs41_file_info info = { 0 }, *pinfo;
init_getattr_request(&attr_request);
@ -739,13 +740,16 @@ int nfs41_write(
write_args.data = data;
write_res.resok4.verf = verf;
if (cinfo) pinfo = cinfo;
else pinfo = &info;
if (stable != UNSTABLE4) {
/* if the write is stable, we can't rely on COMMIT to update
* the attribute cache, so we do the GETATTR here */
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
getattr_args.attr_request = &attr_request;
getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
getattr_res.info = &info;
getattr_res.info = pinfo;
}
status = compound_encode_send_decode(session, &compound, TRUE);
@ -757,10 +761,10 @@ int nfs41_write(
if (stable != UNSTABLE4) {
/* update the attribute cache */
memcpy(&info.attrmask, &getattr_res.obj_attributes.attrmask,
memcpy(&pinfo->attrmask, &getattr_res.obj_attributes.attrmask,
sizeof(bitmap4));
nfs41_attr_cache_update(session_name_cache(session),
file->fh.fileid, &info);
file->fh.fileid, pinfo);
}
*bytes_written = write_res.resok4.count;
@ -773,7 +777,7 @@ int nfs41_write(
nfs_error_string(status));
}
if (info.type == NF4NAMEDATTR)
if (pinfo->type == NF4NAMEDATTR)
goto out;
nfs41_superblock_space_changed(file->fh.superblock);
@ -848,7 +852,8 @@ int nfs41_commit(
IN uint64_t offset,
IN uint32_t count,
IN bool_t do_getattr,
OUT nfs41_write_verf *verf)
OUT nfs41_write_verf *verf,
OUT nfs41_file_info *cinfo)
{
int status;
nfs41_compound compound;
@ -863,7 +868,7 @@ int nfs41_commit(
nfs41_getattr_args getattr_args;
nfs41_getattr_res getattr_res = {0};
bitmap4 attr_request;
nfs41_file_info info;
nfs41_file_info info, *pinfo;
compound_init(&compound, argops, resops,
do_getattr ? "commit" : "ds commit");
@ -884,13 +889,15 @@ int nfs41_commit(
/* send a GETATTR request to update the attribute cache,
* but not if we're talking to a data server! */
if (cinfo) pinfo = cinfo;
else pinfo = &info;
if (do_getattr) {
init_getattr_request(&attr_request);
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
getattr_args.attr_request = &attr_request;
getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
getattr_res.info = &info;
getattr_res.info = pinfo;
}
status = compound_encode_send_decode(session, &compound, TRUE);
@ -902,10 +909,10 @@ int nfs41_commit(
if (do_getattr) {
/* update the attribute cache */
memcpy(&info.attrmask, &getattr_res.obj_attributes.attrmask,
memcpy(&pinfo->attrmask, &getattr_res.obj_attributes.attrmask,
sizeof(bitmap4));
nfs41_attr_cache_update(session_name_cache(session),
file->fh.fileid, &info);
file->fh.fileid, pinfo);
}
nfs41_superblock_space_changed(file->fh.superblock);
out:
@ -2001,7 +2008,8 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
IN uint64_t offset,
IN uint64_t length,
IN OPTIONAL uint64_t *new_last_offset,
IN OPTIONAL nfstime4 *new_time_modify)
IN OPTIONAL nfstime4 *new_time_modify,
OUT nfs41_file_info *info)
{
enum nfsstat4 status;
nfs41_compound compound;
@ -2015,7 +2023,6 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
pnfs_layoutcommit_res lc_res;
nfs41_getattr_args getattr_args;
nfs41_getattr_res getattr_res;
nfs41_file_info info;
bitmap4 attr_request;
init_getattr_request(&attr_request);
@ -2041,7 +2048,7 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
getattr_args.attr_request = &attr_request;
getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
getattr_res.info = &info;
getattr_res.info = info;
status = compound_encode_send_decode(session, &compound, TRUE);
if (status)
@ -2051,10 +2058,10 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
goto out;
/* update the attribute cache */
memcpy(&info.attrmask, &getattr_res.obj_attributes.attrmask,
memcpy(&info->attrmask, &getattr_res.obj_attributes.attrmask,
sizeof(bitmap4));
nfs41_attr_cache_update(session_name_cache(session),
file->fh.fileid, &info);
file->fh.fileid, info);
out:
return status;
}

View file

@ -1078,7 +1078,8 @@ int nfs41_write(
IN uint64_t offset,
IN enum stable_how4 stable,
OUT uint32_t *bytes_written,
OUT nfs41_write_verf *verf);
OUT nfs41_write_verf *verf,
OUT nfs41_file_info *cinfo);
int nfs41_read(
IN nfs41_session *session,
@ -1096,7 +1097,8 @@ int nfs41_commit(
IN uint64_t offset,
IN uint32_t count,
IN bool_t do_getattr,
OUT nfs41_write_verf *verf);
OUT nfs41_write_verf *verf,
OUT nfs41_file_info *cinfo);
int nfs41_lock(
IN nfs41_session *session,
@ -1257,7 +1259,8 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
IN uint64_t offset,
IN uint64_t length,
IN OPTIONAL uint64_t *new_last_offset,
IN OPTIONAL nfstime4 *new_time_modify);
IN OPTIONAL nfstime4 *new_time_modify,
OUT nfs41_file_info *info);
enum nfsstat4 pnfs_rpc_layoutreturn(
IN nfs41_session *session,

View file

@ -381,6 +381,7 @@ enum pnfs_status pnfs_write(
IN uint64_t offset,
IN uint64_t length,
IN unsigned char *buffer,
OUT ULONG *len_out);
OUT ULONG *len_out,
OUT nfs41_file_info *cinfo);
#endif /* !__PNFS_H__ */

View file

@ -371,7 +371,8 @@ retry_write:
io.length = maxwritesize;
nfsstat = nfs41_write(client->session, io.file, &stateid, io.buffer,
(uint32_t)io.length, io.offset, UNSTABLE4, &bytes_written, &verf);
(uint32_t)io.length, io.offset, UNSTABLE4, &bytes_written,
&verf, NULL);
if (nfsstat) {
eprintf("nfs41_write() failed with %s\n",
nfs_error_string(nfsstat));
@ -409,7 +410,7 @@ retry_write:
dprintf(1, "sending COMMIT to data server for offset=%lld len=%lld\n",
commit_min, commit_max - commit_min);
nfsstat = nfs41_commit(client->session, commit_file,
commit_min, (uint32_t)(commit_max - commit_min), 0, &verf);
commit_min, (uint32_t)(commit_max - commit_min), 0, &verf, NULL);
if (nfsstat)
status = map_ds_error(nfsstat, pattern->state);
@ -473,7 +474,8 @@ static enum pnfs_status layout_commit(
IN nfs41_open_state *state,
IN pnfs_layout_state *layout,
IN uint64_t offset,
IN uint64_t length)
IN uint64_t length,
OUT nfs41_file_info *info)
{
stateid4 layout_stateid;
uint64_t last_offset = offset + length - 1;
@ -498,7 +500,7 @@ static enum pnfs_status layout_commit(
dprintf(1, "LAYOUTCOMMIT for offset=%lld len=%lld new_last_offset=%u\n",
offset, length, new_last_offset ? 1 : 0);
nfsstat = pnfs_rpc_layoutcommit(state->session, &state->file,
&layout_stateid, offset, length, new_last_offset, NULL);
&layout_stateid, offset, length, new_last_offset, NULL, info);
if (nfsstat) {
dprintf(IOLVL, "pnfs_rpc_layoutcommit() failed with %s\n",
nfs_error_string(nfsstat));
@ -515,7 +517,8 @@ enum pnfs_status pnfs_write(
IN uint64_t offset,
IN uint64_t length,
IN unsigned char *buffer,
OUT ULONG *len_out)
OUT ULONG *len_out,
OUT nfs41_file_info *info)
{
pnfs_io_pattern pattern;
enum stable_how4 stable;
@ -550,7 +553,7 @@ enum pnfs_status pnfs_write(
dprintf(1, "sending COMMIT to meta server for offset=%lld len=%lld\n",
offset, *len_out);
nfsstat = nfs41_commit(state->session, &state->file,
offset, *len_out, 1, &ignored);
offset, *len_out, 1, &ignored, info);
if (nfsstat) {
dprintf(IOLVL, "nfs41_commit() failed with %s\n",
nfs_error_string(nfsstat));
@ -558,13 +561,12 @@ enum pnfs_status pnfs_write(
}
} else if (stable == DATA_SYNC4) {
/* send LAYOUTCOMMIT to sync the metadata */
status = layout_commit(state, layout, offset, *len_out);
status = layout_commit(state, layout, offset, *len_out, info);
} else {
/* send a GETATTR to update the cached size */
nfs41_file_info info = { 0 };
bitmap4 attr_request;
init_getattr_request(&attr_request);
nfs41_getattr(state->session, &state->file, &attr_request, &info);
nfs41_getattr(state->session, &state->file, &attr_request, info);
}
out_free_pattern:
pattern_free(&pattern);

View file

@ -190,6 +190,7 @@ static int write_to_mds(
int status = 0;
/* on write verifier mismatch, retry N times before failing */
uint32_t retries = MAX_WRITE_RETRIES;
nfs41_file_info info = { 0 };
retry_write:
p = args->buffer;
@ -207,7 +208,7 @@ retry_write:
uint32_t bytes_written = 0, chunk = min(to_send, maxwritesize);
status = nfs41_write(session, file, stateid, p, chunk,
args->offset + reloffset, stable, &bytes_written, &verf);
args->offset + reloffset, stable, &bytes_written, &verf, &info);
if (status && !len)
goto out;
p += bytes_written;
@ -225,7 +226,7 @@ retry_write:
}
if (committed != FILE_SYNC4) {
dprintf(1, "sending COMMIT for offset=%d and len=%d\n", args->offset, len);
status = nfs41_commit(session, file, args->offset, len, 1, &verf);
status = nfs41_commit(session, file, args->offset, len, 1, &verf, &info);
if (status)
goto out;
@ -234,6 +235,7 @@ retry_write:
goto out_verify_failed;
}
}
args->ctime = info.change;
out:
args->out_len = len;
return nfs_to_windows_error(status, ERROR_NET_WRITE_FAULT);
@ -251,6 +253,7 @@ static int write_to_pnfs(
readwrite_upcall_args *args = &upcall->args.rw;
pnfs_layout_state *layout;
int status = NO_ERROR;
nfs41_file_info info = { 0 };
if (pnfs_layout_state_open(upcall->state_ref, PNFS_IOMODE_RW, args->offset,
args->len, &layout)) {
@ -259,10 +262,11 @@ static int write_to_pnfs(
}
if (pnfs_write(upcall->root_ref, upcall->state_ref, stateid, layout,
args->offset, args->len, args->buffer, &args->out_len)) {
args->offset, args->len, args->buffer, &args->out_len, &info)) {
status = ERROR_WRITE_FAULT;
goto out;
}
args->ctime = info.change;
out:
return status;
}
@ -301,7 +305,12 @@ out:
static int marshall_rw(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
{
readwrite_upcall_args *args = &upcall->args.rw;
return safe_write(&buffer, length, &args->out_len, sizeof(args->out_len));
int status;
status = safe_write(&buffer, length, &args->out_len, sizeof(args->out_len));
if (status) goto out;
status = safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
out:
return status;
}

View file

@ -584,7 +584,8 @@ static int handle_setexattr(nfs41_upcall *upcall)
stateid.stateid.seqid = 0;
buf = (UCHAR *) eainfo->EaName + eainfo->EaNameLength + 1;
status = nfs41_write(state->session, &file, &stateid, buf,
eainfo->EaValueLength, 0, FILE_SYNC4, &bytes_written, &verf);
eainfo->EaValueLength, 0, FILE_SYNC4, &bytes_written,
&verf, NULL);
if (status) {
dprintf(1, "handle_setexattr: nfs41_write() failed w/error %s.\n",
nfs_error_string(status));

View file

@ -72,6 +72,7 @@ typedef struct __readwrite_upcall_args {
LONGLONG offset;
ULONG len;
ULONG out_len;
ULONGLONG ctime;
} readwrite_upcall_args;
typedef struct __lock_upcall_args {