aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2016-03-06 17:30:32 -0500
committerDave Chinner <david@fromorbit.com>2016-03-06 17:30:32 -0500
commita2bbcb60ff9a8e8a4159e11bc3ed84f7221fe79f (patch)
tree892f8d40b2267422d2d38a62acace8ed613f71a8
parent6d247d47fbd6883f7096e0e672afbdba6286dbc4 (diff)
parentc19b3b05ae440de50fffe2ac2a9b27392a7448e9 (diff)
Merge branch 'xfs-gut-icdinode-4.6' into for-next
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c6
-rw-r--r--fs/xfs/libxfs/xfs_dir2.c12
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c170
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.h38
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c2
-rw-r--r--fs/xfs/libxfs/xfs_log_format.h17
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.c2
-rw-r--r--fs/xfs/xfs_bmap_util.c4
-rw-r--r--fs/xfs/xfs_dir2_readdir.c2
-rw-r--r--fs/xfs/xfs_export.c2
-rw-r--r--fs/xfs/xfs_file.c6
-rw-r--r--fs/xfs/xfs_filestream.c4
-rw-r--r--fs/xfs/xfs_icache.c43
-rw-r--r--fs/xfs/xfs_inode.c172
-rw-r--r--fs/xfs/xfs_inode.h8
-rw-r--r--fs/xfs/xfs_inode_item.c82
-rw-r--r--fs/xfs/xfs_ioctl.c16
-rw-r--r--fs/xfs/xfs_iops.c53
-rw-r--r--fs/xfs/xfs_itable.c22
-rw-r--r--fs/xfs/xfs_log_recover.c58
-rw-r--r--fs/xfs/xfs_mount.c2
-rw-r--r--fs/xfs/xfs_rtalloc.c2
-rw-r--r--fs/xfs/xfs_trans_inode.c14
23 files changed, 429 insertions, 308 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index ef00156f4f96..6a051662d8f9 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -912,7 +912,7 @@ xfs_bmap_local_to_extents(
912 * We don't want to deal with the case of keeping inode data inline yet. 912 * We don't want to deal with the case of keeping inode data inline yet.
913 * So sending the data fork of a regular inode is invalid. 913 * So sending the data fork of a regular inode is invalid.
914 */ 914 */
915 ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK)); 915 ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK));
916 ifp = XFS_IFORK_PTR(ip, whichfork); 916 ifp = XFS_IFORK_PTR(ip, whichfork);
917 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 917 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
918 918
@@ -1079,7 +1079,7 @@ xfs_bmap_add_attrfork_local(
1079 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) 1079 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
1080 return 0; 1080 return 0;
1081 1081
1082 if (S_ISDIR(ip->i_d.di_mode)) { 1082 if (S_ISDIR(VFS_I(ip)->i_mode)) {
1083 memset(&dargs, 0, sizeof(dargs)); 1083 memset(&dargs, 0, sizeof(dargs));
1084 dargs.geo = ip->i_mount->m_dir_geo; 1084 dargs.geo = ip->i_mount->m_dir_geo;
1085 dargs.dp = ip; 1085 dargs.dp = ip;
@@ -1091,7 +1091,7 @@ xfs_bmap_add_attrfork_local(
1091 return xfs_dir2_sf_to_block(&dargs); 1091 return xfs_dir2_sf_to_block(&dargs);
1092 } 1092 }
1093 1093
1094 if (S_ISLNK(ip->i_d.di_mode)) 1094 if (S_ISLNK(VFS_I(ip)->i_mode))
1095 return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, 1095 return xfs_bmap_local_to_extents(tp, ip, firstblock, 1,
1096 flags, XFS_DATA_FORK, 1096 flags, XFS_DATA_FORK,
1097 xfs_symlink_local_to_remote); 1097 xfs_symlink_local_to_remote);
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 2fb53a5c0a74..af0f9d171f8a 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -176,7 +176,7 @@ xfs_dir_isempty(
176{ 176{
177 xfs_dir2_sf_hdr_t *sfp; 177 xfs_dir2_sf_hdr_t *sfp;
178 178
179 ASSERT(S_ISDIR(dp->i_d.di_mode)); 179 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
180 if (dp->i_d.di_size == 0) /* might happen during shutdown. */ 180 if (dp->i_d.di_size == 0) /* might happen during shutdown. */
181 return 1; 181 return 1;
182 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) 182 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
@@ -231,7 +231,7 @@ xfs_dir_init(
231 struct xfs_da_args *args; 231 struct xfs_da_args *args;
232 int error; 232 int error;
233 233
234 ASSERT(S_ISDIR(dp->i_d.di_mode)); 234 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
235 error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino); 235 error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino);
236 if (error) 236 if (error)
237 return error; 237 return error;
@@ -266,7 +266,7 @@ xfs_dir_createname(
266 int rval; 266 int rval;
267 int v; /* type-checking value */ 267 int v; /* type-checking value */
268 268
269 ASSERT(S_ISDIR(dp->i_d.di_mode)); 269 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
270 if (inum) { 270 if (inum) {
271 rval = xfs_dir_ino_validate(tp->t_mountp, inum); 271 rval = xfs_dir_ino_validate(tp->t_mountp, inum);
272 if (rval) 272 if (rval)
@@ -364,7 +364,7 @@ xfs_dir_lookup(
364 int v; /* type-checking value */ 364 int v; /* type-checking value */
365 int lock_mode; 365 int lock_mode;
366 366
367 ASSERT(S_ISDIR(dp->i_d.di_mode)); 367 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
368 XFS_STATS_INC(dp->i_mount, xs_dir_lookup); 368 XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
369 369
370 /* 370 /*
@@ -443,7 +443,7 @@ xfs_dir_removename(
443 int rval; 443 int rval;
444 int v; /* type-checking value */ 444 int v; /* type-checking value */
445 445
446 ASSERT(S_ISDIR(dp->i_d.di_mode)); 446 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
447 XFS_STATS_INC(dp->i_mount, xs_dir_remove); 447 XFS_STATS_INC(dp->i_mount, xs_dir_remove);
448 448
449 args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); 449 args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
@@ -505,7 +505,7 @@ xfs_dir_replace(
505 int rval; 505 int rval;
506 int v; /* type-checking value */ 506 int v; /* type-checking value */
507 507
508 ASSERT(S_ISDIR(dp->i_d.di_mode)); 508 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
509 509
510 rval = xfs_dir_ino_validate(tp->t_mountp, inum); 510 rval = xfs_dir_ino_validate(tp->t_mountp, inum);
511 if (rval) 511 if (rval)
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 /*
diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h
index 9308c47f2a52..7c4dd321b215 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.h
+++ b/fs/xfs/libxfs/xfs_inode_buf.h
@@ -20,7 +20,36 @@
20 20
21struct xfs_inode; 21struct xfs_inode;
22struct xfs_dinode; 22struct xfs_dinode;
23struct xfs_icdinode; 23
24/*
25 * In memory representation of the XFS inode. This is held in the in-core struct
26 * xfs_inode and represents the current on disk values but the structure is not
27 * in on-disk format. That is, this structure is always translated to on-disk
28 * format specific structures at the appropriate time.
29 */
30struct xfs_icdinode {
31 __int8_t di_version; /* inode version */
32 __int8_t di_format; /* format of di_c data */
33 __uint16_t di_flushiter; /* incremented on flush */
34 __uint32_t di_uid; /* owner's user id */
35 __uint32_t di_gid; /* owner's group id */
36 __uint16_t di_projid_lo; /* lower part of owner's project id */
37 __uint16_t di_projid_hi; /* higher part of owner's project id */
38 xfs_fsize_t di_size; /* number of bytes in file */
39 xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
40 xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
41 xfs_extnum_t di_nextents; /* number of extents in data fork */
42 xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
43 __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
44 __int8_t di_aformat; /* format of attr fork's data */
45 __uint32_t di_dmevmask; /* DMIG event mask */
46 __uint16_t di_dmstate; /* DMIG state info */
47 __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
48
49 __uint64_t di_flags2; /* more random flags */
50
51 xfs_ictimestamp_t di_crtime; /* time created */
52};
24 53
25/* 54/*
26 * Inode location information. Stored in the inode and passed to 55 * Inode location information. Stored in the inode and passed to
@@ -38,8 +67,11 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
38int xfs_iread(struct xfs_mount *, struct xfs_trans *, 67int xfs_iread(struct xfs_mount *, struct xfs_trans *,
39 struct xfs_inode *, uint); 68 struct xfs_inode *, uint);
40void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); 69void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
41void xfs_dinode_to_disk(struct xfs_dinode *to, struct xfs_icdinode *from); 70void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
42void xfs_dinode_from_disk(struct xfs_icdinode *to, struct xfs_dinode *from); 71 xfs_lsn_t lsn);
72void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
73void xfs_log_dinode_to_disk(struct xfs_log_dinode *from,
74 struct xfs_dinode *to);
43 75
44#if defined(DEBUG) 76#if defined(DEBUG)
45void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); 77void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index ef22a78fb569..11faf7df14c8 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -121,7 +121,7 @@ xfs_iformat_fork(
121 return -EFSCORRUPTED; 121 return -EFSCORRUPTED;
122 } 122 }
123 123
124 switch (ip->i_d.di_mode & S_IFMT) { 124 switch (VFS_I(ip)->i_mode & S_IFMT) {
125 case S_IFIFO: 125 case S_IFIFO:
126 case S_IFCHR: 126 case S_IFCHR:
127 case S_IFBLK: 127 case S_IFBLK:
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index 1be26ecdbebf..d54a8018b079 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -290,6 +290,7 @@ typedef struct xfs_inode_log_format_64 {
290 __int32_t ilf_boffset; /* off of inode in buffer */ 290 __int32_t ilf_boffset; /* off of inode in buffer */
291} xfs_inode_log_format_64_t; 291} xfs_inode_log_format_64_t;
292 292
293
293/* 294/*
294 * Flags for xfs_trans_log_inode flags field. 295 * Flags for xfs_trans_log_inode flags field.
295 */ 296 */
@@ -360,15 +361,15 @@ typedef struct xfs_ictimestamp {
360} xfs_ictimestamp_t; 361} xfs_ictimestamp_t;
361 362
362/* 363/*
363 * NOTE: This structure must be kept identical to struct xfs_dinode 364 * Define the format of the inode core that is logged. This structure must be
364 * except for the endianness annotations. 365 * kept identical to struct xfs_dinode except for the endianness annotations.
365 */ 366 */
366typedef struct xfs_icdinode { 367struct xfs_log_dinode {
367 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ 368 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
368 __uint16_t di_mode; /* mode and type of file */ 369 __uint16_t di_mode; /* mode and type of file */
369 __int8_t di_version; /* inode version */ 370 __int8_t di_version; /* inode version */
370 __int8_t di_format; /* format of di_c data */ 371 __int8_t di_format; /* format of di_c data */
371 __uint16_t di_onlink; /* old number of links to file */ 372 __uint8_t di_pad3[2]; /* unused in v2/3 inodes */
372 __uint32_t di_uid; /* owner's user id */ 373 __uint32_t di_uid; /* owner's user id */
373 __uint32_t di_gid; /* owner's group id */ 374 __uint32_t di_gid; /* owner's group id */
374 __uint32_t di_nlink; /* number of links to file */ 375 __uint32_t di_nlink; /* number of links to file */
@@ -407,13 +408,13 @@ typedef struct xfs_icdinode {
407 uuid_t di_uuid; /* UUID of the filesystem */ 408 uuid_t di_uuid; /* UUID of the filesystem */
408 409
409 /* structure must be padded to 64 bit alignment */ 410 /* structure must be padded to 64 bit alignment */
410} xfs_icdinode_t; 411};
411 412
412static inline uint xfs_icdinode_size(int version) 413static inline uint xfs_log_dinode_size(int version)
413{ 414{
414 if (version == 3) 415 if (version == 3)
415 return sizeof(struct xfs_icdinode); 416 return sizeof(struct xfs_log_dinode);
416 return offsetof(struct xfs_icdinode, di_next_unlinked); 417 return offsetof(struct xfs_log_dinode, di_next_unlinked);
417} 418}
418 419
419/* 420/*
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 33806e0c2bc6..951c044e24e4 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1011,7 +1011,7 @@ xfs_rtfree_extent(
1011 mp->m_sb.sb_rextents) { 1011 mp->m_sb.sb_rextents) {
1012 if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) 1012 if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM))
1013 mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; 1013 mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
1014 *(__uint64_t *)&mp->m_rbmip->i_d.di_atime = 0; 1014 *(__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
1015 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); 1015 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1016 } 1016 }
1017 return 0; 1017 return 0;
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 07ef29b9b464..fd7f51c39b3f 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -823,7 +823,7 @@ bool
823xfs_can_free_eofblocks(struct xfs_inode *ip, bool force) 823xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
824{ 824{
825 /* prealloc/delalloc exists only on regular files */ 825 /* prealloc/delalloc exists only on regular files */
826 if (!S_ISREG(ip->i_d.di_mode)) 826 if (!S_ISREG(VFS_I(ip)->i_mode))
827 return false; 827 return false;
828 828
829 /* 829 /*
@@ -1728,7 +1728,7 @@ xfs_swap_extents(
1728 xfs_lock_two_inodes(ip, tip, XFS_MMAPLOCK_EXCL); 1728 xfs_lock_two_inodes(ip, tip, XFS_MMAPLOCK_EXCL);
1729 1729
1730 /* Verify that both files have the same format */ 1730 /* Verify that both files have the same format */
1731 if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { 1731 if ((VFS_I(ip)->i_mode & S_IFMT) != (VFS_I(tip)->i_mode & S_IFMT)) {
1732 error = -EINVAL; 1732 error = -EINVAL;
1733 goto out_unlock; 1733 goto out_unlock;
1734 } 1734 }
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 642d55d10075..93b3ab0c5435 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -665,7 +665,7 @@ xfs_readdir(
665 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 665 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
666 return -EIO; 666 return -EIO;
667 667
668 ASSERT(S_ISDIR(dp->i_d.di_mode)); 668 ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
669 XFS_STATS_INC(dp->i_mount, xs_dir_getdents); 669 XFS_STATS_INC(dp->i_mount, xs_dir_getdents);
670 670
671 args.dp = dp; 671 args.dp = dp;
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 652cd3c5b58c..2816d42507bc 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -152,7 +152,7 @@ xfs_nfs_get_inode(
152 return ERR_PTR(error); 152 return ERR_PTR(error);
153 } 153 }
154 154
155 if (ip->i_d.di_gen != generation) { 155 if (VFS_I(ip)->i_generation != generation) {
156 IRELE(ip); 156 IRELE(ip);
157 return ERR_PTR(-ESTALE); 157 return ERR_PTR(-ESTALE);
158 } 158 }
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 70a4b5a2802e..ac0fd32de31e 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -156,9 +156,9 @@ xfs_update_prealloc_flags(
156 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 156 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
157 157
158 if (!(flags & XFS_PREALLOC_INVISIBLE)) { 158 if (!(flags & XFS_PREALLOC_INVISIBLE)) {
159 ip->i_d.di_mode &= ~S_ISUID; 159 VFS_I(ip)->i_mode &= ~S_ISUID;
160 if (ip->i_d.di_mode & S_IXGRP) 160 if (VFS_I(ip)->i_mode & S_IXGRP)
161 ip->i_d.di_mode &= ~S_ISGID; 161 VFS_I(ip)->i_mode &= ~S_ISGID;
162 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 162 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
163 } 163 }
164 164
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index c4c130f9bfb6..a51353a1f87f 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -151,7 +151,7 @@ xfs_filestream_pick_ag(
151 xfs_agnumber_t ag, max_ag = NULLAGNUMBER; 151 xfs_agnumber_t ag, max_ag = NULLAGNUMBER;
152 int err, trylock, nscan; 152 int err, trylock, nscan;
153 153
154 ASSERT(S_ISDIR(ip->i_d.di_mode)); 154 ASSERT(S_ISDIR(VFS_I(ip)->i_mode));
155 155
156 /* 2% of an AG's blocks must be free for it to be chosen. */ 156 /* 2% of an AG's blocks must be free for it to be chosen. */
157 minfree = mp->m_sb.sb_agblocks / 50; 157 minfree = mp->m_sb.sb_agblocks / 50;
@@ -319,7 +319,7 @@ xfs_filestream_lookup_ag(
319 xfs_agnumber_t startag, ag = NULLAGNUMBER; 319 xfs_agnumber_t startag, ag = NULLAGNUMBER;
320 struct xfs_mru_cache_elem *mru; 320 struct xfs_mru_cache_elem *mru;
321 321
322 ASSERT(S_ISREG(ip->i_d.di_mode)); 322 ASSERT(S_ISREG(VFS_I(ip)->i_mode));
323 323
324 pip = xfs_filestream_get_parent(ip); 324 pip = xfs_filestream_get_parent(ip);
325 if (!pip) 325 if (!pip)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index d7a490f24ead..bf2d60749278 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -63,6 +63,9 @@ xfs_inode_alloc(
63 return NULL; 63 return NULL;
64 } 64 }
65 65
66 /* VFS doesn't initialise i_mode! */
67 VFS_I(ip)->i_mode = 0;
68
66 XFS_STATS_INC(mp, vn_active); 69 XFS_STATS_INC(mp, vn_active);
67 ASSERT(atomic_read(&ip->i_pincount) == 0); 70 ASSERT(atomic_read(&ip->i_pincount) == 0);
68 ASSERT(!spin_is_locked(&ip->i_flags_lock)); 71 ASSERT(!spin_is_locked(&ip->i_flags_lock));
@@ -79,7 +82,7 @@ xfs_inode_alloc(
79 memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); 82 memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
80 ip->i_flags = 0; 83 ip->i_flags = 0;
81 ip->i_delayed_blks = 0; 84 ip->i_delayed_blks = 0;
82 memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); 85 memset(&ip->i_d, 0, sizeof(ip->i_d));
83 86
84 return ip; 87 return ip;
85} 88}
@@ -98,7 +101,7 @@ void
98xfs_inode_free( 101xfs_inode_free(
99 struct xfs_inode *ip) 102 struct xfs_inode *ip)
100{ 103{
101 switch (ip->i_d.di_mode & S_IFMT) { 104 switch (VFS_I(ip)->i_mode & S_IFMT) {
102 case S_IFREG: 105 case S_IFREG:
103 case S_IFDIR: 106 case S_IFDIR:
104 case S_IFLNK: 107 case S_IFLNK:
@@ -135,6 +138,34 @@ xfs_inode_free(
135} 138}
136 139
137/* 140/*
141 * When we recycle a reclaimable inode, we need to re-initialise the VFS inode
142 * part of the structure. This is made more complex by the fact we store
143 * information about the on-disk values in the VFS inode and so we can't just
144 * overwrite the values unconditionally. Hence we save the parameters we
145 * need to retain across reinitialisation, and rewrite them into the VFS inode
146 * after reinitialisation even if it fails.
147 */
148static int
149xfs_reinit_inode(
150 struct xfs_mount *mp,
151 struct inode *inode)
152{
153 int error;
154 uint32_t nlink = inode->i_nlink;
155 uint32_t generation = inode->i_generation;
156 uint64_t version = inode->i_version;
157 umode_t mode = inode->i_mode;
158
159 error = inode_init_always(mp->m_super, inode);
160
161 set_nlink(inode, nlink);
162 inode->i_generation = generation;
163 inode->i_version = version;
164 inode->i_mode = mode;
165 return error;
166}
167
168/*
138 * Check the validity of the inode we just found it the cache 169 * Check the validity of the inode we just found it the cache
139 */ 170 */
140static int 171static int
@@ -185,7 +216,7 @@ xfs_iget_cache_hit(
185 /* 216 /*
186 * If lookup is racing with unlink return an error immediately. 217 * If lookup is racing with unlink return an error immediately.
187 */ 218 */
188 if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) { 219 if (VFS_I(ip)->i_mode == 0 && !(flags & XFS_IGET_CREATE)) {
189 error = -ENOENT; 220 error = -ENOENT;
190 goto out_error; 221 goto out_error;
191 } 222 }
@@ -208,7 +239,7 @@ xfs_iget_cache_hit(
208 spin_unlock(&ip->i_flags_lock); 239 spin_unlock(&ip->i_flags_lock);
209 rcu_read_unlock(); 240 rcu_read_unlock();
210 241
211 error = inode_init_always(mp->m_super, inode); 242 error = xfs_reinit_inode(mp, inode);
212 if (error) { 243 if (error) {
213 /* 244 /*
214 * Re-initializing the inode failed, and we are in deep 245 * Re-initializing the inode failed, and we are in deep
@@ -295,7 +326,7 @@ xfs_iget_cache_miss(
295 326
296 trace_xfs_iget_miss(ip); 327 trace_xfs_iget_miss(ip);
297 328
298 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { 329 if ((VFS_I(ip)->i_mode == 0) && !(flags & XFS_IGET_CREATE)) {
299 error = -ENOENT; 330 error = -ENOENT;
300 goto out_destroy; 331 goto out_destroy;
301 } 332 }
@@ -444,7 +475,7 @@ again:
444 * If we have a real type for an on-disk inode, we can setup the inode 475 * If we have a real type for an on-disk inode, we can setup the inode
445 * now. If it's a new inode being created, xfs_ialloc will handle it. 476 * now. If it's a new inode being created, xfs_ialloc will handle it.
446 */ 477 */
447 if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0) 478 if (xfs_iflags_test(ip, XFS_INEW) && VFS_I(ip)->i_mode != 0)
448 xfs_setup_existing_inode(ip); 479 xfs_setup_existing_inode(ip);
449 return 0; 480 return 0;
450 481
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index ceba1a83cacc..26bac4ab79a3 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -57,9 +57,9 @@ kmem_zone_t *xfs_inode_zone;
57 */ 57 */
58#define XFS_ITRUNC_MAX_EXTENTS 2 58#define XFS_ITRUNC_MAX_EXTENTS 2
59 59
60STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *); 60STATIC int xfs_iflush_int(struct xfs_inode *, struct xfs_buf *);
61 61STATIC int xfs_iunlink(struct xfs_trans *, struct xfs_inode *);
62STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *); 62STATIC int xfs_iunlink_remove(struct xfs_trans *, struct xfs_inode *);
63 63
64/* 64/*
65 * helper function to extract extent size hint from inode 65 * helper function to extract extent size hint from inode
@@ -766,6 +766,7 @@ xfs_ialloc(
766 uint flags; 766 uint flags;
767 int error; 767 int error;
768 struct timespec tv; 768 struct timespec tv;
769 struct inode *inode;
769 770
770 /* 771 /*
771 * Call the space management code to pick 772 * Call the space management code to pick
@@ -791,6 +792,7 @@ xfs_ialloc(
791 if (error) 792 if (error)
792 return error; 793 return error;
793 ASSERT(ip != NULL); 794 ASSERT(ip != NULL);
795 inode = VFS_I(ip);
794 796
795 /* 797 /*
796 * We always convert v1 inodes to v2 now - we only support filesystems 798 * We always convert v1 inodes to v2 now - we only support filesystems
@@ -800,20 +802,16 @@ xfs_ialloc(
800 if (ip->i_d.di_version == 1) 802 if (ip->i_d.di_version == 1)
801 ip->i_d.di_version = 2; 803 ip->i_d.di_version = 2;
802 804
803 ip->i_d.di_mode = mode; 805 inode->i_mode = mode;
804 ip->i_d.di_onlink = 0; 806 set_nlink(inode, nlink);
805 ip->i_d.di_nlink = nlink;
806 ASSERT(ip->i_d.di_nlink == nlink);
807 ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); 807 ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid());
808 ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); 808 ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid());
809 xfs_set_projid(ip, prid); 809 xfs_set_projid(ip, prid);
810 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
811 810
812 if (pip && XFS_INHERIT_GID(pip)) { 811 if (pip && XFS_INHERIT_GID(pip)) {
813 ip->i_d.di_gid = pip->i_d.di_gid; 812 ip->i_d.di_gid = pip->i_d.di_gid;
814 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) { 813 if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode))
815 ip->i_d.di_mode |= S_ISGID; 814 inode->i_mode |= S_ISGID;
816 }
817 } 815 }
818 816
819 /* 817 /*
@@ -822,38 +820,29 @@ xfs_ialloc(
822 * (and only if the irix_sgid_inherit compatibility variable is set). 820 * (and only if the irix_sgid_inherit compatibility variable is set).
823 */ 821 */
824 if ((irix_sgid_inherit) && 822 if ((irix_sgid_inherit) &&
825 (ip->i_d.di_mode & S_ISGID) && 823 (inode->i_mode & S_ISGID) &&
826 (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) { 824 (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid))))
827 ip->i_d.di_mode &= ~S_ISGID; 825 inode->i_mode &= ~S_ISGID;
828 }
829 826
830 ip->i_d.di_size = 0; 827 ip->i_d.di_size = 0;
831 ip->i_d.di_nextents = 0; 828 ip->i_d.di_nextents = 0;
832 ASSERT(ip->i_d.di_nblocks == 0); 829 ASSERT(ip->i_d.di_nblocks == 0);
833 830
834 tv = current_fs_time(mp->m_super); 831 tv = current_fs_time(mp->m_super);
835 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; 832 inode->i_mtime = tv;
836 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; 833 inode->i_atime = tv;
837 ip->i_d.di_atime = ip->i_d.di_mtime; 834 inode->i_ctime = tv;
838 ip->i_d.di_ctime = ip->i_d.di_mtime;
839 835
840 /*
841 * di_gen will have been taken care of in xfs_iread.
842 */
843 ip->i_d.di_extsize = 0; 836 ip->i_d.di_extsize = 0;
844 ip->i_d.di_dmevmask = 0; 837 ip->i_d.di_dmevmask = 0;
845 ip->i_d.di_dmstate = 0; 838 ip->i_d.di_dmstate = 0;
846 ip->i_d.di_flags = 0; 839 ip->i_d.di_flags = 0;
847 840
848 if (ip->i_d.di_version == 3) { 841 if (ip->i_d.di_version == 3) {
849 ASSERT(ip->i_d.di_ino == ino); 842 inode->i_version = 1;
850 ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));
851 ip->i_d.di_crc = 0;
852 ip->i_d.di_changecount = 1;
853 ip->i_d.di_lsn = 0;
854 ip->i_d.di_flags2 = 0; 843 ip->i_d.di_flags2 = 0;
855 memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); 844 ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec;
856 ip->i_d.di_crtime = ip->i_d.di_mtime; 845 ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec;
857 } 846 }
858 847
859 848
@@ -1092,35 +1081,24 @@ xfs_dir_ialloc(
1092} 1081}
1093 1082
1094/* 1083/*
1095 * Decrement the link count on an inode & log the change. 1084 * Decrement the link count on an inode & log the change. If this causes the
1096 * If this causes the link count to go to zero, initiate the 1085 * link count to go to zero, move the inode to AGI unlinked list so that it can
1097 * logging activity required to truncate a file. 1086 * be freed when the last active reference goes away via xfs_inactive().
1098 */ 1087 */
1099int /* error */ 1088int /* error */
1100xfs_droplink( 1089xfs_droplink(
1101 xfs_trans_t *tp, 1090 xfs_trans_t *tp,
1102 xfs_inode_t *ip) 1091 xfs_inode_t *ip)
1103{ 1092{
1104 int error;
1105
1106 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); 1093 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1107 1094
1108 ASSERT (ip->i_d.di_nlink > 0);
1109 ip->i_d.di_nlink--;
1110 drop_nlink(VFS_I(ip)); 1095 drop_nlink(VFS_I(ip));
1111 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1096 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1112 1097
1113 error = 0; 1098 if (VFS_I(ip)->i_nlink)
1114 if (ip->i_d.di_nlink == 0) { 1099 return 0;
1115 /* 1100
1116 * We're dropping the last link to this file. 1101 return xfs_iunlink(tp, ip);
1117 * Move the on-disk inode to the AGI unlinked list.
1118 * From xfs_inactive() we will pull the inode from
1119 * the list and free it.
1120 */
1121 error = xfs_iunlink(tp, ip);
1122 }
1123 return error;
1124} 1102}
1125 1103
1126/* 1104/*
@@ -1134,8 +1112,6 @@ xfs_bumplink(
1134 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); 1112 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1135 1113
1136 ASSERT(ip->i_d.di_version > 1); 1114 ASSERT(ip->i_d.di_version > 1);
1137 ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
1138 ip->i_d.di_nlink++;
1139 inc_nlink(VFS_I(ip)); 1115 inc_nlink(VFS_I(ip));
1140 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1116 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1141 return 0; 1117 return 0;
@@ -1393,7 +1369,6 @@ xfs_create_tmpfile(
1393 */ 1369 */
1394 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); 1370 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
1395 1371
1396 ip->i_d.di_nlink--;
1397 error = xfs_iunlink(tp, ip); 1372 error = xfs_iunlink(tp, ip);
1398 if (error) 1373 if (error)
1399 goto out_trans_cancel; 1374 goto out_trans_cancel;
@@ -1444,7 +1419,7 @@ xfs_link(
1444 1419
1445 trace_xfs_link(tdp, target_name); 1420 trace_xfs_link(tdp, target_name);
1446 1421
1447 ASSERT(!S_ISDIR(sip->i_d.di_mode)); 1422 ASSERT(!S_ISDIR(VFS_I(sip)->i_mode));
1448 1423
1449 if (XFS_FORCED_SHUTDOWN(mp)) 1424 if (XFS_FORCED_SHUTDOWN(mp))
1450 return -EIO; 1425 return -EIO;
@@ -1492,7 +1467,10 @@ xfs_link(
1492 1467
1493 xfs_bmap_init(&free_list, &first_block); 1468 xfs_bmap_init(&free_list, &first_block);
1494 1469
1495 if (sip->i_d.di_nlink == 0) { 1470 /*
1471 * Handle initial link state of O_TMPFILE inode
1472 */
1473 if (VFS_I(sip)->i_nlink == 0) {
1496 error = xfs_iunlink_remove(tp, sip); 1474 error = xfs_iunlink_remove(tp, sip);
1497 if (error) 1475 if (error)
1498 goto error_return; 1476 goto error_return;
@@ -1648,7 +1626,7 @@ xfs_release(
1648 xfs_mount_t *mp = ip->i_mount; 1626 xfs_mount_t *mp = ip->i_mount;
1649 int error; 1627 int error;
1650 1628
1651 if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) 1629 if (!S_ISREG(VFS_I(ip)->i_mode) || (VFS_I(ip)->i_mode == 0))
1652 return 0; 1630 return 0;
1653 1631
1654 /* If this is a read-only mount, don't do this (would generate I/O) */ 1632 /* If this is a read-only mount, don't do this (would generate I/O) */
@@ -1679,7 +1657,7 @@ xfs_release(
1679 } 1657 }
1680 } 1658 }
1681 1659
1682 if (ip->i_d.di_nlink == 0) 1660 if (VFS_I(ip)->i_nlink == 0)
1683 return 0; 1661 return 0;
1684 1662
1685 if (xfs_can_free_eofblocks(ip, false)) { 1663 if (xfs_can_free_eofblocks(ip, false)) {
@@ -1883,7 +1861,7 @@ xfs_inactive(
1883 * If the inode is already free, then there can be nothing 1861 * If the inode is already free, then there can be nothing
1884 * to clean up here. 1862 * to clean up here.
1885 */ 1863 */
1886 if (ip->i_d.di_mode == 0) { 1864 if (VFS_I(ip)->i_mode == 0) {
1887 ASSERT(ip->i_df.if_real_bytes == 0); 1865 ASSERT(ip->i_df.if_real_bytes == 0);
1888 ASSERT(ip->i_df.if_broot_bytes == 0); 1866 ASSERT(ip->i_df.if_broot_bytes == 0);
1889 return; 1867 return;
@@ -1895,7 +1873,7 @@ xfs_inactive(
1895 if (mp->m_flags & XFS_MOUNT_RDONLY) 1873 if (mp->m_flags & XFS_MOUNT_RDONLY)
1896 return; 1874 return;
1897 1875
1898 if (ip->i_d.di_nlink != 0) { 1876 if (VFS_I(ip)->i_nlink != 0) {
1899 /* 1877 /*
1900 * force is true because we are evicting an inode from the 1878 * force is true because we are evicting an inode from the
1901 * cache. Post-eof blocks must be freed, lest we end up with 1879 * cache. Post-eof blocks must be freed, lest we end up with
@@ -1907,7 +1885,7 @@ xfs_inactive(
1907 return; 1885 return;
1908 } 1886 }
1909 1887
1910 if (S_ISREG(ip->i_d.di_mode) && 1888 if (S_ISREG(VFS_I(ip)->i_mode) &&
1911 (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || 1889 (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 ||
1912 ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) 1890 ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0))
1913 truncate = 1; 1891 truncate = 1;
@@ -1916,7 +1894,7 @@ xfs_inactive(
1916 if (error) 1894 if (error)
1917 return; 1895 return;
1918 1896
1919 if (S_ISLNK(ip->i_d.di_mode)) 1897 if (S_ISLNK(VFS_I(ip)->i_mode))
1920 error = xfs_inactive_symlink(ip); 1898 error = xfs_inactive_symlink(ip);
1921 else if (truncate) 1899 else if (truncate)
1922 error = xfs_inactive_truncate(ip); 1900 error = xfs_inactive_truncate(ip);
@@ -1952,16 +1930,21 @@ xfs_inactive(
1952} 1930}
1953 1931
1954/* 1932/*
1955 * This is called when the inode's link count goes to 0. 1933 * This is called when the inode's link count goes to 0 or we are creating a
1956 * We place the on-disk inode on a list in the AGI. It 1934 * tmpfile via O_TMPFILE. In the case of a tmpfile, @ignore_linkcount will be
1957 * will be pulled from this list when the inode is freed. 1935 * set to true as the link count is dropped to zero by the VFS after we've
1936 * created the file successfully, so we have to add it to the unlinked list
1937 * while the link count is non-zero.
1938 *
1939 * We place the on-disk inode on a list in the AGI. It will be pulled from this
1940 * list when the inode is freed.
1958 */ 1941 */
1959int 1942STATIC int
1960xfs_iunlink( 1943xfs_iunlink(
1961 xfs_trans_t *tp, 1944 struct xfs_trans *tp,
1962 xfs_inode_t *ip) 1945 struct xfs_inode *ip)
1963{ 1946{
1964 xfs_mount_t *mp; 1947 xfs_mount_t *mp = tp->t_mountp;
1965 xfs_agi_t *agi; 1948 xfs_agi_t *agi;
1966 xfs_dinode_t *dip; 1949 xfs_dinode_t *dip;
1967 xfs_buf_t *agibp; 1950 xfs_buf_t *agibp;
@@ -1971,10 +1954,7 @@ xfs_iunlink(
1971 int offset; 1954 int offset;
1972 int error; 1955 int error;
1973 1956
1974 ASSERT(ip->i_d.di_nlink == 0); 1957 ASSERT(VFS_I(ip)->i_mode != 0);
1975 ASSERT(ip->i_d.di_mode != 0);
1976
1977 mp = tp->t_mountp;
1978 1958
1979 /* 1959 /*
1980 * Get the agi buffer first. It ensures lock ordering 1960 * Get the agi buffer first. It ensures lock ordering
@@ -2412,10 +2392,10 @@ xfs_ifree(
2412 struct xfs_icluster xic = { 0 }; 2392 struct xfs_icluster xic = { 0 };
2413 2393
2414 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 2394 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2415 ASSERT(ip->i_d.di_nlink == 0); 2395 ASSERT(VFS_I(ip)->i_nlink == 0);
2416 ASSERT(ip->i_d.di_nextents == 0); 2396 ASSERT(ip->i_d.di_nextents == 0);
2417 ASSERT(ip->i_d.di_anextents == 0); 2397 ASSERT(ip->i_d.di_anextents == 0);
2418 ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode)); 2398 ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
2419 ASSERT(ip->i_d.di_nblocks == 0); 2399 ASSERT(ip->i_d.di_nblocks == 0);
2420 2400
2421 /* 2401 /*
@@ -2429,7 +2409,7 @@ xfs_ifree(
2429 if (error) 2409 if (error)
2430 return error; 2410 return error;
2431 2411
2432 ip->i_d.di_mode = 0; /* mark incore inode as free */ 2412 VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
2433 ip->i_d.di_flags = 0; 2413 ip->i_d.di_flags = 0;
2434 ip->i_d.di_dmevmask = 0; 2414 ip->i_d.di_dmevmask = 0;
2435 ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ 2415 ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */
@@ -2439,7 +2419,7 @@ xfs_ifree(
2439 * Bump the generation count so no one will be confused 2419 * Bump the generation count so no one will be confused
2440 * by reincarnations of this inode. 2420 * by reincarnations of this inode.
2441 */ 2421 */
2442 ip->i_d.di_gen++; 2422 VFS_I(ip)->i_generation++;
2443 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 2423 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
2444 2424
2445 if (xic.deleted) 2425 if (xic.deleted)
@@ -2526,7 +2506,7 @@ xfs_remove(
2526{ 2506{
2527 xfs_mount_t *mp = dp->i_mount; 2507 xfs_mount_t *mp = dp->i_mount;
2528 xfs_trans_t *tp = NULL; 2508 xfs_trans_t *tp = NULL;
2529 int is_dir = S_ISDIR(ip->i_d.di_mode); 2509 int is_dir = S_ISDIR(VFS_I(ip)->i_mode);
2530 int error = 0; 2510 int error = 0;
2531 xfs_bmap_free_t free_list; 2511 xfs_bmap_free_t free_list;
2532 xfs_fsblock_t first_block; 2512 xfs_fsblock_t first_block;
@@ -2580,8 +2560,8 @@ xfs_remove(
2580 * If we're removing a directory perform some additional validation. 2560 * If we're removing a directory perform some additional validation.
2581 */ 2561 */
2582 if (is_dir) { 2562 if (is_dir) {
2583 ASSERT(ip->i_d.di_nlink >= 2); 2563 ASSERT(VFS_I(ip)->i_nlink >= 2);
2584 if (ip->i_d.di_nlink != 2) { 2564 if (VFS_I(ip)->i_nlink != 2) {
2585 error = -ENOTEMPTY; 2565 error = -ENOTEMPTY;
2586 goto out_trans_cancel; 2566 goto out_trans_cancel;
2587 } 2567 }
@@ -2771,7 +2751,7 @@ xfs_cross_rename(
2771 if (dp1 != dp2) { 2751 if (dp1 != dp2) {
2772 dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; 2752 dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
2773 2753
2774 if (S_ISDIR(ip2->i_d.di_mode)) { 2754 if (S_ISDIR(VFS_I(ip2)->i_mode)) {
2775 error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, 2755 error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot,
2776 dp1->i_ino, first_block, 2756 dp1->i_ino, first_block,
2777 free_list, spaceres); 2757 free_list, spaceres);
@@ -2779,7 +2759,7 @@ xfs_cross_rename(
2779 goto out_trans_abort; 2759 goto out_trans_abort;
2780 2760
2781 /* transfer ip2 ".." reference to dp1 */ 2761 /* transfer ip2 ".." reference to dp1 */
2782 if (!S_ISDIR(ip1->i_d.di_mode)) { 2762 if (!S_ISDIR(VFS_I(ip1)->i_mode)) {
2783 error = xfs_droplink(tp, dp2); 2763 error = xfs_droplink(tp, dp2);
2784 if (error) 2764 if (error)
2785 goto out_trans_abort; 2765 goto out_trans_abort;
@@ -2798,7 +2778,7 @@ xfs_cross_rename(
2798 ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; 2778 ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
2799 } 2779 }
2800 2780
2801 if (S_ISDIR(ip1->i_d.di_mode)) { 2781 if (S_ISDIR(VFS_I(ip1)->i_mode)) {
2802 error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, 2782 error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot,
2803 dp2->i_ino, first_block, 2783 dp2->i_ino, first_block,
2804 free_list, spaceres); 2784 free_list, spaceres);
@@ -2806,7 +2786,7 @@ xfs_cross_rename(
2806 goto out_trans_abort; 2786 goto out_trans_abort;
2807 2787
2808 /* transfer ip1 ".." reference to dp2 */ 2788 /* transfer ip1 ".." reference to dp2 */
2809 if (!S_ISDIR(ip2->i_d.di_mode)) { 2789 if (!S_ISDIR(VFS_I(ip2)->i_mode)) {
2810 error = xfs_droplink(tp, dp1); 2790 error = xfs_droplink(tp, dp1);
2811 if (error) 2791 if (error)
2812 goto out_trans_abort; 2792 goto out_trans_abort;
@@ -2903,7 +2883,7 @@ xfs_rename(
2903 struct xfs_inode *inodes[__XFS_SORT_INODES]; 2883 struct xfs_inode *inodes[__XFS_SORT_INODES];
2904 int num_inodes = __XFS_SORT_INODES; 2884 int num_inodes = __XFS_SORT_INODES;
2905 bool new_parent = (src_dp != target_dp); 2885 bool new_parent = (src_dp != target_dp);
2906 bool src_is_directory = S_ISDIR(src_ip->i_d.di_mode); 2886 bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode);
2907 int spaceres; 2887 int spaceres;
2908 int error; 2888 int error;
2909 2889
@@ -3032,12 +3012,12 @@ xfs_rename(
3032 * target and source are directories and that target can be 3012 * target and source are directories and that target can be
3033 * destroyed, or that neither is a directory. 3013 * destroyed, or that neither is a directory.
3034 */ 3014 */
3035 if (S_ISDIR(target_ip->i_d.di_mode)) { 3015 if (S_ISDIR(VFS_I(target_ip)->i_mode)) {
3036 /* 3016 /*
3037 * Make sure target dir is empty. 3017 * Make sure target dir is empty.
3038 */ 3018 */
3039 if (!(xfs_dir_isempty(target_ip)) || 3019 if (!(xfs_dir_isempty(target_ip)) ||
3040 (target_ip->i_d.di_nlink > 2)) { 3020 (VFS_I(target_ip)->i_nlink > 2)) {
3041 error = -EEXIST; 3021 error = -EEXIST;
3042 goto out_trans_cancel; 3022 goto out_trans_cancel;
3043 } 3023 }
@@ -3144,7 +3124,7 @@ xfs_rename(
3144 * intermediate state on disk. 3124 * intermediate state on disk.
3145 */ 3125 */
3146 if (wip) { 3126 if (wip) {
3147 ASSERT(VFS_I(wip)->i_nlink == 0 && wip->i_d.di_nlink == 0); 3127 ASSERT(VFS_I(wip)->i_nlink == 0);
3148 error = xfs_bumplink(tp, wip); 3128 error = xfs_bumplink(tp, wip);
3149 if (error) 3129 if (error)
3150 goto out_bmap_cancel; 3130 goto out_bmap_cancel;
@@ -3462,14 +3442,7 @@ xfs_iflush_int(
3462 __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); 3442 __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip);
3463 goto corrupt_out; 3443 goto corrupt_out;
3464 } 3444 }
3465 if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, 3445 if (S_ISREG(VFS_I(ip)->i_mode)) {
3466 mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) {
3467 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3468 "%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x",
3469 __func__, ip->i_ino, ip, ip->i_d.di_magic);
3470 goto corrupt_out;
3471 }
3472 if (S_ISREG(ip->i_d.di_mode)) {
3473 if (XFS_TEST_ERROR( 3446 if (XFS_TEST_ERROR(
3474 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && 3447 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
3475 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), 3448 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE),
@@ -3479,7 +3452,7 @@ xfs_iflush_int(
3479 __func__, ip->i_ino, ip); 3452 __func__, ip->i_ino, ip);
3480 goto corrupt_out; 3453 goto corrupt_out;
3481 } 3454 }
3482 } else if (S_ISDIR(ip->i_d.di_mode)) { 3455 } else if (S_ISDIR(VFS_I(ip)->i_mode)) {
3483 if (XFS_TEST_ERROR( 3456 if (XFS_TEST_ERROR(
3484 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && 3457 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
3485 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && 3458 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
@@ -3523,12 +3496,11 @@ xfs_iflush_int(
3523 ip->i_d.di_flushiter++; 3496 ip->i_d.di_flushiter++;
3524 3497
3525 /* 3498 /*
3526 * Copy the dirty parts of the inode into the on-disk 3499 * Copy the dirty parts of the inode into the on-disk inode. We always
3527 * inode. We always copy out the core of the inode, 3500 * copy out the core of the inode, because if the inode is dirty at all
3528 * because if the inode is dirty at all the core must 3501 * the core must be.
3529 * be.
3530 */ 3502 */
3531 xfs_dinode_to_disk(dip, &ip->i_d); 3503 xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn);
3532 3504
3533 /* Wrap, we never let the log put out DI_MAX_FLUSH */ 3505 /* Wrap, we never let the log put out DI_MAX_FLUSH */
3534 if (ip->i_d.di_flushiter == DI_MAX_FLUSH) 3506 if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
@@ -3580,10 +3552,6 @@ xfs_iflush_int(
3580 */ 3552 */
3581 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item); 3553 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item);
3582 3554
3583 /* update the lsn in the on disk inode if required */
3584 if (ip->i_d.di_version == 3)
3585 dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn);
3586
3587 /* generate the checksum. */ 3555 /* generate the checksum. */
3588 xfs_dinode_calc_crc(mp, dip); 3556 xfs_dinode_calc_crc(mp, dip);
3589 3557
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index ed7e9339c7e9..43e1d51b15eb 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -63,7 +63,7 @@ typedef struct xfs_inode {
63 unsigned long i_flags; /* see defined flags below */ 63 unsigned long i_flags; /* see defined flags below */
64 unsigned int i_delayed_blks; /* count of delay alloc blks */ 64 unsigned int i_delayed_blks; /* count of delay alloc blks */
65 65
66 xfs_icdinode_t i_d; /* most of ondisk inode */ 66 struct xfs_icdinode i_d; /* most of ondisk inode */
67 67
68 /* VFS inode */ 68 /* VFS inode */
69 struct inode i_vnode; /* embedded VFS inode */ 69 struct inode i_vnode; /* embedded VFS inode */
@@ -88,7 +88,7 @@ static inline struct inode *VFS_I(struct xfs_inode *ip)
88 */ 88 */
89static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip) 89static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
90{ 90{
91 if (S_ISREG(ip->i_d.di_mode)) 91 if (S_ISREG(VFS_I(ip)->i_mode))
92 return i_size_read(VFS_I(ip)); 92 return i_size_read(VFS_I(ip));
93 return ip->i_d.di_size; 93 return ip->i_d.di_size;
94} 94}
@@ -369,7 +369,7 @@ static inline int xfs_isiflocked(struct xfs_inode *ip)
369 */ 369 */
370#define XFS_INHERIT_GID(pip) \ 370#define XFS_INHERIT_GID(pip) \
371 (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ 371 (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
372 ((pip)->i_d.di_mode & S_ISGID)) 372 (VFS_I(pip)->i_mode & S_ISGID))
373 373
374int xfs_release(struct xfs_inode *ip); 374int xfs_release(struct xfs_inode *ip);
375void xfs_inactive(struct xfs_inode *ip); 375void xfs_inactive(struct xfs_inode *ip);
@@ -405,8 +405,6 @@ int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
405 struct xfs_bmap_free *); 405 struct xfs_bmap_free *);
406int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *, 406int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *,
407 int, xfs_fsize_t); 407 int, xfs_fsize_t);
408int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
409
410void xfs_iext_realloc(xfs_inode_t *, int, int); 408void xfs_iext_realloc(xfs_inode_t *, int, int);
411 409
412void xfs_iunpin_wait(xfs_inode_t *); 410void xfs_iunpin_wait(xfs_inode_t *);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index d14b12b8cfef..c48b5b18d771 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -135,7 +135,7 @@ xfs_inode_item_size(
135 135
136 *nvecs += 2; 136 *nvecs += 2;
137 *nbytes += sizeof(struct xfs_inode_log_format) + 137 *nbytes += sizeof(struct xfs_inode_log_format) +
138 xfs_icdinode_size(ip->i_d.di_version); 138 xfs_log_dinode_size(ip->i_d.di_version);
139 139
140 xfs_inode_item_data_fork_size(iip, nvecs, nbytes); 140 xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
141 if (XFS_IFORK_Q(ip)) 141 if (XFS_IFORK_Q(ip))
@@ -322,6 +322,81 @@ xfs_inode_item_format_attr_fork(
322 } 322 }
323} 323}
324 324
325static void
326xfs_inode_to_log_dinode(
327 struct xfs_inode *ip,
328 struct xfs_log_dinode *to,
329 xfs_lsn_t lsn)
330{
331 struct xfs_icdinode *from = &ip->i_d;
332 struct inode *inode = VFS_I(ip);
333
334 to->di_magic = XFS_DINODE_MAGIC;
335
336 to->di_version = from->di_version;
337 to->di_format = from->di_format;
338 to->di_uid = from->di_uid;
339 to->di_gid = from->di_gid;
340 to->di_projid_lo = from->di_projid_lo;
341 to->di_projid_hi = from->di_projid_hi;
342
343 memset(to->di_pad, 0, sizeof(to->di_pad));
344 memset(to->di_pad3, 0, sizeof(to->di_pad3));
345 to->di_atime.t_sec = inode->i_atime.tv_sec;
346 to->di_atime.t_nsec = inode->i_atime.tv_nsec;
347 to->di_mtime.t_sec = inode->i_mtime.tv_sec;
348 to->di_mtime.t_nsec = inode->i_mtime.tv_nsec;
349 to->di_ctime.t_sec = inode->i_ctime.tv_sec;
350 to->di_ctime.t_nsec = inode->i_ctime.tv_nsec;
351 to->di_nlink = inode->i_nlink;
352 to->di_gen = inode->i_generation;
353 to->di_mode = inode->i_mode;
354
355 to->di_size = from->di_size;
356 to->di_nblocks = from->di_nblocks;
357 to->di_extsize = from->di_extsize;
358 to->di_nextents = from->di_nextents;
359 to->di_anextents = from->di_anextents;
360 to->di_forkoff = from->di_forkoff;
361 to->di_aformat = from->di_aformat;
362 to->di_dmevmask = from->di_dmevmask;
363 to->di_dmstate = from->di_dmstate;
364 to->di_flags = from->di_flags;
365
366 if (from->di_version == 3) {
367 to->di_changecount = inode->i_version;
368 to->di_crtime.t_sec = from->di_crtime.t_sec;
369 to->di_crtime.t_nsec = from->di_crtime.t_nsec;
370 to->di_flags2 = from->di_flags2;
371
372 to->di_ino = ip->i_ino;
373 to->di_lsn = lsn;
374 memset(to->di_pad2, 0, sizeof(to->di_pad2));
375 uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
376 to->di_flushiter = 0;
377 } else {
378 to->di_flushiter = from->di_flushiter;
379 }
380}
381
382/*
383 * Format the inode core. Current timestamp data is only in the VFS inode
384 * fields, so we need to grab them from there. Hence rather than just copying
385 * the XFS inode core structure, format the fields directly into the iovec.
386 */
387static void
388xfs_inode_item_format_core(
389 struct xfs_inode *ip,
390 struct xfs_log_vec *lv,
391 struct xfs_log_iovec **vecp)
392{
393 struct xfs_log_dinode *dic;
394
395 dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
396 xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn);
397 xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version));
398}
399
325/* 400/*
326 * This is called to fill in the vector of log iovecs for the given inode 401 * This is called to fill in the vector of log iovecs for the given inode
327 * log item. It fills the first item with an inode log format structure, 402 * log item. It fills the first item with an inode log format structure,
@@ -351,10 +426,7 @@ xfs_inode_item_format(
351 ilf->ilf_size = 2; /* format + core */ 426 ilf->ilf_size = 2; /* format + core */
352 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format)); 427 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format));
353 428
354 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE, 429 xfs_inode_item_format_core(ip, lv, &vecp);
355 &ip->i_d,
356 xfs_icdinode_size(ip->i_d.di_version));
357
358 xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp); 430 xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
359 if (XFS_IFORK_Q(ip)) { 431 if (XFS_IFORK_Q(ip)) {
360 xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp); 432 xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 478d04e07f95..81d6d6218803 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -114,7 +114,7 @@ xfs_find_handle(
114 handle.ha_fid.fid_len = sizeof(xfs_fid_t) - 114 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
115 sizeof(handle.ha_fid.fid_len); 115 sizeof(handle.ha_fid.fid_len);
116 handle.ha_fid.fid_pad = 0; 116 handle.ha_fid.fid_pad = 0;
117 handle.ha_fid.fid_gen = ip->i_d.di_gen; 117 handle.ha_fid.fid_gen = inode->i_generation;
118 handle.ha_fid.fid_ino = ip->i_ino; 118 handle.ha_fid.fid_ino = ip->i_ino;
119 119
120 hsize = XFS_HSIZE(handle); 120 hsize = XFS_HSIZE(handle);
@@ -963,7 +963,7 @@ xfs_set_diflags(
963 di_flags |= XFS_DIFLAG_NODEFRAG; 963 di_flags |= XFS_DIFLAG_NODEFRAG;
964 if (xflags & FS_XFLAG_FILESTREAM) 964 if (xflags & FS_XFLAG_FILESTREAM)
965 di_flags |= XFS_DIFLAG_FILESTREAM; 965 di_flags |= XFS_DIFLAG_FILESTREAM;
966 if (S_ISDIR(ip->i_d.di_mode)) { 966 if (S_ISDIR(VFS_I(ip)->i_mode)) {
967 if (xflags & FS_XFLAG_RTINHERIT) 967 if (xflags & FS_XFLAG_RTINHERIT)
968 di_flags |= XFS_DIFLAG_RTINHERIT; 968 di_flags |= XFS_DIFLAG_RTINHERIT;
969 if (xflags & FS_XFLAG_NOSYMLINKS) 969 if (xflags & FS_XFLAG_NOSYMLINKS)
@@ -972,7 +972,7 @@ xfs_set_diflags(
972 di_flags |= XFS_DIFLAG_EXTSZINHERIT; 972 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
973 if (xflags & FS_XFLAG_PROJINHERIT) 973 if (xflags & FS_XFLAG_PROJINHERIT)
974 di_flags |= XFS_DIFLAG_PROJINHERIT; 974 di_flags |= XFS_DIFLAG_PROJINHERIT;
975 } else if (S_ISREG(ip->i_d.di_mode)) { 975 } else if (S_ISREG(VFS_I(ip)->i_mode)) {
976 if (xflags & FS_XFLAG_REALTIME) 976 if (xflags & FS_XFLAG_REALTIME)
977 di_flags |= XFS_DIFLAG_REALTIME; 977 di_flags |= XFS_DIFLAG_REALTIME;
978 if (xflags & FS_XFLAG_EXTSIZE) 978 if (xflags & FS_XFLAG_EXTSIZE)
@@ -1128,14 +1128,14 @@ xfs_ioctl_setattr_check_extsize(
1128{ 1128{
1129 struct xfs_mount *mp = ip->i_mount; 1129 struct xfs_mount *mp = ip->i_mount;
1130 1130
1131 if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode)) 1131 if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode))
1132 return -EINVAL; 1132 return -EINVAL;
1133 1133
1134 if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) && 1134 if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
1135 !S_ISDIR(ip->i_d.di_mode)) 1135 !S_ISDIR(VFS_I(ip)->i_mode))
1136 return -EINVAL; 1136 return -EINVAL;
1137 1137
1138 if (S_ISREG(ip->i_d.di_mode) && ip->i_d.di_nextents && 1138 if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents &&
1139 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) 1139 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
1140 return -EINVAL; 1140 return -EINVAL;
1141 1141
@@ -1256,9 +1256,9 @@ xfs_ioctl_setattr(
1256 * successful return from chown() 1256 * successful return from chown()
1257 */ 1257 */
1258 1258
1259 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && 1259 if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
1260 !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID)) 1260 !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
1261 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); 1261 VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
1262 1262
1263 /* Change the ownerships and register project quota modifications */ 1263 /* Change the ownerships and register project quota modifications */
1264 if (xfs_get_projid(ip) != fa->fsx_projid) { 1264 if (xfs_get_projid(ip) != fa->fsx_projid) {
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 76b71a1c6c32..0d38b1d2c420 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -459,8 +459,8 @@ xfs_vn_getattr(
459 459
460 stat->size = XFS_ISIZE(ip); 460 stat->size = XFS_ISIZE(ip);
461 stat->dev = inode->i_sb->s_dev; 461 stat->dev = inode->i_sb->s_dev;
462 stat->mode = ip->i_d.di_mode; 462 stat->mode = inode->i_mode;
463 stat->nlink = ip->i_d.di_nlink; 463 stat->nlink = inode->i_nlink;
464 stat->uid = inode->i_uid; 464 stat->uid = inode->i_uid;
465 stat->gid = inode->i_gid; 465 stat->gid = inode->i_gid;
466 stat->ino = ip->i_ino; 466 stat->ino = ip->i_ino;
@@ -506,9 +506,6 @@ xfs_setattr_mode(
506 506
507 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 507 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
508 508
509 ip->i_d.di_mode &= S_IFMT;
510 ip->i_d.di_mode |= mode & ~S_IFMT;
511
512 inode->i_mode &= S_IFMT; 509 inode->i_mode &= S_IFMT;
513 inode->i_mode |= mode & ~S_IFMT; 510 inode->i_mode |= mode & ~S_IFMT;
514} 511}
@@ -522,21 +519,12 @@ xfs_setattr_time(
522 519
523 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 520 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
524 521
525 if (iattr->ia_valid & ATTR_ATIME) { 522 if (iattr->ia_valid & ATTR_ATIME)
526 inode->i_atime = iattr->ia_atime; 523 inode->i_atime = iattr->ia_atime;
527 ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; 524 if (iattr->ia_valid & ATTR_CTIME)
528 ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
529 }
530 if (iattr->ia_valid & ATTR_CTIME) {
531 inode->i_ctime = iattr->ia_ctime; 525 inode->i_ctime = iattr->ia_ctime;
532 ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; 526 if (iattr->ia_valid & ATTR_MTIME)
533 ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
534 }
535 if (iattr->ia_valid & ATTR_MTIME) {
536 inode->i_mtime = iattr->ia_mtime; 527 inode->i_mtime = iattr->ia_mtime;
537 ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
538 ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
539 }
540} 528}
541 529
542int 530int
@@ -661,9 +649,9 @@ xfs_setattr_nonsize(
661 * The set-user-ID and set-group-ID bits of a file will be 649 * The set-user-ID and set-group-ID bits of a file will be
662 * cleared upon successful return from chown() 650 * cleared upon successful return from chown()
663 */ 651 */
664 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && 652 if ((inode->i_mode & (S_ISUID|S_ISGID)) &&
665 !capable(CAP_FSETID)) 653 !capable(CAP_FSETID))
666 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); 654 inode->i_mode &= ~(S_ISUID|S_ISGID);
667 655
668 /* 656 /*
669 * Change the ownerships and register quota modifications 657 * Change the ownerships and register quota modifications
@@ -773,7 +761,7 @@ xfs_setattr_size(
773 761
774 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); 762 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
775 ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL)); 763 ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
776 ASSERT(S_ISREG(ip->i_d.di_mode)); 764 ASSERT(S_ISREG(inode->i_mode));
777 ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| 765 ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
778 ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); 766 ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
779 767
@@ -991,21 +979,13 @@ xfs_vn_update_time(
991 } 979 }
992 980
993 xfs_ilock(ip, XFS_ILOCK_EXCL); 981 xfs_ilock(ip, XFS_ILOCK_EXCL);
994 if (flags & S_CTIME) { 982 if (flags & S_CTIME)
995 inode->i_ctime = *now; 983 inode->i_ctime = *now;
996 ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec; 984 if (flags & S_MTIME)
997 ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
998 }
999 if (flags & S_MTIME) {
1000 inode->i_mtime = *now; 985 inode->i_mtime = *now;
1001 ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec; 986 if (flags & S_ATIME)
1002 ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
1003 }
1004 if (flags & S_ATIME) {
1005 inode->i_atime = *now; 987 inode->i_atime = *now;
1006 ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec; 988
1007 ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
1008 }
1009 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 989 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1010 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); 990 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
1011 return xfs_trans_commit(tp); 991 return xfs_trans_commit(tp);
@@ -1232,8 +1212,6 @@ xfs_setup_inode(
1232 /* make the inode look hashed for the writeback code */ 1212 /* make the inode look hashed for the writeback code */
1233 hlist_add_fake(&inode->i_hash); 1213 hlist_add_fake(&inode->i_hash);
1234 1214
1235 inode->i_mode = ip->i_d.di_mode;
1236 set_nlink(inode, ip->i_d.di_nlink);
1237 inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid); 1215 inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid);
1238 inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid); 1216 inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid);
1239 1217
@@ -1249,14 +1227,7 @@ xfs_setup_inode(
1249 break; 1227 break;
1250 } 1228 }
1251 1229
1252 inode->i_generation = ip->i_d.di_gen;
1253 i_size_write(inode, ip->i_d.di_size); 1230 i_size_write(inode, ip->i_d.di_size);
1254 inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec;
1255 inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
1256 inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
1257 inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
1258 inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
1259 inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
1260 xfs_diflags_to_iflags(inode, ip); 1231 xfs_diflags_to_iflags(inode, ip);
1261 1232
1262 ip->d_ops = ip->i_mount->m_nondir_inode_ops; 1233 ip->d_ops = ip->i_mount->m_nondir_inode_ops;
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 930ebd86beba..ce73eb34620d 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -57,6 +57,7 @@ xfs_bulkstat_one_int(
57{ 57{
58 struct xfs_icdinode *dic; /* dinode core info pointer */ 58 struct xfs_icdinode *dic; /* dinode core info pointer */
59 struct xfs_inode *ip; /* incore inode pointer */ 59 struct xfs_inode *ip; /* incore inode pointer */
60 struct inode *inode;
60 struct xfs_bstat *buf; /* return buffer */ 61 struct xfs_bstat *buf; /* return buffer */
61 int error = 0; /* error value */ 62 int error = 0; /* error value */
62 63
@@ -77,30 +78,33 @@ xfs_bulkstat_one_int(
77 78
78 ASSERT(ip != NULL); 79 ASSERT(ip != NULL);
79 ASSERT(ip->i_imap.im_blkno != 0); 80 ASSERT(ip->i_imap.im_blkno != 0);
81 inode = VFS_I(ip);
80 82
81 dic = &ip->i_d; 83 dic = &ip->i_d;
82 84
83 /* xfs_iget returns the following without needing 85 /* xfs_iget returns the following without needing
84 * further change. 86 * further change.
85 */ 87 */
86 buf->bs_nlink = dic->di_nlink;
87 buf->bs_projid_lo = dic->di_projid_lo; 88 buf->bs_projid_lo = dic->di_projid_lo;
88 buf->bs_projid_hi = dic->di_projid_hi; 89 buf->bs_projid_hi = dic->di_projid_hi;
89 buf->bs_ino = ino; 90 buf->bs_ino = ino;
90 buf->bs_mode = dic->di_mode;
91 buf->bs_uid = dic->di_uid; 91 buf->bs_uid = dic->di_uid;
92 buf->bs_gid = dic->di_gid; 92 buf->bs_gid = dic->di_gid;
93 buf->bs_size = dic->di_size; 93 buf->bs_size = dic->di_size;
94 buf->bs_atime.tv_sec = dic->di_atime.t_sec; 94
95 buf->bs_atime.tv_nsec = dic->di_atime.t_nsec; 95 buf->bs_nlink = inode->i_nlink;
96 buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; 96 buf->bs_atime.tv_sec = inode->i_atime.tv_sec;
97 buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; 97 buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec;
98 buf->bs_ctime.tv_sec = dic->di_ctime.t_sec; 98 buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec;
99 buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec; 99 buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec;
100 buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec;
101 buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec;
102 buf->bs_gen = inode->i_generation;
103 buf->bs_mode = inode->i_mode;
104
100 buf->bs_xflags = xfs_ip2xflags(ip); 105 buf->bs_xflags = xfs_ip2xflags(ip);
101 buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; 106 buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
102 buf->bs_extents = dic->di_nextents; 107 buf->bs_extents = dic->di_nextents;
103 buf->bs_gen = dic->di_gen;
104 memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); 108 memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
105 buf->bs_dmevmask = dic->di_dmevmask; 109 buf->bs_dmevmask = dic->di_dmevmask;
106 buf->bs_dmstate = dic->di_dmstate; 110 buf->bs_dmstate = dic->di_dmstate;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 2c449a25c4f6..e776594889c3 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2865,7 +2865,7 @@ xfs_recover_inode_owner_change(
2865 return -ENOMEM; 2865 return -ENOMEM;
2866 2866
2867 /* instantiate the inode */ 2867 /* instantiate the inode */
2868 xfs_dinode_from_disk(&ip->i_d, dip); 2868 xfs_inode_from_disk(ip, dip);
2869 ASSERT(ip->i_d.di_version >= 3); 2869 ASSERT(ip->i_d.di_version >= 3);
2870 2870
2871 error = xfs_iformat_fork(ip, dip); 2871 error = xfs_iformat_fork(ip, dip);
@@ -2911,7 +2911,7 @@ xlog_recover_inode_pass2(
2911 int error; 2911 int error;
2912 int attr_index; 2912 int attr_index;
2913 uint fields; 2913 uint fields;
2914 xfs_icdinode_t *dicp; 2914 struct xfs_log_dinode *ldip;
2915 uint isize; 2915 uint isize;
2916 int need_free = 0; 2916 int need_free = 0;
2917 2917
@@ -2964,8 +2964,8 @@ xlog_recover_inode_pass2(
2964 error = -EFSCORRUPTED; 2964 error = -EFSCORRUPTED;
2965 goto out_release; 2965 goto out_release;
2966 } 2966 }
2967 dicp = item->ri_buf[1].i_addr; 2967 ldip = item->ri_buf[1].i_addr;
2968 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2968 if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) {
2969 xfs_alert(mp, 2969 xfs_alert(mp,
2970 "%s: Bad inode log record, rec ptr 0x%p, ino %Ld", 2970 "%s: Bad inode log record, rec ptr 0x%p, ino %Ld",
2971 __func__, item, in_f->ilf_ino); 2971 __func__, item, in_f->ilf_ino);
@@ -3001,13 +3001,13 @@ xlog_recover_inode_pass2(
3001 * to skip replay when the on disk inode is newer than the log one 3001 * to skip replay when the on disk inode is newer than the log one
3002 */ 3002 */
3003 if (!xfs_sb_version_hascrc(&mp->m_sb) && 3003 if (!xfs_sb_version_hascrc(&mp->m_sb) &&
3004 dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) { 3004 ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
3005 /* 3005 /*
3006 * Deal with the wrap case, DI_MAX_FLUSH is less 3006 * Deal with the wrap case, DI_MAX_FLUSH is less
3007 * than smaller numbers 3007 * than smaller numbers
3008 */ 3008 */
3009 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && 3009 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
3010 dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) { 3010 ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) {
3011 /* do nothing */ 3011 /* do nothing */
3012 } else { 3012 } else {
3013 trace_xfs_log_recover_inode_skip(log, in_f); 3013 trace_xfs_log_recover_inode_skip(log, in_f);
@@ -3017,13 +3017,13 @@ xlog_recover_inode_pass2(
3017 } 3017 }
3018 3018
3019 /* Take the opportunity to reset the flush iteration count */ 3019 /* Take the opportunity to reset the flush iteration count */
3020 dicp->di_flushiter = 0; 3020 ldip->di_flushiter = 0;
3021 3021
3022 if (unlikely(S_ISREG(dicp->di_mode))) { 3022 if (unlikely(S_ISREG(ldip->di_mode))) {
3023 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 3023 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
3024 (dicp->di_format != XFS_DINODE_FMT_BTREE)) { 3024 (ldip->di_format != XFS_DINODE_FMT_BTREE)) {
3025 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", 3025 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
3026 XFS_ERRLEVEL_LOW, mp, dicp); 3026 XFS_ERRLEVEL_LOW, mp, ldip);
3027 xfs_alert(mp, 3027 xfs_alert(mp,
3028 "%s: Bad regular inode log record, rec ptr 0x%p, " 3028 "%s: Bad regular inode log record, rec ptr 0x%p, "
3029 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 3029 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
@@ -3031,12 +3031,12 @@ xlog_recover_inode_pass2(
3031 error = -EFSCORRUPTED; 3031 error = -EFSCORRUPTED;
3032 goto out_release; 3032 goto out_release;
3033 } 3033 }
3034 } else if (unlikely(S_ISDIR(dicp->di_mode))) { 3034 } else if (unlikely(S_ISDIR(ldip->di_mode))) {
3035 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 3035 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
3036 (dicp->di_format != XFS_DINODE_FMT_BTREE) && 3036 (ldip->di_format != XFS_DINODE_FMT_BTREE) &&
3037 (dicp->di_format != XFS_DINODE_FMT_LOCAL)) { 3037 (ldip->di_format != XFS_DINODE_FMT_LOCAL)) {
3038 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)", 3038 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
3039 XFS_ERRLEVEL_LOW, mp, dicp); 3039 XFS_ERRLEVEL_LOW, mp, ldip);
3040 xfs_alert(mp, 3040 xfs_alert(mp,
3041 "%s: Bad dir inode log record, rec ptr 0x%p, " 3041 "%s: Bad dir inode log record, rec ptr 0x%p, "
3042 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 3042 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
@@ -3045,32 +3045,32 @@ xlog_recover_inode_pass2(
3045 goto out_release; 3045 goto out_release;
3046 } 3046 }
3047 } 3047 }
3048 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ 3048 if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
3049 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)", 3049 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
3050 XFS_ERRLEVEL_LOW, mp, dicp); 3050 XFS_ERRLEVEL_LOW, mp, ldip);
3051 xfs_alert(mp, 3051 xfs_alert(mp,
3052 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " 3052 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
3053 "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld", 3053 "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
3054 __func__, item, dip, bp, in_f->ilf_ino, 3054 __func__, item, dip, bp, in_f->ilf_ino,
3055 dicp->di_nextents + dicp->di_anextents, 3055 ldip->di_nextents + ldip->di_anextents,
3056 dicp->di_nblocks); 3056 ldip->di_nblocks);
3057 error = -EFSCORRUPTED; 3057 error = -EFSCORRUPTED;
3058 goto out_release; 3058 goto out_release;
3059 } 3059 }
3060 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { 3060 if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
3061 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)", 3061 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
3062 XFS_ERRLEVEL_LOW, mp, dicp); 3062 XFS_ERRLEVEL_LOW, mp, ldip);
3063 xfs_alert(mp, 3063 xfs_alert(mp,
3064 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " 3064 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
3065 "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__, 3065 "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__,
3066 item, dip, bp, in_f->ilf_ino, dicp->di_forkoff); 3066 item, dip, bp, in_f->ilf_ino, ldip->di_forkoff);
3067 error = -EFSCORRUPTED; 3067 error = -EFSCORRUPTED;
3068 goto out_release; 3068 goto out_release;
3069 } 3069 }
3070 isize = xfs_icdinode_size(dicp->di_version); 3070 isize = xfs_log_dinode_size(ldip->di_version);
3071 if (unlikely(item->ri_buf[1].i_len > isize)) { 3071 if (unlikely(item->ri_buf[1].i_len > isize)) {
3072 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", 3072 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
3073 XFS_ERRLEVEL_LOW, mp, dicp); 3073 XFS_ERRLEVEL_LOW, mp, ldip);
3074 xfs_alert(mp, 3074 xfs_alert(mp,
3075 "%s: Bad inode log record length %d, rec ptr 0x%p", 3075 "%s: Bad inode log record length %d, rec ptr 0x%p",
3076 __func__, item->ri_buf[1].i_len, item); 3076 __func__, item->ri_buf[1].i_len, item);
@@ -3078,8 +3078,8 @@ xlog_recover_inode_pass2(
3078 goto out_release; 3078 goto out_release;
3079 } 3079 }
3080 3080
3081 /* The core is in in-core format */ 3081 /* recover the log dinode inode into the on disk inode */
3082 xfs_dinode_to_disk(dip, dicp); 3082 xfs_log_dinode_to_disk(ldip, dip);
3083 3083
3084 /* the rest is in on-disk format */ 3084 /* the rest is in on-disk format */
3085 if (item->ri_buf[1].i_len > isize) { 3085 if (item->ri_buf[1].i_len > isize) {
@@ -4409,8 +4409,8 @@ xlog_recover_process_one_iunlink(
4409 if (error) 4409 if (error)
4410 goto fail_iput; 4410 goto fail_iput;
4411 4411
4412 ASSERT(ip->i_d.di_nlink == 0); 4412 ASSERT(VFS_I(ip)->i_nlink == 0);
4413 ASSERT(ip->i_d.di_mode != 0); 4413 ASSERT(VFS_I(ip)->i_mode != 0);
4414 4414
4415 /* setup for the next pass */ 4415 /* setup for the next pass */
4416 agino = be32_to_cpu(dip->di_next_unlinked); 4416 agino = be32_to_cpu(dip->di_next_unlinked);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index bb753b359bee..d3061054bad2 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -865,7 +865,7 @@ xfs_mountfs(
865 865
866 ASSERT(rip != NULL); 866 ASSERT(rip != NULL);
867 867
868 if (unlikely(!S_ISDIR(rip->i_d.di_mode))) { 868 if (unlikely(!S_ISDIR(VFS_I(rip)->i_mode))) {
869 xfs_warn(mp, "corrupted root inode %llu: not a directory", 869 xfs_warn(mp, "corrupted root inode %llu: not a directory",
870 (unsigned long long)rip->i_ino); 870 (unsigned long long)rip->i_ino);
871 xfs_iunlock(rip, XFS_ILOCK_EXCL); 871 xfs_iunlock(rip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index be02a68b2fe2..abf44435d04a 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1272,7 +1272,7 @@ xfs_rtpick_extent(
1272 1272
1273 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); 1273 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
1274 1274
1275 seqp = (__uint64_t *)&mp->m_rbmip->i_d.di_atime; 1275 seqp = (__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime;
1276 if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) { 1276 if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) {
1277 mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; 1277 mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
1278 *seqp = 0; 1278 *seqp = 0;
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index b97f1df910ab..11a3af08b5c7 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -75,18 +75,10 @@ xfs_trans_ichgtime(
75 75
76 tv = current_fs_time(inode->i_sb); 76 tv = current_fs_time(inode->i_sb);
77 77
78 if ((flags & XFS_ICHGTIME_MOD) && 78 if (flags & XFS_ICHGTIME_MOD)
79 !timespec_equal(&inode->i_mtime, &tv)) {
80 inode->i_mtime = tv; 79 inode->i_mtime = tv;
81 ip->i_d.di_mtime.t_sec = tv.tv_sec; 80 if (flags & XFS_ICHGTIME_CHG)
82 ip->i_d.di_mtime.t_nsec = tv.tv_nsec;
83 }
84 if ((flags & XFS_ICHGTIME_CHG) &&
85 !timespec_equal(&inode->i_ctime, &tv)) {
86 inode->i_ctime = tv; 81 inode->i_ctime = tv;
87 ip->i_d.di_ctime.t_sec = tv.tv_sec;
88 ip->i_d.di_ctime.t_nsec = tv.tv_nsec;
89 }
90} 82}
91 83
92/* 84/*
@@ -125,7 +117,7 @@ xfs_trans_log_inode(
125 */ 117 */
126 if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) && 118 if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) &&
127 IS_I_VERSION(VFS_I(ip))) { 119 IS_I_VERSION(VFS_I(ip))) {
128 ip->i_d.di_changecount = ++VFS_I(ip)->i_version; 120 VFS_I(ip)->i_version++;
129 flags |= XFS_ILOG_CORE; 121 flags |= XFS_ILOG_CORE;
130 } 122 }
131 123