return 0;
}
-static int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
- loff_t *offs, handle_t *handle)
+static int
+osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
+ int write_NUL, loff_t *offs, handle_t *handle)
{
struct buffer_head *bh = NULL;
loff_t offset = *offs;
int boffs;
int dirty_inode = 0;
+ if (write_NUL) {
+ /*
+ * long symlink write does not count the NUL terminator in
+ * bufsize, we write it, and the inode's file size does not
+ * count the NUL terminator as well.
+ */
+ ((char*)buf)[bufsize] = '\0';
+ ++bufsize;
+ }
while (bufsize > 0) {
if (bh != NULL)
brelse(bh);
if (bh)
brelse(bh);
+ if (write_NUL)
+ --new_size;
/* correct in-core and on-disk sizes */
if (new_size > i_size_read(inode)) {
spin_lock(&inode->i_lock);
struct inode *inode = obj->oo_inode;
struct osd_thandle *oh;
ssize_t result = 0;
+ int is_link;
#ifdef HAVE_QUOTA_SUPPORT
cfs_cap_t save = cfs_curproc_cap_pack();
#endif
#endif
/* Write small symlink to inode body as we need to maintain correct
* on-disk symlinks for ldiskfs.
+ * Note: the buf->lb_buf contains a NUL terminator while buf->lb_len
+ * does not count it in.
*/
- if(S_ISLNK(obj->oo_dt.do_lu.lo_header->loh_attr) &&
- (buf->lb_len < sizeof (LDISKFS_I(inode)->i_data)))
+ is_link = S_ISLNK(dt->do_lu.lo_header->loh_attr);
+ if(is_link && (buf->lb_len < sizeof (LDISKFS_I(inode)->i_data)))
result = osd_ldiskfs_writelink(inode, buf->lb_buf, buf->lb_len);
else
result = osd_ldiskfs_write_record(inode, buf->lb_buf,
- buf->lb_len, pos,
+ buf->lb_len, is_link, pos,
oh->ot_handle);
#ifdef HAVE_QUOTA_SUPPORT
cfs_curproc_cap_unpack(save);