aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_inode_buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_inode_buf.c')
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c170
1 files changed, 111 insertions, 59 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 1aabfda669b0..9d9559eb2835 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -195,28 +195,50 @@ xfs_imap_to_bp(
195} 195}
196 196
197void 197void
198xfs_dinode_from_disk( 198xfs_inode_from_disk(
199 xfs_icdinode_t *to, 199 struct xfs_inode *ip,
200 xfs_dinode_t *from) 200 struct xfs_dinode *from)
201{ 201{
202 to->di_magic = be16_to_cpu(from->di_magic); 202 struct xfs_icdinode *to = &ip->i_d;
203 to->di_mode = be16_to_cpu(from->di_mode); 203 struct inode *inode = VFS_I(ip);
204 to->di_version = from ->di_version; 204
205
206 /*
207 * Convert v1 inodes immediately to v2 inode format as this is the
208 * minimum inode version format we support in the rest of the code.
209 */
210 to->di_version = from->di_version;
211 if (to->di_version == 1) {
212 set_nlink(inode, be16_to_cpu(from->di_onlink));
213 to->di_projid_lo = 0;
214 to->di_projid_hi = 0;
215 to->di_version = 2;
216 } else {
217 set_nlink(inode, be32_to_cpu(from->di_nlink));
218 to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
219 to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
220 }
221
205 to->di_format = from->di_format; 222 to->di_format = from->di_format;
206 to->di_onlink = be16_to_cpu(from->di_onlink);
207 to->di_uid = be32_to_cpu(from->di_uid); 223 to->di_uid = be32_to_cpu(from->di_uid);
208 to->di_gid = be32_to_cpu(from->di_gid); 224 to->di_gid = be32_to_cpu(from->di_gid);
209 to->di_nlink = be32_to_cpu(from->di_nlink);
210 to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
211 to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
212 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
213 to->di_flushiter = be16_to_cpu(from->di_flushiter); 225 to->di_flushiter = be16_to_cpu(from->di_flushiter);
214 to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); 226
215 to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); 227 /*
216 to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); 228 * Time is signed, so need to convert to signed 32 bit before
217 to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); 229 * storing in inode timestamp which may be 64 bit. Otherwise
218 to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); 230 * a time before epoch is converted to a time long after epoch
219 to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); 231 * on 64 bit systems.
232 */
233 inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec);
234 inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec);
235 inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec);
236 inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec);
237 inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec);
238 inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec);
239 inode->i_generation = be32_to_cpu(from->di_gen);
240 inode->i_mode = be16_to_cpu(from->di_mode);
241
220 to->di_size = be64_to_cpu(from->di_size); 242 to->di_size = be64_to_cpu(from->di_size);
221 to->di_nblocks = be64_to_cpu(from->di_nblocks); 243 to->di_nblocks = be64_to_cpu(from->di_nblocks);
222 to->di_extsize = be32_to_cpu(from->di_extsize); 244 to->di_extsize = be32_to_cpu(from->di_extsize);
@@ -227,42 +249,96 @@ xfs_dinode_from_disk(
227 to->di_dmevmask = be32_to_cpu(from->di_dmevmask); 249 to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
228 to->di_dmstate = be16_to_cpu(from->di_dmstate); 250 to->di_dmstate = be16_to_cpu(from->di_dmstate);
229 to->di_flags = be16_to_cpu(from->di_flags); 251 to->di_flags = be16_to_cpu(from->di_flags);
230 to->di_gen = be32_to_cpu(from->di_gen);
231 252
232 if (to->di_version == 3) { 253 if (to->di_version == 3) {
233 to->di_changecount = be64_to_cpu(from->di_changecount); 254 inode->i_version = be64_to_cpu(from->di_changecount);
234 to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); 255 to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
235 to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); 256 to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
236 to->di_flags2 = be64_to_cpu(from->di_flags2); 257 to->di_flags2 = be64_to_cpu(from->di_flags2);
237 to->di_ino = be64_to_cpu(from->di_ino);
238 to->di_lsn = be64_to_cpu(from->di_lsn);
239 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
240 uuid_copy(&to->di_uuid, &from->di_uuid);
241 } 258 }
242} 259}
243 260
244void 261void
245xfs_dinode_to_disk( 262xfs_inode_to_disk(
246 xfs_dinode_t *to, 263 struct xfs_inode *ip,
247 xfs_icdinode_t *from) 264 struct xfs_dinode *to,
265 xfs_lsn_t lsn)
266{
267 struct xfs_icdinode *from = &ip->i_d;
268 struct inode *inode = VFS_I(ip);
269
270 to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
271 to->di_onlink = 0;
272
273 to->di_version = from->di_version;
274 to->di_format = from->di_format;
275 to->di_uid = cpu_to_be32(from->di_uid);
276 to->di_gid = cpu_to_be32(from->di_gid);
277 to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
278 to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
279
280 memset(to->di_pad, 0, sizeof(to->di_pad));
281 to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec);
282 to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
283 to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec);
284 to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
285 to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec);
286 to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
287 to->di_nlink = cpu_to_be32(inode->i_nlink);
288 to->di_gen = cpu_to_be32(inode->i_generation);
289 to->di_mode = cpu_to_be16(inode->i_mode);
290
291 to->di_size = cpu_to_be64(from->di_size);
292 to->di_nblocks = cpu_to_be64(from->di_nblocks);
293 to->di_extsize = cpu_to_be32(from->di_extsize);
294 to->di_nextents = cpu_to_be32(from->di_nextents);
295 to->di_anextents = cpu_to_be16(from->di_anextents);
296 to->di_forkoff = from->di_forkoff;
297 to->di_aformat = from->di_aformat;
298 to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
299 to->di_dmstate = cpu_to_be16(from->di_dmstate);
300 to->di_flags = cpu_to_be16(from->di_flags);
301
302 if (from->di_version == 3) {
303 to->di_changecount = cpu_to_be64(inode->i_version);
304 to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
305 to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
306 to->di_flags2 = cpu_to_be64(from->di_flags2);
307
308 to->di_ino = cpu_to_be64(ip->i_ino);
309 to->di_lsn = cpu_to_be64(lsn);
310 memset(to->di_pad2, 0, sizeof(to->di_pad2));
311 uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
312 to->di_flushiter = 0;
313 } else {
314 to->di_flushiter = cpu_to_be16(from->di_flushiter);
315 }
316}
317
318void
319xfs_log_dinode_to_disk(
320 struct xfs_log_dinode *from,
321 struct xfs_dinode *to)
248{ 322{
249 to->di_magic = cpu_to_be16(from->di_magic); 323 to->di_magic = cpu_to_be16(from->di_magic);
250 to->di_mode = cpu_to_be16(from->di_mode); 324 to->di_mode = cpu_to_be16(from->di_mode);
251 to->di_version = from ->di_version; 325 to->di_version = from->di_version;
252 to->di_format = from->di_format; 326 to->di_format = from->di_format;
253 to->di_onlink = cpu_to_be16(from->di_onlink); 327 to->di_onlink = 0;
254 to->di_uid = cpu_to_be32(from->di_uid); 328 to->di_uid = cpu_to_be32(from->di_uid);
255 to->di_gid = cpu_to_be32(from->di_gid); 329 to->di_gid = cpu_to_be32(from->di_gid);
256 to->di_nlink = cpu_to_be32(from->di_nlink); 330 to->di_nlink = cpu_to_be32(from->di_nlink);
257 to->di_projid_lo = cpu_to_be16(from->di_projid_lo); 331 to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
258 to->di_projid_hi = cpu_to_be16(from->di_projid_hi); 332 to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
259 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); 333 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
334
260 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); 335 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
261 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); 336 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
262 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); 337 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
263 to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); 338 to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
264 to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); 339 to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
265 to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); 340 to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
341
266 to->di_size = cpu_to_be64(from->di_size); 342 to->di_size = cpu_to_be64(from->di_size);
267 to->di_nblocks = cpu_to_be64(from->di_nblocks); 343 to->di_nblocks = cpu_to_be64(from->di_nblocks);
268 to->di_extsize = cpu_to_be32(from->di_extsize); 344 to->di_extsize = cpu_to_be32(from->di_extsize);
@@ -367,13 +443,10 @@ xfs_iread(
367 !(mp->m_flags & XFS_MOUNT_IKEEP)) { 443 !(mp->m_flags & XFS_MOUNT_IKEEP)) {
368 /* initialise the on-disk inode core */ 444 /* initialise the on-disk inode core */
369 memset(&ip->i_d, 0, sizeof(ip->i_d)); 445 memset(&ip->i_d, 0, sizeof(ip->i_d));
370 ip->i_d.di_magic = XFS_DINODE_MAGIC; 446 VFS_I(ip)->i_generation = prandom_u32();
371 ip->i_d.di_gen = prandom_u32(); 447 if (xfs_sb_version_hascrc(&mp->m_sb))
372 if (xfs_sb_version_hascrc(&mp->m_sb)) {
373 ip->i_d.di_version = 3; 448 ip->i_d.di_version = 3;
374 ip->i_d.di_ino = ip->i_ino; 449 else
375 uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid);
376 } else
377 ip->i_d.di_version = 2; 450 ip->i_d.di_version = 2;
378 return 0; 451 return 0;
379 } 452 }
@@ -403,7 +476,7 @@ xfs_iread(
403 * Otherwise, just get the truly permanent information. 476 * Otherwise, just get the truly permanent information.
404 */ 477 */
405 if (dip->di_mode) { 478 if (dip->di_mode) {
406 xfs_dinode_from_disk(&ip->i_d, dip); 479 xfs_inode_from_disk(ip, dip);
407 error = xfs_iformat_fork(ip, dip); 480 error = xfs_iformat_fork(ip, dip);
408 if (error) { 481 if (error) {
409#ifdef DEBUG 482#ifdef DEBUG
@@ -417,16 +490,10 @@ xfs_iread(
417 * Partial initialisation of the in-core inode. Just the bits 490 * Partial initialisation of the in-core inode. Just the bits
418 * that xfs_ialloc won't overwrite or relies on being correct. 491 * that xfs_ialloc won't overwrite or relies on being correct.
419 */ 492 */
420 ip->i_d.di_magic = be16_to_cpu(dip->di_magic);
421 ip->i_d.di_version = dip->di_version; 493 ip->i_d.di_version = dip->di_version;
422 ip->i_d.di_gen = be32_to_cpu(dip->di_gen); 494 VFS_I(ip)->i_generation = be32_to_cpu(dip->di_gen);
423 ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); 495 ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter);
424 496
425 if (dip->di_version == 3) {
426 ip->i_d.di_ino = be64_to_cpu(dip->di_ino);
427 uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid);
428 }
429
430 /* 497 /*
431 * Make sure to pull in the mode here as well in 498 * Make sure to pull in the mode here as well in
432 * case the inode is released without being used. 499 * case the inode is released without being used.
@@ -434,25 +501,10 @@ xfs_iread(
434 * the inode is already free and not try to mess 501 * the inode is already free and not try to mess
435 * with the uninitialized part of it. 502 * with the uninitialized part of it.
436 */ 503 */
437 ip->i_d.di_mode = 0; 504 VFS_I(ip)->i_mode = 0;
438 }
439
440 /*
441 * Automatically convert version 1 inode formats in memory to version 2
442 * inode format. If the inode is modified, it will get logged and
443 * rewritten as a version 2 inode. We can do this because we set the
444 * superblock feature bit for v2 inodes unconditionally during mount
445 * and it means the reast of the code can assume the inode version is 2
446 * or higher.
447 */
448 if (ip->i_d.di_version == 1) {
449 ip->i_d.di_version = 2;
450 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
451 ip->i_d.di_nlink = ip->i_d.di_onlink;
452 ip->i_d.di_onlink = 0;
453 xfs_set_projid(ip, 0);
454 } 505 }
455 506
507 ASSERT(ip->i_d.di_version >= 2);
456 ip->i_delayed_blks = 0; 508 ip->i_delayed_blks = 0;
457 509
458 /* 510 /*