mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
cmsfs-fuse: write more than a single line in linefeed mode
The cmsfs_write function only writes a single record in line mode and returns the number of bytes it consumed from the input buffer. This is valid behaviour as the write system call can always return with a partial write. But there are tools that ignore the return value of the write and just assume that a single write call is sufficient to write many lines aka records on the cmsfs filesystem. Enhance the cmsfs_write function to loop until all lines from the input buffer have been consumed. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
6f7cb68dcf
commit
7677d3c0b4
@@ -17,6 +17,7 @@
|
||||
#include <fuse.h>
|
||||
#include <fuse_opt.h>
|
||||
#include <iconv.h>
|
||||
#include <limits.h>
|
||||
#include <linux/fs.h>
|
||||
#ifdef HAVE_SETXATTR
|
||||
#include <linux/xattr.h>
|
||||
@@ -4187,22 +4188,13 @@ static ssize_t find_newline(const char *buf, int len)
|
||||
return pos - buf;
|
||||
}
|
||||
|
||||
static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *fi)
|
||||
static int cmsfs_write_strings(struct file *f, const char *buf,
|
||||
size_t size, off_t offset)
|
||||
{
|
||||
int scan_len = MIN(size, (size_t)MAX_RECORD_LEN + 1);
|
||||
int rc, nl_byte = 1, null_record = 0, pad = 0;
|
||||
struct file *f = get_fobj(fi);
|
||||
ssize_t rsize;
|
||||
|
||||
(void) path;
|
||||
|
||||
if (cmsfs.readonly)
|
||||
return -EROFS;
|
||||
|
||||
if (!f->linefeed)
|
||||
return do_write(f, buf, size, offset);
|
||||
|
||||
/* remove already committed bytes */
|
||||
offset -= f->wcache_commited;
|
||||
|
||||
@@ -4278,6 +4270,36 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *fi)
|
||||
{
|
||||
struct file *f = get_fobj(fi);
|
||||
int rc, written, nbytes;
|
||||
|
||||
(void) path;
|
||||
|
||||
if (cmsfs.readonly)
|
||||
return -EROFS;
|
||||
|
||||
if (!f->linefeed)
|
||||
return do_write(f, buf, size, offset);
|
||||
|
||||
/* Limit the size to what we can report back as written */
|
||||
nbytes = MIN(size, (size_t) INT_MAX);
|
||||
|
||||
written = 0;
|
||||
while (nbytes) {
|
||||
rc = cmsfs_write_strings(f, buf, nbytes, offset);
|
||||
if (rc < 0)
|
||||
return written ? written : rc;
|
||||
written += rc;
|
||||
offset += rc;
|
||||
buf += rc;
|
||||
nbytes -= rc;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
static int cmsfs_unlink(const char *path)
|
||||
{
|
||||
struct fst_entry fst;
|
||||
|
||||
Reference in New Issue
Block a user