1 /* This file contains file writing system call handlers.
3 * The entry points into this file are:
4 * do_write perform the WRITE file system call
5 * do_trunc perform the TRUNC file system call
8 * April 2009 (D.C. van Moolenbroek)
13 /*===========================================================================*
15 *===========================================================================*/
16 static ssize_t
write_file(struct inode
*ino
, off_t pos
, size_t count
,
17 struct fsdriver_data
*data
)
19 /* Write data or zeroes to a file, depending on whether a valid pointer to
20 * a data grant was provided.
22 size_t size
, off
, chunk
;
31 if ((r
= get_handle(ino
)) != OK
)
36 /* Use the buffer from below to eliminate extra copying. */
37 size
= sffs_table
->t_writebuf(&ptr
);
41 chunk
= MIN(count
, size
);
44 if ((r
= fsdriver_copyin(data
, off
, ptr
, chunk
)) != OK
)
47 /* Do this every time. We don't know what happens below. */
48 memset(ptr
, 0, chunk
);
51 if ((r
= sffs_table
->t_write(ino
->i_file
, ptr
, chunk
, pos
)) <= 0)
65 /*===========================================================================*
67 *===========================================================================*/
68 ssize_t
do_write(ino_t ino_nr
, struct fsdriver_data
*data
, size_t count
,
71 /* Write data to a file.
78 if ((ino
= find_inode(ino_nr
)) == NULL
)
81 if (IS_DIR(ino
)) return EISDIR
;
83 if (count
== 0) return 0;
85 return write_file(ino
, pos
, count
, data
);
88 /*===========================================================================*
90 *===========================================================================*/
91 int do_trunc(ino_t ino_nr
, off_t start
, off_t end
)
93 /* Change file size or create file holes.
97 struct sffs_attr attr
;
104 if ((ino
= find_inode(ino_nr
)) == NULL
)
107 if (IS_DIR(ino
)) return EISDIR
;
110 /* Truncate or expand the file. */
111 if ((r
= verify_inode(ino
, path
, NULL
)) != OK
)
114 attr
.a_mask
= SFFS_ATTR_SIZE
;
117 r
= sffs_table
->t_setattr(path
, &attr
);
119 /* Write zeroes to the file. We can't create holes. */
120 if (end
<= start
) return EINVAL
;
122 delta
= (uint64_t)end
- (uint64_t)start
;
124 if (delta
> SSIZE_MAX
) return EINVAL
;
126 if ((r
= write_file(ino
, start
, (size_t)delta
, NULL
)) >= 0)