NFSv4: Add support for mknod()
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>libnfs-4.0.0-vitalif
parent
de9da5689d
commit
bd95371005
|
@ -484,6 +484,8 @@ int nfs4_link_async(struct nfs_context *nfs, const char *oldpath,
|
|||
const char *newpath, nfs_cb cb, void *private_data);
|
||||
int nfs4_mkdir2_async(struct nfs_context *nfs, const char *path, int mode,
|
||||
nfs_cb cb, void *private_data);
|
||||
int nfs4_mknod_async(struct nfs_context *nfs, const char *path, int mode,
|
||||
int dev, nfs_cb cb, void *private_data);
|
||||
int nfs4_mount_async(struct nfs_context *nfs, const char *server,
|
||||
const char *export, nfs_cb cb, void *private_data);
|
||||
int nfs4_open_async(struct nfs_context *nfs, const char *path, int flags,
|
||||
|
|
|
@ -1247,9 +1247,11 @@ nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev,
|
|||
switch (nfs->version) {
|
||||
case NFS_V3:
|
||||
return nfs3_mknod_async(nfs, path, mode, dev, cb, private_data);
|
||||
case NFS_V4:
|
||||
return nfs4_mknod_async(nfs, path, mode, dev, cb, private_data);
|
||||
default:
|
||||
nfs_set_error(nfs, "%s does not support NFSv4",
|
||||
__FUNCTION__);
|
||||
nfs_set_error(nfs, "%s does not support NFSv%d",
|
||||
__FUNCTION__, nfs->version);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3001,6 +3001,7 @@ nfs3_mknod_continue_internal(struct nfs_context *nfs,
|
|||
args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
|
||||
args.what.mknoddata3_u.blk_device.spec.specdata1 = cb_data->major;
|
||||
args.what.mknoddata3_u.blk_device.spec.specdata2 = cb_data->minor;
|
||||
break;
|
||||
case S_IFSOCK:
|
||||
args.what.type = NF3SOCK;
|
||||
args.what.mknoddata3_u.sock_attributes.mode.set_it = 1;
|
||||
|
|
125
lib/nfs_v4.c
125
lib/nfs_v4.c
|
@ -2752,3 +2752,128 @@ nfs4_rename_async(struct nfs_context *nfs, const char *oldpath,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_mknod_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
{
|
||||
struct nfs4_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
COMPOUND4res *res = command_data;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (check_nfs4_error(nfs, status, data, res, "MKNOD")) {
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
data->cb(0, nfs, NULL, data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
}
|
||||
|
||||
static int
|
||||
nfs4_populate_mknod(struct nfs4_cb_data *data, nfs_argop4 *op)
|
||||
{
|
||||
CREATE4args *cargs;
|
||||
uint32_t mode, *ptr;
|
||||
int dev;
|
||||
|
||||
/* Strip off the file type before we marshall it */
|
||||
ptr = (void *)data->filler.blob1.val;
|
||||
mode = *ptr;
|
||||
*ptr = htonl(mode & ~S_IFMT);
|
||||
|
||||
dev = data->filler.blob2.len;
|
||||
|
||||
op[0].argop = OP_CREATE;
|
||||
cargs = &op[0].nfs_argop4_u.opcreate;
|
||||
memset(cargs, 0, sizeof(*cargs));
|
||||
cargs->objname.utf8string_val = data->filler.data;
|
||||
cargs->objname.utf8string_len = strlen(cargs->objname.utf8string_val);
|
||||
cargs->createattrs.attrmask.bitmap4_len = data->filler.blob0.len;
|
||||
cargs->createattrs.attrmask.bitmap4_val = data->filler.blob0.val;
|
||||
cargs->createattrs.attr_vals.attrlist4_len = data->filler.blob1.len;
|
||||
cargs->createattrs.attr_vals.attrlist4_val = data->filler.blob1.val;
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
cargs->objtype.type = NF4CHR;
|
||||
cargs->objtype.createtype4_u.devdata.specdata1 = major(dev);
|
||||
cargs->objtype.createtype4_u.devdata.specdata2 = minor(dev);
|
||||
break;
|
||||
case S_IFBLK:
|
||||
cargs->objtype.type = NF4BLK;
|
||||
cargs->objtype.createtype4_u.devdata.specdata1 = major(dev);
|
||||
cargs->objtype.createtype4_u.devdata.specdata2 = minor(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Takes object name as filler.data
|
||||
* blob0 as attribute mask
|
||||
* blob1 as attribute value
|
||||
* blob2.len as dev
|
||||
*/
|
||||
int
|
||||
nfs4_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev,
|
||||
nfs_cb cb, void *private_data)
|
||||
{
|
||||
struct nfs4_cb_data *data;
|
||||
uint32_t *u32ptr;
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
break;
|
||||
default:
|
||||
nfs_set_error(nfs, "Invalid file type for "
|
||||
"MKNOD call");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = init_cb_data_split_path(nfs, path);
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->cb = cb;
|
||||
data->private_data = private_data;
|
||||
data->filler.func = nfs4_populate_mknod;
|
||||
data->filler.max_op = 1;
|
||||
|
||||
/* attribute mask */
|
||||
u32ptr = malloc(2 * sizeof(uint32_t));
|
||||
if (u32ptr == NULL) {
|
||||
nfs_set_error(nfs, "Out of memory allocating bitmap");
|
||||
return 0;
|
||||
}
|
||||
u32ptr[0] = 0;
|
||||
u32ptr[1] = 1 << (FATTR4_MODE - 32);
|
||||
data->filler.blob0.len = 2;
|
||||
data->filler.blob0.val = u32ptr;
|
||||
data->filler.blob0.free = free;
|
||||
|
||||
/* attribute values */
|
||||
u32ptr = malloc(1 * sizeof(uint32_t));
|
||||
if (u32ptr == NULL) {
|
||||
nfs_set_error(nfs, "Out of memory allocating attributes");
|
||||
free_nfs4_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
u32ptr[0] = mode;
|
||||
data->filler.blob1.len = 4;
|
||||
data->filler.blob1.val = u32ptr;
|
||||
data->filler.blob1.free = free;
|
||||
|
||||
data->filler.blob2.len = dev;
|
||||
|
||||
if (nfs4_lookup_path_async(nfs, data, nfs4_mknod_cb) < 0) {
|
||||
free_nfs4_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,18 @@ echo -n "Create a chrdev outside the share (abs) (6)... "
|
|||
./prog_mknod "${TESTURL}/?uid=0&version=${VERS}" "." ../subdir2/mknod6 020775 0x1234 2>/dev/null && failure
|
||||
success
|
||||
|
||||
echo -n "Create a blkdev in the root (abs) (7)... "
|
||||
./prog_mknod "${TESTURL}/?uid=0&version=${VERS}" "." /mknod7 060755 0x1234 || failure
|
||||
success
|
||||
|
||||
echo -n "Stat the node ... "
|
||||
./prog_stat "${TESTURL}/?version=${VERS}" "." mknod7 > "${TESTDIR}/output" || failure
|
||||
success
|
||||
|
||||
echo -n "Testing nfs_mode and verify it is a BLKDEV ... "
|
||||
grep "nfs_mode:60755" "${TESTDIR}/output" >/dev/null || failure
|
||||
success
|
||||
|
||||
stop_share
|
||||
|
||||
exit 0
|
||||
|
|
Loading…
Reference in New Issue