propagating file change attr on setattr
This commit is contained in:
parent
aa7a680a40
commit
cdf31d3ee0
5 changed files with 57 additions and 19 deletions
|
|
@ -1385,7 +1385,8 @@ int nfs41_link(
|
||||||
IN nfs41_path_fh *src,
|
IN nfs41_path_fh *src,
|
||||||
IN nfs41_path_fh *dst_dir,
|
IN nfs41_path_fh *dst_dir,
|
||||||
IN const nfs41_component *target,
|
IN const nfs41_component *target,
|
||||||
OUT OPTIONAL nfs41_path_fh *link_out)
|
OUT OPTIONAL nfs41_path_fh *link_out,
|
||||||
|
OUT nfs41_file_info *cinfo)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
nfs41_compound compound;
|
nfs41_compound compound;
|
||||||
|
|
@ -1403,15 +1404,15 @@ int nfs41_link(
|
||||||
nfs41_getfh_res getfh_res;
|
nfs41_getfh_res getfh_res;
|
||||||
nfs41_getattr_args getattr_args[2];
|
nfs41_getattr_args getattr_args[2];
|
||||||
nfs41_getattr_res getattr_res[2];
|
nfs41_getattr_res getattr_res[2];
|
||||||
nfs41_file_info info[2] = { 0 };
|
nfs41_file_info info = { 0 };
|
||||||
nfs41_path_fh file;
|
nfs41_path_fh file;
|
||||||
|
|
||||||
if (link_out == NULL)
|
if (link_out == NULL)
|
||||||
link_out = &file;
|
link_out = &file;
|
||||||
|
|
||||||
init_getattr_request(&info[0].attrmask);
|
init_getattr_request(&info.attrmask);
|
||||||
init_getattr_request(&info[1].attrmask);
|
init_getattr_request(&cinfo->attrmask);
|
||||||
info[1].attrmask.arr[0] |= FATTR4_WORD0_FSID;
|
cinfo->attrmask.arr[0] |= FATTR4_WORD0_FSID;
|
||||||
|
|
||||||
compound_init(&compound, argops, resops, "link");
|
compound_init(&compound, argops, resops, "link");
|
||||||
|
|
||||||
|
|
@ -1437,9 +1438,9 @@ int nfs41_link(
|
||||||
|
|
||||||
/* GETATTR(dst_dir) */
|
/* GETATTR(dst_dir) */
|
||||||
compound_add_op(&compound, OP_GETATTR, &getattr_args[0], &getattr_res[0]);
|
compound_add_op(&compound, OP_GETATTR, &getattr_args[0], &getattr_res[0]);
|
||||||
getattr_args[0].attr_request = &info[0].attrmask;
|
getattr_args[0].attr_request = &info.attrmask;
|
||||||
getattr_res[0].obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
getattr_res[0].obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
||||||
getattr_res[0].info = &info[0];
|
getattr_res[0].info = &info;
|
||||||
|
|
||||||
/* LOOKUP(target) */
|
/* LOOKUP(target) */
|
||||||
compound_add_op(&compound, OP_LOOKUP, &lookup_args, &lookup_res);
|
compound_add_op(&compound, OP_LOOKUP, &lookup_args, &lookup_res);
|
||||||
|
|
@ -1447,9 +1448,9 @@ int nfs41_link(
|
||||||
|
|
||||||
/* GETATTR(target) */
|
/* GETATTR(target) */
|
||||||
compound_add_op(&compound, OP_GETATTR, &getattr_args[1], &getattr_res[1]);
|
compound_add_op(&compound, OP_GETATTR, &getattr_args[1], &getattr_res[1]);
|
||||||
getattr_args[1].attr_request = &info[1].attrmask;
|
getattr_args[1].attr_request = &cinfo->attrmask;
|
||||||
getattr_res[1].obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
getattr_res[1].obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
||||||
getattr_res[1].info = &info[1];
|
getattr_res[1].info = cinfo;
|
||||||
|
|
||||||
/* GETFH(target) */
|
/* GETFH(target) */
|
||||||
compound_add_op(&compound, OP_GETFH, NULL, &getfh_res);
|
compound_add_op(&compound, OP_GETFH, NULL, &getfh_res);
|
||||||
|
|
@ -1463,25 +1464,25 @@ int nfs41_link(
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* fill in the file handle's fileid and superblock */
|
/* fill in the file handle's fileid and superblock */
|
||||||
link_out->fh.fileid = info[1].fileid;
|
link_out->fh.fileid = cinfo->fileid;
|
||||||
status = nfs41_superblock_for_fh(session,
|
status = nfs41_superblock_for_fh(session,
|
||||||
&info[1].fsid, &dst_dir->fh, link_out);
|
&cinfo->fsid, &dst_dir->fh, link_out);
|
||||||
if (status)
|
if (status)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* update the attributes of the destination directory */
|
/* update the attributes of the destination directory */
|
||||||
memcpy(&info[0].attrmask, &getattr_res[0].obj_attributes.attrmask,
|
memcpy(&info.attrmask, &getattr_res[0].obj_attributes.attrmask,
|
||||||
sizeof(bitmap4));
|
sizeof(bitmap4));
|
||||||
nfs41_attr_cache_update(session_name_cache(session),
|
nfs41_attr_cache_update(session_name_cache(session),
|
||||||
info[0].fileid, &info[0]);
|
info.fileid, &info);
|
||||||
|
|
||||||
/* add the new file handle and attributes to the name cache */
|
/* add the new file handle and attributes to the name cache */
|
||||||
memcpy(&info[1].attrmask, &getattr_res[1].obj_attributes.attrmask,
|
memcpy(&cinfo->attrmask, &getattr_res[1].obj_attributes.attrmask,
|
||||||
sizeof(bitmap4));
|
sizeof(bitmap4));
|
||||||
AcquireSRWLockShared(&dst_dir->path->lock);
|
AcquireSRWLockShared(&dst_dir->path->lock);
|
||||||
nfs41_name_cache_insert(session_name_cache(session),
|
nfs41_name_cache_insert(session_name_cache(session),
|
||||||
dst_dir->path->path, target, &link_out->fh,
|
dst_dir->path->path, target, &link_out->fh,
|
||||||
&info[1], &link_res.cinfo, OPEN_DELEGATE_NONE);
|
cinfo, &link_res.cinfo, OPEN_DELEGATE_NONE);
|
||||||
ReleaseSRWLockShared(&dst_dir->path->lock);
|
ReleaseSRWLockShared(&dst_dir->path->lock);
|
||||||
|
|
||||||
nfs41_superblock_space_changed(dst_dir->fh.superblock);
|
nfs41_superblock_space_changed(dst_dir->fh.superblock);
|
||||||
|
|
|
||||||
|
|
@ -1170,7 +1170,8 @@ int nfs41_link(
|
||||||
IN nfs41_path_fh *src,
|
IN nfs41_path_fh *src,
|
||||||
IN nfs41_path_fh *dst_dir,
|
IN nfs41_path_fh *dst_dir,
|
||||||
IN const nfs41_component *target,
|
IN const nfs41_component *target,
|
||||||
OUT OPTIONAL nfs41_path_fh *link_out);
|
OUT OPTIONAL nfs41_path_fh *link_out,
|
||||||
|
OUT nfs41_file_info *cinfo);
|
||||||
|
|
||||||
/* symlink.c */
|
/* symlink.c */
|
||||||
int nfs41_symlink_target(
|
int nfs41_symlink_target(
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ static int handle_nfs41_setattr(setattr_upcall_args *args)
|
||||||
nfs_error_string(status));
|
nfs_error_string(status));
|
||||||
status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
args->ctime = info.change;
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -355,6 +356,7 @@ static int handle_nfs41_set_size(setattr_upcall_args *args)
|
||||||
AcquireSRWLockExclusive(&state->lock);
|
AcquireSRWLockExclusive(&state->lock);
|
||||||
state->pnfs_last_offset = info.size ? info.size - 1 : 0;
|
state->pnfs_last_offset = info.size ? info.size - 1 : 0;
|
||||||
ReleaseSRWLockExclusive(&state->lock);
|
ReleaseSRWLockExclusive(&state->lock);
|
||||||
|
args->ctime = info.change;
|
||||||
out:
|
out:
|
||||||
return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
@ -368,6 +370,7 @@ static int handle_nfs41_link(setattr_upcall_args *args)
|
||||||
nfs41_path_fh dst_dir, dst;
|
nfs41_path_fh dst_dir, dst;
|
||||||
nfs41_component dst_name;
|
nfs41_component dst_name;
|
||||||
uint32_t depth = 0;
|
uint32_t depth = 0;
|
||||||
|
nfs41_file_info info = { 0 };
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8, 0,
|
dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8, 0,
|
||||||
|
|
@ -449,12 +452,13 @@ static int handle_nfs41_link(setattr_upcall_args *args)
|
||||||
OPEN_DELEGATE_READ, FALSE);
|
OPEN_DELEGATE_READ, FALSE);
|
||||||
|
|
||||||
status = nfs41_link(state->session, &state->file,
|
status = nfs41_link(state->session, &state->file,
|
||||||
&dst_dir, &dst_name, NULL);
|
&dst_dir, &dst_name, NULL, &info);
|
||||||
if (status) {
|
if (status) {
|
||||||
dprintf(1, "nfs41_link() failed with error %s.\n",
|
dprintf(1, "nfs41_link() failed with error %s.\n",
|
||||||
nfs_error_string(status));
|
nfs_error_string(status));
|
||||||
status = nfs_to_windows_error(status, ERROR_INVALID_PARAMETER);
|
status = nfs_to_windows_error(status, ERROR_INVALID_PARAMETER);
|
||||||
}
|
}
|
||||||
|
args->ctime = info.change;
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -491,6 +495,11 @@ static int handle_setattr(nfs41_upcall *upcall)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int marshall_setattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
setattr_upcall_args *args = &upcall->args.setattr;
|
||||||
|
return safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
|
||||||
|
}
|
||||||
|
|
||||||
/* NFS41_EA_SET */
|
/* NFS41_EA_SET */
|
||||||
static int parse_setexattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
static int parse_setexattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
|
@ -548,6 +557,7 @@ static int handle_setexattr(nfs41_upcall *upcall)
|
||||||
nfs_error_string(status));
|
nfs_error_string(status));
|
||||||
return nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
return nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
args->ctime = info.change;
|
||||||
} else {
|
} else {
|
||||||
status = nfs41_rpc_openattr(state->session, &state->file, TRUE, &parent.fh);
|
status = nfs41_rpc_openattr(state->session, &state->file, TRUE, &parent.fh);
|
||||||
if (status) {
|
if (status) {
|
||||||
|
|
@ -612,12 +622,19 @@ out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int marshall_setexattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
setexattr_upcall_args *args = &upcall->args.setexattr;
|
||||||
|
return safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
|
||||||
|
}
|
||||||
|
|
||||||
const nfs41_upcall_op nfs41_op_setattr = {
|
const nfs41_upcall_op nfs41_op_setattr = {
|
||||||
parse_setattr,
|
parse_setattr,
|
||||||
handle_setattr
|
handle_setattr,
|
||||||
|
marshall_setattr
|
||||||
};
|
};
|
||||||
const nfs41_upcall_op nfs41_op_setexattr = {
|
const nfs41_upcall_op nfs41_op_setexattr = {
|
||||||
parse_setexattr,
|
parse_setexattr,
|
||||||
handle_setexattr
|
handle_setexattr,
|
||||||
|
marshall_setexattr
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@ typedef struct __setattr_upcall_args {
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
uint32_t buf_len;
|
uint32_t buf_len;
|
||||||
int set_class;
|
int set_class;
|
||||||
|
ULONGLONG ctime;
|
||||||
} setattr_upcall_args;
|
} setattr_upcall_args;
|
||||||
|
|
||||||
typedef struct __getexattr_upcall_args {
|
typedef struct __getexattr_upcall_args {
|
||||||
|
|
@ -126,6 +127,7 @@ typedef struct __setexattr_upcall_args {
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
uint32_t buf_len;
|
uint32_t buf_len;
|
||||||
uint32_t mode;
|
uint32_t mode;
|
||||||
|
ULONGLONG ctime;
|
||||||
} setexattr_upcall_args;
|
} setexattr_upcall_args;
|
||||||
|
|
||||||
typedef struct __readdir_upcall_args {
|
typedef struct __readdir_upcall_args {
|
||||||
|
|
|
||||||
|
|
@ -202,12 +202,14 @@ typedef struct _updowncall_entry {
|
||||||
PVOID buf;
|
PVOID buf;
|
||||||
ULONG buf_len;
|
ULONG buf_len;
|
||||||
FILE_INFORMATION_CLASS InfoClass;
|
FILE_INFORMATION_CLASS InfoClass;
|
||||||
|
ULONGLONG ChangeTime;
|
||||||
} SetFile;
|
} SetFile;
|
||||||
struct {
|
struct {
|
||||||
PUNICODE_STRING filename;
|
PUNICODE_STRING filename;
|
||||||
PVOID buf;
|
PVOID buf;
|
||||||
ULONG buf_len;
|
ULONG buf_len;
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
|
ULONGLONG ChangeTime;
|
||||||
} SetEa;
|
} SetEa;
|
||||||
struct {
|
struct {
|
||||||
PUNICODE_STRING filename;
|
PUNICODE_STRING filename;
|
||||||
|
|
@ -1534,6 +1536,15 @@ void unmarshal_nfs41_mount(
|
||||||
cur->version);
|
cur->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID unmarshal_nfs41_setattr(
|
||||||
|
nfs41_updowncall_entry *cur,
|
||||||
|
PULONGLONG dest_buf,
|
||||||
|
unsigned char **buf)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(dest_buf, *buf, sizeof(ULONGLONG));
|
||||||
|
DbgP("[setattr] returned ChangeTime %llu\n", *dest_buf);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS unmarshal_nfs41_rw(
|
NTSTATUS unmarshal_nfs41_rw(
|
||||||
nfs41_updowncall_entry *cur,
|
nfs41_updowncall_entry *cur,
|
||||||
unsigned char **buf)
|
unsigned char **buf)
|
||||||
|
|
@ -1804,6 +1815,12 @@ NTSTATUS nfs41_downcall(
|
||||||
case NFS41_ACL_QUERY:
|
case NFS41_ACL_QUERY:
|
||||||
status = unmarshal_nfs41_getacl(cur, &buf);
|
status = unmarshal_nfs41_getacl(cur, &buf);
|
||||||
break;
|
break;
|
||||||
|
case NFS41_FILE_SET:
|
||||||
|
unmarshal_nfs41_setattr(cur, &cur->u.SetFile.ChangeTime, &buf);
|
||||||
|
break;
|
||||||
|
case NFS41_EA_SET:
|
||||||
|
unmarshal_nfs41_setattr(cur, &cur->u.SetEa.ChangeTime, &buf);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DbgP("[downcall] About to signal waiting IO thread\n");
|
DbgP("[downcall] About to signal waiting IO thread\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue