Skip to content

Commit b8102b6

Browse files
author
Darrick J. Wong
committed
xfs: move symlink target write function to libxfs
Move xfs_symlink_write_target to xfs_symlink_remote.c so that kernel and mkfs can share the same function. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
1 parent 376b4f0 commit b8102b6

File tree

3 files changed

+84
-64
lines changed

3 files changed

+84
-64
lines changed

fs/xfs/libxfs/xfs_symlink_remote.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,79 @@ xfs_symlink_remote_read(
304304
out:
305305
return error;
306306
}
307+
308+
/* Write the symlink target into the inode. */
309+
int
310+
xfs_symlink_write_target(
311+
struct xfs_trans *tp,
312+
struct xfs_inode *ip,
313+
const char *target_path,
314+
int pathlen,
315+
xfs_fsblock_t fs_blocks,
316+
uint resblks)
317+
{
318+
struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
319+
struct xfs_mount *mp = tp->t_mountp;
320+
const char *cur_chunk;
321+
struct xfs_buf *bp;
322+
xfs_daddr_t d;
323+
int byte_cnt;
324+
int nmaps;
325+
int offset = 0;
326+
int n;
327+
int error;
328+
329+
/*
330+
* If the symlink will fit into the inode, write it inline.
331+
*/
332+
if (pathlen <= xfs_inode_data_fork_size(ip)) {
333+
xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
334+
335+
ip->i_disk_size = pathlen;
336+
ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
337+
xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
338+
return 0;
339+
}
340+
341+
nmaps = XFS_SYMLINK_MAPS;
342+
error = xfs_bmapi_write(tp, ip, 0, fs_blocks, XFS_BMAPI_METADATA,
343+
resblks, mval, &nmaps);
344+
if (error)
345+
return error;
346+
347+
ip->i_disk_size = pathlen;
348+
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
349+
350+
cur_chunk = target_path;
351+
offset = 0;
352+
for (n = 0; n < nmaps; n++) {
353+
char *buf;
354+
355+
d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
356+
byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
357+
error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
358+
BTOBB(byte_cnt), 0, &bp);
359+
if (error)
360+
return error;
361+
bp->b_ops = &xfs_symlink_buf_ops;
362+
363+
byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
364+
byte_cnt = min(byte_cnt, pathlen);
365+
366+
buf = bp->b_addr;
367+
buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset, byte_cnt,
368+
bp);
369+
370+
memcpy(buf, cur_chunk, byte_cnt);
371+
372+
cur_chunk += byte_cnt;
373+
pathlen -= byte_cnt;
374+
offset += byte_cnt;
375+
376+
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
377+
xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
378+
(char *)bp->b_addr);
379+
}
380+
ASSERT(pathlen == 0);
381+
return 0;
382+
}

fs/xfs/libxfs/xfs_symlink_remote.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,8 @@ void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
1919
struct xfs_inode *ip, struct xfs_ifork *ifp);
2020
xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
2121
int xfs_symlink_remote_read(struct xfs_inode *ip, char *link);
22+
int xfs_symlink_write_target(struct xfs_trans *tp, struct xfs_inode *ip,
23+
const char *target_path, int pathlen, xfs_fsblock_t fs_blocks,
24+
uint resblks);
2225

2326
#endif /* __XFS_SYMLINK_REMOTE_H */

fs/xfs/xfs_symlink.c

Lines changed: 5 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,7 @@ xfs_symlink(
9393
int error = 0;
9494
int pathlen;
9595
bool unlock_dp_on_error = false;
96-
xfs_fileoff_t first_fsb;
9796
xfs_filblks_t fs_blocks;
98-
int nmaps;
99-
struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
100-
xfs_daddr_t d;
101-
const char *cur_chunk;
102-
int byte_cnt;
103-
int n;
104-
struct xfs_buf *bp;
10597
prid_t prid;
10698
struct xfs_dquot *udqp = NULL;
10799
struct xfs_dquot *gdqp = NULL;
@@ -189,62 +181,11 @@ xfs_symlink(
189181
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
190182

191183
resblks -= XFS_IALLOC_SPACE_RES(mp);
192-
/*
193-
* If the symlink will fit into the inode, write it inline.
194-
*/
195-
if (pathlen <= xfs_inode_data_fork_size(ip)) {
196-
xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
197-
198-
ip->i_disk_size = pathlen;
199-
ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
200-
xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
201-
} else {
202-
int offset;
203-
204-
first_fsb = 0;
205-
nmaps = XFS_SYMLINK_MAPS;
206-
207-
error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks,
208-
XFS_BMAPI_METADATA, resblks, mval, &nmaps);
209-
if (error)
210-
goto out_trans_cancel;
211-
212-
resblks -= fs_blocks;
213-
ip->i_disk_size = pathlen;
214-
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
215-
216-
cur_chunk = target_path;
217-
offset = 0;
218-
for (n = 0; n < nmaps; n++) {
219-
char *buf;
220-
221-
d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
222-
byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
223-
error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
224-
BTOBB(byte_cnt), 0, &bp);
225-
if (error)
226-
goto out_trans_cancel;
227-
bp->b_ops = &xfs_symlink_buf_ops;
228-
229-
byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
230-
byte_cnt = min(byte_cnt, pathlen);
231-
232-
buf = bp->b_addr;
233-
buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
234-
byte_cnt, bp);
235-
236-
memcpy(buf, cur_chunk, byte_cnt);
237-
238-
cur_chunk += byte_cnt;
239-
pathlen -= byte_cnt;
240-
offset += byte_cnt;
241-
242-
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
243-
xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
244-
(char *)bp->b_addr);
245-
}
246-
ASSERT(pathlen == 0);
247-
}
184+
error = xfs_symlink_write_target(tp, ip, target_path, pathlen,
185+
fs_blocks, resblks);
186+
if (error)
187+
goto out_trans_cancel;
188+
resblks -= fs_blocks;
248189
i_size_write(VFS_I(ip), ip->i_disk_size);
249190

250191
/*

0 commit comments

Comments
 (0)