/** * hmcdrv_ftp_cmd_getid() - determine FTP command ID from a command string * @cmd: FTP command string (NOT zero-terminated) * @len: length of FTP command string in @cmd
*/ staticenum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(constchar *cmd, int len)
{ /* HMC FTP command descriptor */ struct hmcdrv_ftp_cmd_desc { constchar *str; /* command string */ enum hmcdrv_ftp_cmdid cmd; /* associated command as enum */
};
/* Description of all HMC drive FTP commands * * Notes: * 1. Array size should be a prime number. * 2. Do not change the order of commands in table (because the * index is determined by CRC % ARRAY_SIZE). * 3. Original command 'nlist' was renamed, else the CRC would * collide with 'append' (see point 2).
*/ staticconststruct hmcdrv_ftp_cmd_desc ftpcmds[7] = {
switch (argc) { case 0: /* 1st argument (FTP command) */ while ((*cmd != '\0') && !isspace(*cmd))
++cmd;
ftp->id = hmcdrv_ftp_cmd_getid(start, cmd - start); break; case 1: /* 2nd / last argument (rest of line) */ while ((*cmd != '\0') && !iscntrl(*cmd))
++cmd;
ftp->fname = start;
fallthrough; default:
*cmd = '\0'; break;
} /* switch */
++argc;
} /* while */
if (!ftp->fname || (ftp->id == HMCDRV_FTP_NOOP)) return -EINVAL;
return 0;
}
/** * hmcdrv_ftp_do() - perform a HMC drive FTP, with data from kernel-space * @ftp: pointer to FTP command specification * * Return: number of bytes read/written or a negative error code
*/
ssize_t hmcdrv_ftp_do(conststruct hmcdrv_ftp_cmdspec *ftp)
{
ssize_t len;
mutex_lock(&hmcdrv_ftp_mutex);
if (hmcdrv_ftp_funcs && hmcdrv_ftp_refcnt) {
pr_debug("starting transfer, cmd %d for '%s' at %lld with %zd bytes\n",
ftp->id, ftp->fname, (longlong) ftp->ofs, ftp->len);
len = hmcdrv_cache_cmd(ftp, hmcdrv_ftp_funcs->transfer);
} else {
len = -ENXIO;
}
/** * hmcdrv_ftp_probe() - probe for the HMC drive FTP service * * Return: 0 if service is available, else an (negative) error code
*/ int hmcdrv_ftp_probe(void)
{ int rc;
switch (rc) { case -ENOENT: /* no such file/media or currently busy, */ case -EBUSY: /* but service seems to be available */
rc = 0; break; default: /* leave 'rc' as it is for [0, -EPERM, -E...] */ if (rc > 0)
rc = 0; /* clear length (success) */ break;
} /* switch */
out:
free_page((unsignedlong) ftp.buf); return rc;
}
EXPORT_SYMBOL(hmcdrv_ftp_probe);
/** * hmcdrv_ftp_cmd() - Perform a HMC drive FTP, with data from user-space * * @cmd: FTP command string "<cmd> <filename>" * @offset: file position to read/write * @buf: user-space buffer for read/written directory/file * @len: size of @buf (read/dir) or number of bytes to write * * This function must not be called before hmcdrv_ftp_startup() was called. * * Return: number of bytes read/written or a negative error code
*/
ssize_t hmcdrv_ftp_cmd(char __kernel *cmd, loff_t offset, char __user *buf, size_t len)
{ int order;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.