propagating file change attr on writes
This commit is contained in:
parent
ec034e7fd9
commit
aa7a680a40
8 changed files with 63 additions and 35 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue