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_ftrunc perform the FTRUNC file system call
8 * April 2009 (D.C. van Moolenbroek)
13 static int write_file(struct inode
*ino
, u64_t
*posp
, size_t *countp
,
14 cp_grant_id_t
*grantp
);
16 /*===========================================================================*
18 *===========================================================================*/
19 static int write_file(ino
, posp
, countp
, grantp
)
23 cp_grant_id_t
*grantp
;
25 /* Write data or zeroes to a file, depending on whether a valid pointer to
26 * a data grant was provided.
36 if ((r
= get_handle(ino
)) != OK
)
44 /* Use the buffer from below to eliminate extra copying. */
45 size
= sffs_table
->t_writebuf(&ptr
);
49 chunk
= MIN(count
, size
);
52 r
= sys_safecopyfrom(m_in
.m_source
, *grantp
,
53 off
, (vir_bytes
) ptr
, chunk
);
58 /* Do this every time. We don't know what happens below. */
59 memset(ptr
, 0, chunk
);
62 if ((r
= sffs_table
->t_write(ino
->i_file
, ptr
, chunk
, pos
)) <= 0)
79 /*===========================================================================*
81 *===========================================================================*/
84 /* Write data to a file.
92 if (state
.s_read_only
)
95 if ((ino
= find_inode(m_in
.REQ_INODE_NR
)) == NULL
)
98 if (IS_DIR(ino
)) return EISDIR
;
100 pos
= make64(m_in
.REQ_SEEK_POS_LO
, m_in
.REQ_SEEK_POS_HI
);
101 count
= m_in
.REQ_NBYTES
;
102 grant
= m_in
.REQ_GRANT
;
104 if (count
== 0) return EINVAL
;
106 if ((r
= write_file(ino
, &pos
, &count
, &grant
)) != OK
)
109 m_out
.RES_SEEK_POS_HI
= ex64hi(pos
);
110 m_out
.RES_SEEK_POS_LO
= ex64lo(pos
);
111 m_out
.RES_NBYTES
= count
;
116 /*===========================================================================*
118 *===========================================================================*/
121 /* Change file size or create file holes.
125 struct sffs_attr attr
;
126 u64_t start
, end
, delta
;
130 if (state
.s_read_only
)
133 if ((ino
= find_inode(m_in
.REQ_INODE_NR
)) == NULL
)
136 if (IS_DIR(ino
)) return EISDIR
;
138 start
= make64(m_in
.REQ_TRC_START_LO
, m_in
.REQ_TRC_START_HI
);
139 end
= make64(m_in
.REQ_TRC_END_LO
, m_in
.REQ_TRC_END_HI
);
141 if (cmp64u(end
, 0) == 0) {
142 /* Truncate or expand the file. */
143 if ((r
= verify_inode(ino
, path
, NULL
)) != OK
)
146 attr
.a_mask
= SFFS_ATTR_SIZE
;
149 r
= sffs_table
->t_setattr(path
, &attr
);
151 /* Write zeroes to the file. We can't create holes. */
152 if (cmp64(end
, start
) <= 0) return EINVAL
;
154 delta
= sub64(end
, start
);
156 if (ex64hi(delta
) != 0) return EINVAL
;
158 count
= ex64lo(delta
);
160 r
= write_file(ino
, &start
, &count
, NULL
);