Windows: Add VIOC_GETUNIXMODE and VIOC_SETUNIXMODE

Add pioctls to get and set the UNIX mode bits for an
object in AFS.

Change-Id: I220047d8be50b5db511e41004b8248859f479c0c
Reviewed-on: http://gerrit.openafs.org/3545
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
Jeffrey Altman 2010-12-18 18:36:18 -05:00 committed by Jeffrey Altman
parent 16dac6d4a6
commit 27469e59b1
5 changed files with 159 additions and 0 deletions

View File

@ -3417,3 +3417,73 @@ cm_IoctlVolStatTest(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_req_t *re
return code;
}
/*
* VIOC_GETUNIXMODE internals.
*
* Assumes that pioctl path has been parsed or skipped.
* scp is held but not locked.
*/
afs_int32
cm_IoctlGetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
afs_int32 code = 0;
char *cp;
lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code == 0)
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
lock_ReleaseWrite(&scp->rw);
if (code == 0) {
/* Copy all this junk into msg->im_data, keeping track of the lengths. */
cp = ioctlp->outDatap;
memcpy(cp, (char *)&scp->unixModeBits, sizeof(afs_uint32));
cp += sizeof(afs_uint32);
/* return new size */
ioctlp->outDatap = cp;
}
return code;
}
/*
* VIOC_SETUNIXMODE internals.
*
* Assumes that pioctl path has been parsed or skipped
* and that cm_ioctlQueryOptions_t have been parsed and skipped.
*
* scp is held but not locked.
*/
afs_int32
cm_IoctlSetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
afs_int32 code = 0;
char *cp;
lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code == 0)
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
lock_ReleaseWrite(&scp->rw);
if (code == 0) {
afs_uint32 unixModeBits;
cm_attr_t attr;
memset(&attr, 0, sizeof(attr));
cp = ioctlp->inDatap;
memcpy((char *)&unixModeBits, cp, sizeof(afs_uint32));
attr.mask = CM_ATTRMASK_UNIXMODEBITS;
attr.unixModeBits = unixModeBits;
code = cm_SetAttr(scp, &attr, userp, reqp);
}
return code;
}

View File

@ -281,6 +281,10 @@ extern afs_int32 cm_IoctlUnicodeControl(struct cm_ioctl *ioctlp, struct cm_user
extern void TranslateExtendedChars(char *str);
extern afs_int32 cm_IoctlGetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
extern afs_int32 cm_IoctlSetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
#endif /* __CM_IOCTL_INTERFACES_ONLY__ */
#endif /* __CM_IOCTL_H_ENV__ */

View File

@ -99,6 +99,8 @@ struct sbstruct {
#define VIOC_SETGROUP 0x35
#define VIOC_FS_CMD 0x36
#define VIOCNEWCELL2 0x37
#define VIOC_GETUNIXMODE 0x38
#define VIOC_SETUNIXMODE 0x39
#define VIOC_VOLSTAT_TEST 0x3F

View File

@ -94,6 +94,8 @@ smb_InitIoctl(void)
smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
smb_ioctlProcsp[VIOC_SETUNIXMODE] = smb_IoctlSetUnixMode;
smb_ioctlProcsp[VIOC_GETUNIXMODE] = smb_IoctlSetUnixMode;
}
/* called to make a fid structure into an IOCTL fid structure */
@ -2089,4 +2091,81 @@ smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
}
afs_int32
smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
cm_req_t req;
cm_ioctlQueryOptions_t *optionsp;
afs_uint32 flags = 0;
smb_InitReq(&req);
optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
if (code)
return code;
code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &req);
cm_ReleaseSCache(scp);
return code;
}
/*
* VIOC_SETUNIXMODE
*
* This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
*/
afs_int32
smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
cm_req_t req;
cm_ioctlQueryOptions_t *optionsp;
afs_uint32 flags = 0;
smb_InitReq(&req);
optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
if (optionsp) {
if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
if (code)
return code;
cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
}
code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &req);
cm_ReleaseSCache(scp);
return code;
}

View File

@ -207,4 +207,8 @@ extern afs_int32 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *use
extern afs_int32 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
extern afs_int32 smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
extern afs_int32 smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
#endif /* __SMB_IOCTL_H_ENV__ */