diff options
author | Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com> | 2024-09-24 15:53:18 +0200 |
---|---|---|
committer | Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com> | 2024-09-27 11:08:49 +0200 |
commit | d95edceb362a6b647ec454c2a83add11c4ed4e64 (patch) | |
tree | 0252bfed2ab558eeb9d4a33458a123c9c9cb2afd /sysfs.c | |
parent | Incremental: Rename IncrementalRemove (diff) | |
download | mdadm-d95edceb362a6b647ec454c2a83add11c4ed4e64.tar.xz mdadm-d95edceb362a6b647ec454c2a83add11c4ed4e64.zip |
sysfs: add function for writing to sysfs fd
Proposed function sysfs_wrte_descriptor() unifies error handling for
write() done to sysfs files. Main purpose is to use it with MD sysfs
file but it can be used elsewhere.
No functional changes.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Diffstat (limited to 'sysfs.c')
-rw-r--r-- | sysfs.c | 65 |
1 files changed, 53 insertions, 12 deletions
@@ -73,6 +73,47 @@ void sysfs_free(struct mdinfo *sra) sra = sra2; } } +/** + * write_attr() - write value to fd, don't check errno. + * @attr: value to write. + * @fd: file descriptor write to. + * + * Size to write is calculated by strlen(). + */ +mdadm_status_t write_attr(const char *value, const int fd) +{ + return sysfs_write_descriptor(fd, value, strlen(value), NULL); +} + +/** + * sysfs_write_descriptor()- wrapper for write(), projected to be used with sysfs. + * @fd: file descriptor. + * @value: value to set. + * @len: length of the value. + * @errno_p: On write() failure, buffer to copy errno value, might be NULL. + * + * Errors are differentiated, because (at least theoretically) kernel may not process whole string + * and it may or may not be a problem (it depends on implementation in kernel). Decision belongs to + * caller then. + * Generally, it should be safe to check if @errno_p changed to determine if error occurred. + */ +mdadm_status_t sysfs_write_descriptor(const int fd, const char *value, const ssize_t len, + int *errno_p) +{ + ssize_t ret; + + ret = write(fd, value, len); + if (ret == -1) { + if (errno_p) + *errno_p = errno; + return MDADM_STATUS_ERROR; + } + + if (ret != len) + return MDADM_STATUS_UNDEF; + + return MDADM_STATUS_SUCCESS; +} /** * sysfs_get_container_devnm() - extract container device name. @@ -486,7 +527,6 @@ int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev, char *name, char *val) { char fname[MAX_SYSFS_PATH_LEN]; - unsigned int n; int fd; snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md/%s/%s", @@ -494,13 +534,14 @@ int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev, fd = open(fname, O_WRONLY); if (fd < 0) return -1; - n = write(fd, val, strlen(val)); - close(fd); - if (n != strlen(val)) { - dprintf("failed to write '%s' to '%s' (%s)\n", - val, fname, strerror(errno)); + + if (write_attr(val, fd)) { + pr_err("failed to write '%s' to '%s' (%s)\n", val, fname, strerror(errno)); + close(fd); return -1; } + + close(fd); return 0; } @@ -523,7 +564,6 @@ int sysfs_set_num_signed(struct mdinfo *sra, struct mdinfo *dev, int sysfs_uevent(struct mdinfo *sra, char *event) { char fname[MAX_SYSFS_PATH_LEN]; - int n; int fd; snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/uevent", @@ -531,13 +571,14 @@ int sysfs_uevent(struct mdinfo *sra, char *event) fd = open(fname, O_WRONLY); if (fd < 0) return -1; - n = write(fd, event, strlen(event)); - close(fd); - if (n != (int)strlen(event)) { - dprintf("failed to write '%s' to '%s' (%s)\n", - event, fname, strerror(errno)); + + if (write_attr(event, fd)) { + pr_err("failed to write '%s' to '%s' (%s)\n", event, fname, strerror(errno)); + close(fd); return -1; } + + close(fd); return 0; } |