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(struct inode
*ino
, u64_t
*posp
, size_t *countp
,
20 cp_grant_id_t
*grantp
)
22 /* Write data or zeroes to a file, depending on whether a valid pointer to
23 * a data grant was provided.
33 if ((r
= get_handle(ino
)) != OK
)
41 /* Use the buffer from below to eliminate extra copying. */
42 size
= sffs_table
->t_writebuf(&ptr
);
46 chunk
= MIN(count
, size
);
49 r
= sys_safecopyfrom(m_in
.m_source
, *grantp
,
50 off
, (vir_bytes
) ptr
, chunk
);
55 /* Do this every time. We don't know what happens below. */
56 memset(ptr
, 0, chunk
);
59 if ((r
= sffs_table
->t_write(ino
->i_file
, ptr
, chunk
, pos
)) <= 0)
76 /*===========================================================================*
78 *===========================================================================*/
81 /* Write data to a file.
89 if (state
.s_read_only
)
92 if ((ino
= find_inode(m_in
.REQ_INODE_NR
)) == NULL
)
95 if (IS_DIR(ino
)) return EISDIR
;
97 pos
= m_in
.REQ_SEEK_POS
;
98 count
= m_in
.REQ_NBYTES
;
99 grant
= m_in
.REQ_GRANT
;
101 if (count
== 0) return EINVAL
;
103 if ((r
= write_file(ino
, &pos
, &count
, &grant
)) != OK
)
106 m_out
.RES_SEEK_POS
= pos
;
107 m_out
.RES_NBYTES
= count
;
112 /*===========================================================================*
114 *===========================================================================*/
117 /* Change file size or create file holes.
121 struct sffs_attr attr
;
122 u64_t start
, end
, delta
;
126 if (state
.s_read_only
)
129 if ((ino
= find_inode(m_in
.REQ_INODE_NR
)) == NULL
)
132 if (IS_DIR(ino
)) return EISDIR
;
134 start
= m_in
.REQ_TRC_START
;
135 end
= m_in
.REQ_TRC_END
;
138 /* Truncate or expand the file. */
139 if ((r
= verify_inode(ino
, path
, NULL
)) != OK
)
142 attr
.a_mask
= SFFS_ATTR_SIZE
;
145 r
= sffs_table
->t_setattr(path
, &attr
);
147 /* Write zeroes to the file. We can't create holes. */
148 if (end
<= start
) return EINVAL
;
152 if (ex64hi(delta
) != 0) return EINVAL
;
154 count
= ex64lo(delta
);
156 r
= write_file(ino
, &start
, &count
, NULL
);