propagating file change attr on setattr

This commit is contained in:
Olga Kornievskaia 2012-02-07 11:46:02 -05:00 committed by unknown
parent aa7a680a40
commit cdf31d3ee0
5 changed files with 57 additions and 19 deletions

View file

@ -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);

View file

@ -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(

View file

@ -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
}; };

View file

@ -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 {

View file

@ -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");