aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-04-05 17:41:43 -0400
committerDave Chinner <david@fromorbit.com>2016-04-05 17:41:43 -0400
commit143f4aede7fb25b9198b15660d6f9830936394a8 (patch)
tree0dda05573ebb338ef3baa869db179e7d06e0f402
parentf55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff)
xfs: factor out a helper to initialize a local format inode fork
Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_dir2_sf.c9
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c48
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.h1
-rw-r--r--fs/xfs/xfs_symlink.c12
4 files changed, 36 insertions, 34 deletions
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 974d62e677f4..e5bb9cc3b243 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -257,15 +257,12 @@ xfs_dir2_block_to_sf(
257 * 257 *
258 * Convert the inode to local format and copy the data in. 258 * Convert the inode to local format and copy the data in.
259 */ 259 */
260 dp->i_df.if_flags &= ~XFS_IFEXTENTS;
261 dp->i_df.if_flags |= XFS_IFINLINE;
262 dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
263 ASSERT(dp->i_df.if_bytes == 0); 260 ASSERT(dp->i_df.if_bytes == 0);
264 xfs_idata_realloc(dp, size, XFS_DATA_FORK); 261 xfs_init_local_fork(dp, XFS_DATA_FORK, dst, size);
262 dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
263 dp->i_d.di_size = size;
265 264
266 logflags |= XFS_ILOG_DDATA; 265 logflags |= XFS_ILOG_DDATA;
267 memcpy(dp->i_df.if_u1.if_data, dst, size);
268 dp->i_d.di_size = size;
269 xfs_dir2_sf_check(args); 266 xfs_dir2_sf_check(args);
270out: 267out:
271 xfs_trans_log_inode(args->trans, dp, logflags); 268 xfs_trans_log_inode(args->trans, dp, logflags);
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 11faf7df14c8..86a97f8a9de3 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -231,6 +231,34 @@ xfs_iformat_fork(
231 return error; 231 return error;
232} 232}
233 233
234void
235xfs_init_local_fork(
236 struct xfs_inode *ip,
237 int whichfork,
238 const void *data,
239 int size)
240{
241 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
242 int real_size = 0;
243
244 if (size == 0)
245 ifp->if_u1.if_data = NULL;
246 else if (size <= sizeof(ifp->if_u2.if_inline_data))
247 ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
248 else {
249 real_size = roundup(size, 4);
250 ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
251 }
252
253 if (size)
254 memcpy(ifp->if_u1.if_data, data, size);
255
256 ifp->if_bytes = size;
257 ifp->if_real_bytes = real_size;
258 ifp->if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT);
259 ifp->if_flags |= XFS_IFINLINE;
260}
261
234/* 262/*
235 * The file is in-lined in the on-disk inode. 263 * The file is in-lined in the on-disk inode.
236 * If it fits into if_inline_data, then copy 264 * If it fits into if_inline_data, then copy
@@ -248,8 +276,6 @@ xfs_iformat_local(
248 int whichfork, 276 int whichfork,
249 int size) 277 int size)
250{ 278{
251 xfs_ifork_t *ifp;
252 int real_size;
253 279
254 /* 280 /*
255 * If the size is unreasonable, then something 281 * If the size is unreasonable, then something
@@ -265,22 +291,8 @@ xfs_iformat_local(
265 ip->i_mount, dip); 291 ip->i_mount, dip);
266 return -EFSCORRUPTED; 292 return -EFSCORRUPTED;
267 } 293 }
268 ifp = XFS_IFORK_PTR(ip, whichfork); 294
269 real_size = 0; 295 xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);
270 if (size == 0)
271 ifp->if_u1.if_data = NULL;
272 else if (size <= sizeof(ifp->if_u2.if_inline_data))
273 ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
274 else {
275 real_size = roundup(size, 4);
276 ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
277 }
278 ifp->if_bytes = size;
279 ifp->if_real_bytes = real_size;
280 if (size)
281 memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
282 ifp->if_flags &= ~XFS_IFEXTENTS;
283 ifp->if_flags |= XFS_IFINLINE;
284 return 0; 296 return 0;
285} 297}
286 298
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index 7d3b1ed6dcbe..f95e072ae646 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -134,6 +134,7 @@ void xfs_iroot_realloc(struct xfs_inode *, int, int);
134int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); 134int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
135int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, 135int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
136 int); 136 int);
137void xfs_init_local_fork(struct xfs_inode *, int, const void *, int);
137 138
138struct xfs_bmbt_rec_host * 139struct xfs_bmbt_rec_host *
139 xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t); 140 xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index b44284c1adda..b69f4a770fc9 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -302,19 +302,11 @@ xfs_symlink(
302 * If the symlink will fit into the inode, write it inline. 302 * If the symlink will fit into the inode, write it inline.
303 */ 303 */
304 if (pathlen <= XFS_IFORK_DSIZE(ip)) { 304 if (pathlen <= XFS_IFORK_DSIZE(ip)) {
305 xfs_idata_realloc(ip, pathlen, XFS_DATA_FORK); 305 xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
306 memcpy(ip->i_df.if_u1.if_data, target_path, pathlen);
307 ip->i_d.di_size = pathlen;
308
309 /*
310 * The inode was initially created in extent format.
311 */
312 ip->i_df.if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT);
313 ip->i_df.if_flags |= XFS_IFINLINE;
314 306
307 ip->i_d.di_size = pathlen;
315 ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; 308 ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
316 xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE); 309 xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
317
318 } else { 310 } else {
319 int offset; 311 int offset;
320 312