open and create accept pointer to attributes

allow callers of nfs41_open() and nfs41_create() to pass arbitrary attributes fo
r use with open_args.openhow.how.createattrs and create_args.createattrs
This commit is contained in:
Olga Kornievskaia 2012-03-29 16:16:55 -04:00
parent dc9377ce58
commit 6bb641e547
9 changed files with 56 additions and 49 deletions

View file

@ -441,19 +441,14 @@ static int delegation_truncate(
IN nfs41_delegation_state *deleg, IN nfs41_delegation_state *deleg,
IN nfs41_client *client, IN nfs41_client *client,
IN stateid_arg *stateid, IN stateid_arg *stateid,
IN uint32_t mode,
IN nfs41_file_info *info) IN nfs41_file_info *info)
{ {
nfs41_superblock *superblock = deleg->file.fh.superblock; nfs41_superblock *superblock = deleg->file.fh.superblock;
/* use SETATTR to truncate the file */ /* use SETATTR to truncate the file */
info->attrmask.arr[0] = FATTR4_WORD0_SIZE; info->attrmask.arr[1] |= FATTR4_WORD1_TIME_CREATE |
info->attrmask.arr[1] = FATTR4_WORD1_MODE | FATTR4_WORD1_TIME_MODIFY_SET;
FATTR4_WORD1_TIME_CREATE | FATTR4_WORD1_TIME_MODIFY_SET;
info->attrmask.count = 2;
info->size = 0;
info->mode = mode;
get_nfs_time(&info->time_create); get_nfs_time(&info->time_create);
get_nfs_time(&info->time_modify); get_nfs_time(&info->time_modify);
info->time_delta = &superblock->time_delta; info->time_delta = &superblock->time_delta;
@ -467,7 +462,7 @@ static int delegation_truncate(
int nfs41_delegate_open( int nfs41_delegate_open(
IN nfs41_open_state *state, IN nfs41_open_state *state,
IN uint32_t create, IN uint32_t create,
IN uint32_t mode, IN OPTIONAL nfs41_file_info *createattrs,
OUT nfs41_file_info *info) OUT nfs41_file_info *info)
{ {
nfs41_client *client = state->session->client; nfs41_client *client = state->session->client;
@ -518,8 +513,10 @@ int nfs41_delegate_open(
goto out_deleg; goto out_deleg;
if (create == OPEN4_CREATE) { if (create == OPEN4_CREATE) {
memcpy(info, createattrs, sizeof(nfs41_file_info));
/* write delegations allow us to simulate OPEN4_CREATE with SETATTR */ /* write delegations allow us to simulate OPEN4_CREATE with SETATTR */
status = delegation_truncate(deleg, client, &stateid, mode, info); status = delegation_truncate(deleg, client, &stateid, info);
if (status) if (status)
goto out_deleg; goto out_deleg;
} }
@ -585,7 +582,7 @@ int nfs41_delegation_to_open(
status = nfs41_open(open->session, &open->parent, &open->file, status = nfs41_open(open->session, &open->parent, &open->file,
&open->owner, &claim, open->share_access, open->share_deny, &open->owner, &claim, open->share_access, open->share_deny,
OPEN4_NOCREATE, 0, 0, try_recovery, &open_stateid, &ignore, NULL); OPEN4_NOCREATE, 0, NULL, try_recovery, &open_stateid, &ignore, NULL);
AcquireSRWLockExclusive(&open->lock); AcquireSRWLockExclusive(&open->lock);
if (status == NFS4_OK) { if (status == NFS4_OK) {

View file

@ -52,7 +52,7 @@ int nfs41_delegation_granted(
int nfs41_delegate_open( int nfs41_delegate_open(
IN nfs41_open_state *state, IN nfs41_open_state *state,
IN uint32_t create, IN uint32_t create,
IN uint32_t mode, IN OPTIONAL nfs41_file_info *createattrs,
OUT nfs41_file_info *info); OUT nfs41_file_info *info);
int nfs41_delegation_to_open( int nfs41_delegation_to_open(

View file

@ -375,7 +375,7 @@ int nfs41_open(
IN uint32_t deny, IN uint32_t deny,
IN uint32_t create, IN uint32_t create,
IN uint32_t how_mode, IN uint32_t how_mode,
IN uint32_t mode, IN OPTIONAL nfs41_file_info *createattrs,
IN bool_t try_recovery, IN bool_t try_recovery,
OUT stateid4 *stateid, OUT stateid4 *stateid,
OUT open_delegation4 *delegation, OUT open_delegation4 *delegation,
@ -462,11 +462,7 @@ int nfs41_open(
open_args.owner = owner; open_args.owner = owner;
open_args.openhow.opentype = create; open_args.openhow.opentype = create;
open_args.openhow.how.mode = how_mode; open_args.openhow.how.mode = how_mode;
open_args.openhow.how.createattrs.info.attrmask.count = 2; open_args.openhow.how.createattrs = createattrs;
open_args.openhow.how.createattrs.info.attrmask.arr[0] = FATTR4_WORD0_SIZE;
open_args.openhow.how.createattrs.info.attrmask.arr[1] = FATTR4_WORD1_MODE;
open_args.openhow.how.createattrs.info.mode = mode;
open_args.openhow.how.createattrs.info.size = 0;
if (how_mode == EXCLUSIVE4_1) { if (how_mode == EXCLUSIVE4_1) {
DWORD tid = GetCurrentThreadId(); DWORD tid = GetCurrentThreadId();
time((time_t*)open_args.openhow.how.createverf); time((time_t*)open_args.openhow.how.createverf);
@ -529,7 +525,7 @@ out:
int nfs41_create( int nfs41_create(
IN nfs41_session *session, IN nfs41_session *session,
IN uint32_t type, IN uint32_t type,
IN uint32_t mode, IN nfs41_file_info *createattrs,
IN OPTIONAL const char *symlink, IN OPTIONAL const char *symlink,
IN nfs41_path_fh *parent, IN nfs41_path_fh *parent,
OUT nfs41_path_fh *file, OUT nfs41_path_fh *file,
@ -575,10 +571,7 @@ int nfs41_create(
create_args.objtype.u.lnk.linkdata_len = (uint32_t)strlen(symlink); create_args.objtype.u.lnk.linkdata_len = (uint32_t)strlen(symlink);
} }
create_args.name = &file->name; create_args.name = &file->name;
create_args.createattrs.info.attrmask.count = 2; create_args.createattrs = createattrs;
create_args.createattrs.info.attrmask.arr[0] = 0;
create_args.createattrs.info.attrmask.arr[1] = FATTR4_WORD1_MODE;
create_args.createattrs.info.mode = mode; //511; // 0777
compound_add_op(&compound, OP_GETFH, NULL, &getfh_res); compound_add_op(&compound, OP_GETFH, NULL, &getfh_res);
getfh_res.fh = &file->fh; getfh_res.fh = &file->fh;

View file

@ -352,14 +352,10 @@ typedef struct __createtype4 {
} u; } u;
} createtype4; } createtype4;
typedef struct __createattrs4 {
nfs41_file_info info;
} createattrs4;
typedef struct __nfs41_create_args { typedef struct __nfs41_create_args {
createtype4 objtype; createtype4 objtype;
const nfs41_component *name; const nfs41_component *name;
createattrs4 createattrs; nfs41_file_info *createattrs;
} nfs41_create_args; } nfs41_create_args;
typedef struct __nfs41_create_res { typedef struct __nfs41_create_res {
@ -549,7 +545,7 @@ enum createmode4 {
typedef struct __createhow4 { typedef struct __createhow4 {
uint32_t mode; uint32_t mode;
createattrs4 createattrs; nfs41_file_info *createattrs;
unsigned char createverf[NFS4_VERIFIER_SIZE]; unsigned char createverf[NFS4_VERIFIER_SIZE];
} createhow4; } createhow4;
@ -1045,7 +1041,7 @@ int nfs41_open(
IN uint32_t deny, IN uint32_t deny,
IN uint32_t create, IN uint32_t create,
IN uint32_t how_mode, IN uint32_t how_mode,
IN uint32_t mode, IN OPTIONAL nfs41_file_info *createattrs,
IN bool_t try_recovery, IN bool_t try_recovery,
OUT stateid4 *stateid, OUT stateid4 *stateid,
OUT open_delegation4 *delegation, OUT open_delegation4 *delegation,
@ -1054,7 +1050,7 @@ int nfs41_open(
int nfs41_create( int nfs41_create(
IN nfs41_session *session, IN nfs41_session *session,
IN uint32_t type, IN uint32_t type,
IN uint32_t mode, IN nfs41_file_info *createattrs,
IN OPTIONAL const char *symlink, IN OPTIONAL const char *symlink,
IN nfs41_path_fh *parent, IN nfs41_path_fh *parent,
OUT nfs41_path_fh *file, OUT nfs41_path_fh *file,

View file

@ -1338,13 +1338,13 @@ static bool_t encode_createtype4(
static bool_t encode_createattrs4( static bool_t encode_createattrs4(
XDR *xdr, XDR *xdr,
createattrs4* createattrs) nfs41_file_info* createattrs)
{ {
fattr4 attrs; fattr4 attrs;
/* encode attribute values from createattrs->info into attrs.attr_vals */ /* encode attribute values from createattrs->info into attrs.attr_vals */
attrs.attr_vals_len = NFS4_OPAQUE_LIMIT; attrs.attr_vals_len = NFS4_OPAQUE_LIMIT;
if (!encode_file_attrs(&attrs, &createattrs->info)) if (!encode_file_attrs(&attrs, createattrs))
return FALSE; return FALSE;
return xdr_fattr4(xdr, &attrs); return xdr_fattr4(xdr, &attrs);
@ -1365,7 +1365,7 @@ static bool_t encode_op_create(
if (!encode_component(xdr, args->name)) if (!encode_component(xdr, args->name))
return FALSE; return FALSE;
return encode_createattrs4(xdr, &args->createattrs); return encode_createattrs4(xdr, args->createattrs);
} }
static bool_t xdr_change_info4( static bool_t xdr_change_info4(
@ -1896,7 +1896,7 @@ static bool_t encode_createhow4(
{ {
case UNCHECKED4: case UNCHECKED4:
case GUARDED4: case GUARDED4:
result = encode_createattrs4(xdr, &ch->createattrs); result = encode_createattrs4(xdr, ch->createattrs);
break; break;
case EXCLUSIVE4: case EXCLUSIVE4:
result = xdr_opaque(xdr, (char *)ch->createverf, NFS4_VERIFIER_SIZE); result = xdr_opaque(xdr, (char *)ch->createverf, NFS4_VERIFIER_SIZE);
@ -1904,7 +1904,7 @@ static bool_t encode_createhow4(
case EXCLUSIVE4_1: case EXCLUSIVE4_1:
if (!xdr_opaque(xdr, (char *)ch->createverf, NFS4_VERIFIER_SIZE)) if (!xdr_opaque(xdr, (char *)ch->createverf, NFS4_VERIFIER_SIZE))
return FALSE; return FALSE;
if (!encode_createattrs4(xdr, &ch->createattrs)) if (!encode_createattrs4(xdr, ch->createattrs))
return FALSE; return FALSE;
break; break;
} }

View file

@ -184,7 +184,7 @@ static int do_open(
IN OUT nfs41_open_state *state, IN OUT nfs41_open_state *state,
IN uint32_t create, IN uint32_t create,
IN uint32_t createhow, IN uint32_t createhow,
IN uint32_t mode, IN nfs41_file_info *createattrs,
IN bool_t try_recovery, IN bool_t try_recovery,
OUT nfs41_file_info *info) OUT nfs41_file_info *info)
{ {
@ -199,7 +199,8 @@ static int do_open(
status = nfs41_open(state->session, &state->parent, &state->file, status = nfs41_open(state->session, &state->parent, &state->file,
&state->owner, &claim, state->share_access, state->share_deny, &state->owner, &claim, state->share_access, state->share_deny,
create, createhow, mode, TRUE, &open_stateid, &delegation, info); create, createhow, createattrs, TRUE, &open_stateid,
&delegation, info);
if (status) if (status)
goto out; goto out;
@ -226,18 +227,19 @@ static int open_or_delegate(
IN OUT nfs41_open_state *state, IN OUT nfs41_open_state *state,
IN uint32_t create, IN uint32_t create,
IN uint32_t createhow, IN uint32_t createhow,
IN uint32_t mode, IN nfs41_file_info *createattrs,
IN bool_t try_recovery, IN bool_t try_recovery,
OUT nfs41_file_info *info) OUT nfs41_file_info *info)
{ {
int status; int status;
/* check for existing delegation */ /* check for existing delegation */
status = nfs41_delegate_open(state, create, mode, info); status = nfs41_delegate_open(state, create, createattrs, info);
/* get an open stateid if we have no delegation stateid */ /* get an open stateid if we have no delegation stateid */
if (status) if (status)
status = do_open(state, create, createhow, mode, try_recovery, info); status = do_open(state, create, createhow,
createattrs, try_recovery, info);
state->pnfs_last_offset = info->size ? info->size - 1 : 0; state->pnfs_last_offset = info->size ? info->size - 1 : 0;
@ -582,8 +584,14 @@ static int handle_open(nfs41_upcall *upcall)
args->mode = info.mode; args->mode = info.mode;
args->changeattr = info.change; args->changeattr = info.change;
} else { } else {
nfs41_file_info createattrs;
uint32_t create = 0, createhowmode = 0, lookup_status = status; uint32_t create = 0, createhowmode = 0, lookup_status = status;
createattrs.attrmask.count = 2;
createattrs.attrmask.arr[0] = 0;
createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
createattrs.mode = args->mode;
map_access_2_allowdeny(args->access_mask, args->access_mode, map_access_2_allowdeny(args->access_mask, args->access_mode,
args->disposition, &state->share_access, &state->share_deny); args->disposition, &state->share_access, &state->share_deny);
status = map_disposition_2_nfsopen(args->disposition, status, status = map_disposition_2_nfsopen(args->disposition, status,
@ -614,11 +622,13 @@ supersede_retry:
} }
if (create == OPEN4_CREATE && (args->create_opts & FILE_DIRECTORY_FILE)) { if (create == OPEN4_CREATE && (args->create_opts & FILE_DIRECTORY_FILE)) {
status = nfs41_create(state->session, NF4DIR, args->mode, NULL, status = nfs41_create(state->session, NF4DIR, &createattrs, NULL,
&state->parent, &state->file, &info); &state->parent, &state->file, &info);
args->created = status == NFS4_OK ? TRUE : FALSE; args->created = status == NFS4_OK ? TRUE : FALSE;
} else { } else {
status = open_or_delegate(state, create, createhowmode, args->mode, createattrs.attrmask.arr[0] = FATTR4_WORD0_SIZE;
createattrs.size = 0;
status = open_or_delegate(state, create, createhowmode, &createattrs,
TRUE, &info); TRUE, &info);
if (status == NFS4_OK && state->delegation.state) if (status == NFS4_OK && state->delegation.state)
args->deleg_type = state->delegation.state->state.type; args->deleg_type = state->delegation.state->state.type;

View file

@ -151,7 +151,7 @@ static int recover_open_grace(
claim.u.prev.delegate_type = delegation->type; claim.u.prev.delegate_type = delegation->type;
return nfs41_open(session, parent, file, owner, &claim, access, deny, return nfs41_open(session, parent, file, owner, &claim, access, deny,
OPEN4_NOCREATE, 0, 0, FALSE, stateid, delegation, NULL); OPEN4_NOCREATE, 0, NULL, FALSE, stateid, delegation, NULL);
} }
static int recover_open_no_grace( static int recover_open_no_grace(
@ -173,7 +173,7 @@ static int recover_open_no_grace(
claim.u.deleg_prev.filename = &file->name; claim.u.deleg_prev.filename = &file->name;
status = nfs41_open(session, parent, file, owner, status = nfs41_open(session, parent, file, owner,
&claim, access, deny, OPEN4_NOCREATE, 0, 0, FALSE, &claim, access, deny, OPEN4_NOCREATE, 0, NULL, FALSE,
stateid, delegation, NULL); stateid, delegation, NULL);
if (status == NFS4_OK || status == NFS4ERR_BADSESSION) if (status == NFS4_OK || status == NFS4ERR_BADSESSION)
goto out; goto out;
@ -193,7 +193,7 @@ static int recover_open_no_grace(
access |= OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG; access |= OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG;
status = nfs41_open(session, parent, file, owner, status = nfs41_open(session, parent, file, owner,
&claim, access, deny, OPEN4_NOCREATE, 0, 0, FALSE, &claim, access, deny, OPEN4_NOCREATE, 0, NULL, FALSE,
stateid, delegation, NULL); stateid, delegation, NULL);
out: out:
return status; return status;

View file

@ -521,7 +521,7 @@ static int handle_setexattr(nfs41_upcall *upcall)
setexattr_upcall_args *args = &upcall->args.setexattr; setexattr_upcall_args *args = &upcall->args.setexattr;
nfs41_open_state *state = upcall->state_ref; nfs41_open_state *state = upcall->state_ref;
stateid_arg stateid; stateid_arg stateid;
nfs41_file_info info = { 0 }; nfs41_file_info createattrs, info = { 0 };
PFILE_FULL_EA_INFORMATION eainfo = PFILE_FULL_EA_INFORMATION eainfo =
(PFILE_FULL_EA_INFORMATION)args->buf, prev = NULL; (PFILE_FULL_EA_INFORMATION)args->buf, prev = NULL;
nfs41_path_fh parent, file; nfs41_path_fh parent, file;
@ -533,6 +533,12 @@ static int handle_setexattr(nfs41_upcall *upcall)
UCHAR *buf; UCHAR *buf;
open_delegation4 delegation = { 0 }; open_delegation4 delegation = { 0 };
createattrs.attrmask.count = 2;
createattrs.attrmask.arr[0] = FATTR4_WORD0_SIZE;
createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
createattrs.size = 0;
createattrs.mode = 0664;
/* break read delegations before SETATTR */ /* break read delegations before SETATTR */
nfs41_delegation_return(state->session, &state->file, nfs41_delegation_return(state->session, &state->file,
OPEN_DELEGATE_READ, FALSE); OPEN_DELEGATE_READ, FALSE);
@ -577,7 +583,7 @@ static int handle_setexattr(nfs41_upcall *upcall)
claim.u.null.filename = &dst_name; claim.u.null.filename = &dst_name;
status = nfs41_open(state->session, &parent, &file, &state->owner, &claim, status = nfs41_open(state->session, &parent, &file, &state->owner, &claim,
OPEN4_SHARE_ACCESS_WRITE, OPEN4_SHARE_DENY_BOTH, OPEN4_CREATE, OPEN4_SHARE_ACCESS_WRITE, OPEN4_SHARE_DENY_BOTH, OPEN4_CREATE,
UNCHECKED4, 0664, TRUE, &open_stateid, &delegation, NULL); UNCHECKED4, &createattrs, TRUE, &open_stateid, &delegation, NULL);
if (status) { if (status) {
dprintf(1, "handle_setexattr: nfs41_rpc_open() failed with error %s.\n", dprintf(1, "handle_setexattr: nfs41_rpc_open() failed with error %s.\n",
nfs_error_string(status)); nfs_error_string(status));

View file

@ -227,7 +227,8 @@ static int handle_symlink(nfs41_upcall *upcall)
int status = NO_ERROR; int status = NO_ERROR;
if (args->set) { if (args->set) {
nfs41_file_info info; nfs41_file_info info, createattrs;
/* don't send windows slashes to the server */ /* don't send windows slashes to the server */
char *p; char *p;
for (p = args->target_set; *p; p++) if (*p == '\\') *p = '/'; for (p = args->target_set; *p; p++) if (*p == '\\') *p = '/';
@ -249,7 +250,11 @@ static int handle_symlink(nfs41_upcall *upcall)
} }
/* create the symlink */ /* create the symlink */
status = nfs41_create(state->session, NF4LNK, 0777, createattrs.attrmask.count = 1;
createattrs.attrmask.arr[0] = 0;
createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
createattrs.mode = 0777;
status = nfs41_create(state->session, NF4LNK, &createattrs,
args->target_set, &state->parent, &state->file, &info); args->target_set, &state->parent, &state->file, &info);
if (status) { if (status) {
eprintf("nfs41_create() for symlink=%s failed with %s\n", eprintf("nfs41_create() for symlink=%s failed with %s\n",