Merge branch 'xfs-gut-icdinode-4.6' into for-next
This commit is contained in:
Коммит
a2bbcb60ff
|
@ -912,7 +912,7 @@ xfs_bmap_local_to_extents(
|
|||
* We don't want to deal with the case of keeping inode data inline yet.
|
||||
* So sending the data fork of a regular inode is invalid.
|
||||
*/
|
||||
ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK));
|
||||
ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK));
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
|
||||
|
||||
|
@ -1079,7 +1079,7 @@ xfs_bmap_add_attrfork_local(
|
|||
if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
|
||||
return 0;
|
||||
|
||||
if (S_ISDIR(ip->i_d.di_mode)) {
|
||||
if (S_ISDIR(VFS_I(ip)->i_mode)) {
|
||||
memset(&dargs, 0, sizeof(dargs));
|
||||
dargs.geo = ip->i_mount->m_dir_geo;
|
||||
dargs.dp = ip;
|
||||
|
@ -1091,7 +1091,7 @@ xfs_bmap_add_attrfork_local(
|
|||
return xfs_dir2_sf_to_block(&dargs);
|
||||
}
|
||||
|
||||
if (S_ISLNK(ip->i_d.di_mode))
|
||||
if (S_ISLNK(VFS_I(ip)->i_mode))
|
||||
return xfs_bmap_local_to_extents(tp, ip, firstblock, 1,
|
||||
flags, XFS_DATA_FORK,
|
||||
xfs_symlink_local_to_remote);
|
||||
|
|
|
@ -176,7 +176,7 @@ xfs_dir_isempty(
|
|||
{
|
||||
xfs_dir2_sf_hdr_t *sfp;
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
if (dp->i_d.di_size == 0) /* might happen during shutdown. */
|
||||
return 1;
|
||||
if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
|
||||
|
@ -231,7 +231,7 @@ xfs_dir_init(
|
|||
struct xfs_da_args *args;
|
||||
int error;
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -266,7 +266,7 @@ xfs_dir_createname(
|
|||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
if (inum) {
|
||||
rval = xfs_dir_ino_validate(tp->t_mountp, inum);
|
||||
if (rval)
|
||||
|
@ -364,7 +364,7 @@ xfs_dir_lookup(
|
|||
int v; /* type-checking value */
|
||||
int lock_mode;
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
|
||||
|
||||
/*
|
||||
|
@ -443,7 +443,7 @@ xfs_dir_removename(
|
|||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
XFS_STATS_INC(dp->i_mount, xs_dir_remove);
|
||||
|
||||
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
|
||||
|
@ -505,7 +505,7 @@ xfs_dir_replace(
|
|||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
|
||||
rval = xfs_dir_ino_validate(tp->t_mountp, inum);
|
||||
if (rval)
|
||||
|
|
|
@ -195,28 +195,50 @@ xfs_imap_to_bp(
|
|||
}
|
||||
|
||||
void
|
||||
xfs_dinode_from_disk(
|
||||
xfs_icdinode_t *to,
|
||||
xfs_dinode_t *from)
|
||||
xfs_inode_from_disk(
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_dinode *from)
|
||||
{
|
||||
to->di_magic = be16_to_cpu(from->di_magic);
|
||||
to->di_mode = be16_to_cpu(from->di_mode);
|
||||
to->di_version = from ->di_version;
|
||||
struct xfs_icdinode *to = &ip->i_d;
|
||||
struct inode *inode = VFS_I(ip);
|
||||
|
||||
|
||||
/*
|
||||
* Convert v1 inodes immediately to v2 inode format as this is the
|
||||
* minimum inode version format we support in the rest of the code.
|
||||
*/
|
||||
to->di_version = from->di_version;
|
||||
if (to->di_version == 1) {
|
||||
set_nlink(inode, be16_to_cpu(from->di_onlink));
|
||||
to->di_projid_lo = 0;
|
||||
to->di_projid_hi = 0;
|
||||
to->di_version = 2;
|
||||
} else {
|
||||
set_nlink(inode, be32_to_cpu(from->di_nlink));
|
||||
to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
|
||||
to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
|
||||
}
|
||||
|
||||
to->di_format = from->di_format;
|
||||
to->di_onlink = be16_to_cpu(from->di_onlink);
|
||||
to->di_uid = be32_to_cpu(from->di_uid);
|
||||
to->di_gid = be32_to_cpu(from->di_gid);
|
||||
to->di_nlink = be32_to_cpu(from->di_nlink);
|
||||
to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
|
||||
to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
|
||||
memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
|
||||
to->di_flushiter = be16_to_cpu(from->di_flushiter);
|
||||
to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
|
||||
to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
|
||||
to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
|
||||
to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
|
||||
to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
|
||||
to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
|
||||
|
||||
/*
|
||||
* Time is signed, so need to convert to signed 32 bit before
|
||||
* storing in inode timestamp which may be 64 bit. Otherwise
|
||||
* a time before epoch is converted to a time long after epoch
|
||||
* on 64 bit systems.
|
||||
*/
|
||||
inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec);
|
||||
inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec);
|
||||
inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec);
|
||||
inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec);
|
||||
inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec);
|
||||
inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec);
|
||||
inode->i_generation = be32_to_cpu(from->di_gen);
|
||||
inode->i_mode = be16_to_cpu(from->di_mode);
|
||||
|
||||
to->di_size = be64_to_cpu(from->di_size);
|
||||
to->di_nblocks = be64_to_cpu(from->di_nblocks);
|
||||
to->di_extsize = be32_to_cpu(from->di_extsize);
|
||||
|
@ -227,42 +249,96 @@ xfs_dinode_from_disk(
|
|||
to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
|
||||
to->di_dmstate = be16_to_cpu(from->di_dmstate);
|
||||
to->di_flags = be16_to_cpu(from->di_flags);
|
||||
to->di_gen = be32_to_cpu(from->di_gen);
|
||||
|
||||
if (to->di_version == 3) {
|
||||
to->di_changecount = be64_to_cpu(from->di_changecount);
|
||||
inode->i_version = be64_to_cpu(from->di_changecount);
|
||||
to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
|
||||
to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
|
||||
to->di_flags2 = be64_to_cpu(from->di_flags2);
|
||||
to->di_ino = be64_to_cpu(from->di_ino);
|
||||
to->di_lsn = be64_to_cpu(from->di_lsn);
|
||||
memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
|
||||
uuid_copy(&to->di_uuid, &from->di_uuid);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xfs_dinode_to_disk(
|
||||
xfs_dinode_t *to,
|
||||
xfs_icdinode_t *from)
|
||||
xfs_inode_to_disk(
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_dinode *to,
|
||||
xfs_lsn_t lsn)
|
||||
{
|
||||
struct xfs_icdinode *from = &ip->i_d;
|
||||
struct inode *inode = VFS_I(ip);
|
||||
|
||||
to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
|
||||
to->di_onlink = 0;
|
||||
|
||||
to->di_version = from->di_version;
|
||||
to->di_format = from->di_format;
|
||||
to->di_uid = cpu_to_be32(from->di_uid);
|
||||
to->di_gid = cpu_to_be32(from->di_gid);
|
||||
to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
|
||||
to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
|
||||
|
||||
memset(to->di_pad, 0, sizeof(to->di_pad));
|
||||
to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec);
|
||||
to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
|
||||
to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec);
|
||||
to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
|
||||
to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec);
|
||||
to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
|
||||
to->di_nlink = cpu_to_be32(inode->i_nlink);
|
||||
to->di_gen = cpu_to_be32(inode->i_generation);
|
||||
to->di_mode = cpu_to_be16(inode->i_mode);
|
||||
|
||||
to->di_size = cpu_to_be64(from->di_size);
|
||||
to->di_nblocks = cpu_to_be64(from->di_nblocks);
|
||||
to->di_extsize = cpu_to_be32(from->di_extsize);
|
||||
to->di_nextents = cpu_to_be32(from->di_nextents);
|
||||
to->di_anextents = cpu_to_be16(from->di_anextents);
|
||||
to->di_forkoff = from->di_forkoff;
|
||||
to->di_aformat = from->di_aformat;
|
||||
to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
|
||||
to->di_dmstate = cpu_to_be16(from->di_dmstate);
|
||||
to->di_flags = cpu_to_be16(from->di_flags);
|
||||
|
||||
if (from->di_version == 3) {
|
||||
to->di_changecount = cpu_to_be64(inode->i_version);
|
||||
to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
|
||||
to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
|
||||
to->di_flags2 = cpu_to_be64(from->di_flags2);
|
||||
|
||||
to->di_ino = cpu_to_be64(ip->i_ino);
|
||||
to->di_lsn = cpu_to_be64(lsn);
|
||||
memset(to->di_pad2, 0, sizeof(to->di_pad2));
|
||||
uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
|
||||
to->di_flushiter = 0;
|
||||
} else {
|
||||
to->di_flushiter = cpu_to_be16(from->di_flushiter);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xfs_log_dinode_to_disk(
|
||||
struct xfs_log_dinode *from,
|
||||
struct xfs_dinode *to)
|
||||
{
|
||||
to->di_magic = cpu_to_be16(from->di_magic);
|
||||
to->di_mode = cpu_to_be16(from->di_mode);
|
||||
to->di_version = from ->di_version;
|
||||
to->di_version = from->di_version;
|
||||
to->di_format = from->di_format;
|
||||
to->di_onlink = cpu_to_be16(from->di_onlink);
|
||||
to->di_onlink = 0;
|
||||
to->di_uid = cpu_to_be32(from->di_uid);
|
||||
to->di_gid = cpu_to_be32(from->di_gid);
|
||||
to->di_nlink = cpu_to_be32(from->di_nlink);
|
||||
to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
|
||||
to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
|
||||
memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
|
||||
|
||||
to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
|
||||
to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
|
||||
to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
|
||||
to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
|
||||
to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
|
||||
to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
|
||||
|
||||
to->di_size = cpu_to_be64(from->di_size);
|
||||
to->di_nblocks = cpu_to_be64(from->di_nblocks);
|
||||
to->di_extsize = cpu_to_be32(from->di_extsize);
|
||||
|
@ -367,13 +443,10 @@ xfs_iread(
|
|||
!(mp->m_flags & XFS_MOUNT_IKEEP)) {
|
||||
/* initialise the on-disk inode core */
|
||||
memset(&ip->i_d, 0, sizeof(ip->i_d));
|
||||
ip->i_d.di_magic = XFS_DINODE_MAGIC;
|
||||
ip->i_d.di_gen = prandom_u32();
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
VFS_I(ip)->i_generation = prandom_u32();
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
||||
ip->i_d.di_version = 3;
|
||||
ip->i_d.di_ino = ip->i_ino;
|
||||
uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid);
|
||||
} else
|
||||
else
|
||||
ip->i_d.di_version = 2;
|
||||
return 0;
|
||||
}
|
||||
|
@ -403,7 +476,7 @@ xfs_iread(
|
|||
* Otherwise, just get the truly permanent information.
|
||||
*/
|
||||
if (dip->di_mode) {
|
||||
xfs_dinode_from_disk(&ip->i_d, dip);
|
||||
xfs_inode_from_disk(ip, dip);
|
||||
error = xfs_iformat_fork(ip, dip);
|
||||
if (error) {
|
||||
#ifdef DEBUG
|
||||
|
@ -417,16 +490,10 @@ xfs_iread(
|
|||
* Partial initialisation of the in-core inode. Just the bits
|
||||
* that xfs_ialloc won't overwrite or relies on being correct.
|
||||
*/
|
||||
ip->i_d.di_magic = be16_to_cpu(dip->di_magic);
|
||||
ip->i_d.di_version = dip->di_version;
|
||||
ip->i_d.di_gen = be32_to_cpu(dip->di_gen);
|
||||
VFS_I(ip)->i_generation = be32_to_cpu(dip->di_gen);
|
||||
ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter);
|
||||
|
||||
if (dip->di_version == 3) {
|
||||
ip->i_d.di_ino = be64_to_cpu(dip->di_ino);
|
||||
uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure to pull in the mode here as well in
|
||||
* case the inode is released without being used.
|
||||
|
@ -434,25 +501,10 @@ xfs_iread(
|
|||
* the inode is already free and not try to mess
|
||||
* with the uninitialized part of it.
|
||||
*/
|
||||
ip->i_d.di_mode = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Automatically convert version 1 inode formats in memory to version 2
|
||||
* inode format. If the inode is modified, it will get logged and
|
||||
* rewritten as a version 2 inode. We can do this because we set the
|
||||
* superblock feature bit for v2 inodes unconditionally during mount
|
||||
* and it means the reast of the code can assume the inode version is 2
|
||||
* or higher.
|
||||
*/
|
||||
if (ip->i_d.di_version == 1) {
|
||||
ip->i_d.di_version = 2;
|
||||
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
|
||||
ip->i_d.di_nlink = ip->i_d.di_onlink;
|
||||
ip->i_d.di_onlink = 0;
|
||||
xfs_set_projid(ip, 0);
|
||||
VFS_I(ip)->i_mode = 0;
|
||||
}
|
||||
|
||||
ASSERT(ip->i_d.di_version >= 2);
|
||||
ip->i_delayed_blks = 0;
|
||||
|
||||
/*
|
||||
|
|
|
@ -20,7 +20,36 @@
|
|||
|
||||
struct xfs_inode;
|
||||
struct xfs_dinode;
|
||||
struct xfs_icdinode;
|
||||
|
||||
/*
|
||||
* In memory representation of the XFS inode. This is held in the in-core struct
|
||||
* xfs_inode and represents the current on disk values but the structure is not
|
||||
* in on-disk format. That is, this structure is always translated to on-disk
|
||||
* format specific structures at the appropriate time.
|
||||
*/
|
||||
struct xfs_icdinode {
|
||||
__int8_t di_version; /* inode version */
|
||||
__int8_t di_format; /* format of di_c data */
|
||||
__uint16_t di_flushiter; /* incremented on flush */
|
||||
__uint32_t di_uid; /* owner's user id */
|
||||
__uint32_t di_gid; /* owner's group id */
|
||||
__uint16_t di_projid_lo; /* lower part of owner's project id */
|
||||
__uint16_t di_projid_hi; /* higher part of owner's project id */
|
||||
xfs_fsize_t di_size; /* number of bytes in file */
|
||||
xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
|
||||
xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
|
||||
xfs_extnum_t di_nextents; /* number of extents in data fork */
|
||||
xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
|
||||
__uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
|
||||
__int8_t di_aformat; /* format of attr fork's data */
|
||||
__uint32_t di_dmevmask; /* DMIG event mask */
|
||||
__uint16_t di_dmstate; /* DMIG state info */
|
||||
__uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
|
||||
|
||||
__uint64_t di_flags2; /* more random flags */
|
||||
|
||||
xfs_ictimestamp_t di_crtime; /* time created */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 *,
|
|||
int xfs_iread(struct xfs_mount *, struct xfs_trans *,
|
||||
struct xfs_inode *, uint);
|
||||
void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
|
||||
void xfs_dinode_to_disk(struct xfs_dinode *to, struct xfs_icdinode *from);
|
||||
void xfs_dinode_from_disk(struct xfs_icdinode *to, struct xfs_dinode *from);
|
||||
void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
|
||||
xfs_lsn_t lsn);
|
||||
void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
|
||||
void xfs_log_dinode_to_disk(struct xfs_log_dinode *from,
|
||||
struct xfs_dinode *to);
|
||||
|
||||
#if defined(DEBUG)
|
||||
void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
|
||||
|
|
|
@ -121,7 +121,7 @@ xfs_iformat_fork(
|
|||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
switch (ip->i_d.di_mode & S_IFMT) {
|
||||
switch (VFS_I(ip)->i_mode & S_IFMT) {
|
||||
case S_IFIFO:
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
|
|
|
@ -290,6 +290,7 @@ typedef struct xfs_inode_log_format_64 {
|
|||
__int32_t ilf_boffset; /* off of inode in buffer */
|
||||
} xfs_inode_log_format_64_t;
|
||||
|
||||
|
||||
/*
|
||||
* Flags for xfs_trans_log_inode flags field.
|
||||
*/
|
||||
|
@ -360,15 +361,15 @@ typedef struct xfs_ictimestamp {
|
|||
} xfs_ictimestamp_t;
|
||||
|
||||
/*
|
||||
* NOTE: This structure must be kept identical to struct xfs_dinode
|
||||
* except for the endianness annotations.
|
||||
* Define the format of the inode core that is logged. This structure must be
|
||||
* kept identical to struct xfs_dinode except for the endianness annotations.
|
||||
*/
|
||||
typedef struct xfs_icdinode {
|
||||
struct xfs_log_dinode {
|
||||
__uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
|
||||
__uint16_t di_mode; /* mode and type of file */
|
||||
__int8_t di_version; /* inode version */
|
||||
__int8_t di_format; /* format of di_c data */
|
||||
__uint16_t di_onlink; /* old number of links to file */
|
||||
__uint8_t di_pad3[2]; /* unused in v2/3 inodes */
|
||||
__uint32_t di_uid; /* owner's user id */
|
||||
__uint32_t di_gid; /* owner's group id */
|
||||
__uint32_t di_nlink; /* number of links to file */
|
||||
|
@ -407,13 +408,13 @@ typedef struct xfs_icdinode {
|
|||
uuid_t di_uuid; /* UUID of the filesystem */
|
||||
|
||||
/* structure must be padded to 64 bit alignment */
|
||||
} xfs_icdinode_t;
|
||||
};
|
||||
|
||||
static inline uint xfs_icdinode_size(int version)
|
||||
static inline uint xfs_log_dinode_size(int version)
|
||||
{
|
||||
if (version == 3)
|
||||
return sizeof(struct xfs_icdinode);
|
||||
return offsetof(struct xfs_icdinode, di_next_unlinked);
|
||||
return sizeof(struct xfs_log_dinode);
|
||||
return offsetof(struct xfs_log_dinode, di_next_unlinked);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1011,7 +1011,7 @@ xfs_rtfree_extent(
|
|||
mp->m_sb.sb_rextents) {
|
||||
if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM))
|
||||
mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
|
||||
*(__uint64_t *)&mp->m_rbmip->i_d.di_atime = 0;
|
||||
*(__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
|
||||
xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -823,7 +823,7 @@ bool
|
|||
xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
|
||||
{
|
||||
/* prealloc/delalloc exists only on regular files */
|
||||
if (!S_ISREG(ip->i_d.di_mode))
|
||||
if (!S_ISREG(VFS_I(ip)->i_mode))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
@ -1728,7 +1728,7 @@ xfs_swap_extents(
|
|||
xfs_lock_two_inodes(ip, tip, XFS_MMAPLOCK_EXCL);
|
||||
|
||||
/* Verify that both files have the same format */
|
||||
if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
|
||||
if ((VFS_I(ip)->i_mode & S_IFMT) != (VFS_I(tip)->i_mode & S_IFMT)) {
|
||||
error = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
|
@ -665,7 +665,7 @@ xfs_readdir(
|
|||
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
|
||||
return -EIO;
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
|
||||
XFS_STATS_INC(dp->i_mount, xs_dir_getdents);
|
||||
|
||||
args.dp = dp;
|
||||
|
|
|
@ -152,7 +152,7 @@ xfs_nfs_get_inode(
|
|||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
if (ip->i_d.di_gen != generation) {
|
||||
if (VFS_I(ip)->i_generation != generation) {
|
||||
IRELE(ip);
|
||||
return ERR_PTR(-ESTALE);
|
||||
}
|
||||
|
|
|
@ -156,9 +156,9 @@ xfs_update_prealloc_flags(
|
|||
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
||||
|
||||
if (!(flags & XFS_PREALLOC_INVISIBLE)) {
|
||||
ip->i_d.di_mode &= ~S_ISUID;
|
||||
if (ip->i_d.di_mode & S_IXGRP)
|
||||
ip->i_d.di_mode &= ~S_ISGID;
|
||||
VFS_I(ip)->i_mode &= ~S_ISUID;
|
||||
if (VFS_I(ip)->i_mode & S_IXGRP)
|
||||
VFS_I(ip)->i_mode &= ~S_ISGID;
|
||||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ xfs_filestream_pick_ag(
|
|||
xfs_agnumber_t ag, max_ag = NULLAGNUMBER;
|
||||
int err, trylock, nscan;
|
||||
|
||||
ASSERT(S_ISDIR(ip->i_d.di_mode));
|
||||
ASSERT(S_ISDIR(VFS_I(ip)->i_mode));
|
||||
|
||||
/* 2% of an AG's blocks must be free for it to be chosen. */
|
||||
minfree = mp->m_sb.sb_agblocks / 50;
|
||||
|
@ -319,7 +319,7 @@ xfs_filestream_lookup_ag(
|
|||
xfs_agnumber_t startag, ag = NULLAGNUMBER;
|
||||
struct xfs_mru_cache_elem *mru;
|
||||
|
||||
ASSERT(S_ISREG(ip->i_d.di_mode));
|
||||
ASSERT(S_ISREG(VFS_I(ip)->i_mode));
|
||||
|
||||
pip = xfs_filestream_get_parent(ip);
|
||||
if (!pip)
|
||||
|
|
|
@ -63,6 +63,9 @@ xfs_inode_alloc(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* VFS doesn't initialise i_mode! */
|
||||
VFS_I(ip)->i_mode = 0;
|
||||
|
||||
XFS_STATS_INC(mp, vn_active);
|
||||
ASSERT(atomic_read(&ip->i_pincount) == 0);
|
||||
ASSERT(!spin_is_locked(&ip->i_flags_lock));
|
||||
|
@ -79,7 +82,7 @@ xfs_inode_alloc(
|
|||
memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
|
||||
ip->i_flags = 0;
|
||||
ip->i_delayed_blks = 0;
|
||||
memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
|
||||
memset(&ip->i_d, 0, sizeof(ip->i_d));
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
@ -98,7 +101,7 @@ void
|
|||
xfs_inode_free(
|
||||
struct xfs_inode *ip)
|
||||
{
|
||||
switch (ip->i_d.di_mode & S_IFMT) {
|
||||
switch (VFS_I(ip)->i_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
case S_IFDIR:
|
||||
case S_IFLNK:
|
||||
|
@ -134,6 +137,34 @@ xfs_inode_free(
|
|||
call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* When we recycle a reclaimable inode, we need to re-initialise the VFS inode
|
||||
* part of the structure. This is made more complex by the fact we store
|
||||
* information about the on-disk values in the VFS inode and so we can't just
|
||||
* overwrite the values unconditionally. Hence we save the parameters we
|
||||
* need to retain across reinitialisation, and rewrite them into the VFS inode
|
||||
* after reinitialisation even if it fails.
|
||||
*/
|
||||
static int
|
||||
xfs_reinit_inode(
|
||||
struct xfs_mount *mp,
|
||||
struct inode *inode)
|
||||
{
|
||||
int error;
|
||||
uint32_t nlink = inode->i_nlink;
|
||||
uint32_t generation = inode->i_generation;
|
||||
uint64_t version = inode->i_version;
|
||||
umode_t mode = inode->i_mode;
|
||||
|
||||
error = inode_init_always(mp->m_super, inode);
|
||||
|
||||
set_nlink(inode, nlink);
|
||||
inode->i_generation = generation;
|
||||
inode->i_version = version;
|
||||
inode->i_mode = mode;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the validity of the inode we just found it the cache
|
||||
*/
|
||||
|
@ -185,7 +216,7 @@ xfs_iget_cache_hit(
|
|||
/*
|
||||
* If lookup is racing with unlink return an error immediately.
|
||||
*/
|
||||
if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) {
|
||||
if (VFS_I(ip)->i_mode == 0 && !(flags & XFS_IGET_CREATE)) {
|
||||
error = -ENOENT;
|
||||
goto out_error;
|
||||
}
|
||||
|
@ -208,7 +239,7 @@ xfs_iget_cache_hit(
|
|||
spin_unlock(&ip->i_flags_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
error = inode_init_always(mp->m_super, inode);
|
||||
error = xfs_reinit_inode(mp, inode);
|
||||
if (error) {
|
||||
/*
|
||||
* Re-initializing the inode failed, and we are in deep
|
||||
|
@ -295,7 +326,7 @@ xfs_iget_cache_miss(
|
|||
|
||||
trace_xfs_iget_miss(ip);
|
||||
|
||||
if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
|
||||
if ((VFS_I(ip)->i_mode == 0) && !(flags & XFS_IGET_CREATE)) {
|
||||
error = -ENOENT;
|
||||
goto out_destroy;
|
||||
}
|
||||
|
@ -444,7 +475,7 @@ again:
|
|||
* If we have a real type for an on-disk inode, we can setup the inode
|
||||
* now. If it's a new inode being created, xfs_ialloc will handle it.
|
||||
*/
|
||||
if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0)
|
||||
if (xfs_iflags_test(ip, XFS_INEW) && VFS_I(ip)->i_mode != 0)
|
||||
xfs_setup_existing_inode(ip);
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -57,9 +57,9 @@ kmem_zone_t *xfs_inode_zone;
|
|||
*/
|
||||
#define XFS_ITRUNC_MAX_EXTENTS 2
|
||||
|
||||
STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);
|
||||
|
||||
STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *);
|
||||
STATIC int xfs_iflush_int(struct xfs_inode *, struct xfs_buf *);
|
||||
STATIC int xfs_iunlink(struct xfs_trans *, struct xfs_inode *);
|
||||
STATIC int xfs_iunlink_remove(struct xfs_trans *, struct xfs_inode *);
|
||||
|
||||
/*
|
||||
* helper function to extract extent size hint from inode
|
||||
|
@ -766,6 +766,7 @@ xfs_ialloc(
|
|||
uint flags;
|
||||
int error;
|
||||
struct timespec tv;
|
||||
struct inode *inode;
|
||||
|
||||
/*
|
||||
* Call the space management code to pick
|
||||
|
@ -791,6 +792,7 @@ xfs_ialloc(
|
|||
if (error)
|
||||
return error;
|
||||
ASSERT(ip != NULL);
|
||||
inode = VFS_I(ip);
|
||||
|
||||
/*
|
||||
* We always convert v1 inodes to v2 now - we only support filesystems
|
||||
|
@ -800,20 +802,16 @@ xfs_ialloc(
|
|||
if (ip->i_d.di_version == 1)
|
||||
ip->i_d.di_version = 2;
|
||||
|
||||
ip->i_d.di_mode = mode;
|
||||
ip->i_d.di_onlink = 0;
|
||||
ip->i_d.di_nlink = nlink;
|
||||
ASSERT(ip->i_d.di_nlink == nlink);
|
||||
inode->i_mode = mode;
|
||||
set_nlink(inode, nlink);
|
||||
ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid());
|
||||
ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid());
|
||||
xfs_set_projid(ip, prid);
|
||||
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
|
||||
|
||||
if (pip && XFS_INHERIT_GID(pip)) {
|
||||
ip->i_d.di_gid = pip->i_d.di_gid;
|
||||
if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) {
|
||||
ip->i_d.di_mode |= S_ISGID;
|
||||
}
|
||||
if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode))
|
||||
inode->i_mode |= S_ISGID;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -822,38 +820,29 @@ xfs_ialloc(
|
|||
* (and only if the irix_sgid_inherit compatibility variable is set).
|
||||
*/
|
||||
if ((irix_sgid_inherit) &&
|
||||
(ip->i_d.di_mode & S_ISGID) &&
|
||||
(!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) {
|
||||
ip->i_d.di_mode &= ~S_ISGID;
|
||||
}
|
||||
(inode->i_mode & S_ISGID) &&
|
||||
(!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid))))
|
||||
inode->i_mode &= ~S_ISGID;
|
||||
|
||||
ip->i_d.di_size = 0;
|
||||
ip->i_d.di_nextents = 0;
|
||||
ASSERT(ip->i_d.di_nblocks == 0);
|
||||
|
||||
tv = current_fs_time(mp->m_super);
|
||||
ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
|
||||
ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
|
||||
ip->i_d.di_atime = ip->i_d.di_mtime;
|
||||
ip->i_d.di_ctime = ip->i_d.di_mtime;
|
||||
inode->i_mtime = tv;
|
||||
inode->i_atime = tv;
|
||||
inode->i_ctime = tv;
|
||||
|
||||
/*
|
||||
* di_gen will have been taken care of in xfs_iread.
|
||||
*/
|
||||
ip->i_d.di_extsize = 0;
|
||||
ip->i_d.di_dmevmask = 0;
|
||||
ip->i_d.di_dmstate = 0;
|
||||
ip->i_d.di_flags = 0;
|
||||
|
||||
if (ip->i_d.di_version == 3) {
|
||||
ASSERT(ip->i_d.di_ino == ino);
|
||||
ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));
|
||||
ip->i_d.di_crc = 0;
|
||||
ip->i_d.di_changecount = 1;
|
||||
ip->i_d.di_lsn = 0;
|
||||
inode->i_version = 1;
|
||||
ip->i_d.di_flags2 = 0;
|
||||
memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2));
|
||||
ip->i_d.di_crtime = ip->i_d.di_mtime;
|
||||
ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec;
|
||||
ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1092,35 +1081,24 @@ xfs_dir_ialloc(
|
|||
}
|
||||
|
||||
/*
|
||||
* Decrement the link count on an inode & log the change.
|
||||
* If this causes the link count to go to zero, initiate the
|
||||
* logging activity required to truncate a file.
|
||||
* Decrement the link count on an inode & log the change. If this causes the
|
||||
* link count to go to zero, move the inode to AGI unlinked list so that it can
|
||||
* be freed when the last active reference goes away via xfs_inactive().
|
||||
*/
|
||||
int /* error */
|
||||
xfs_droplink(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
int error;
|
||||
|
||||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
||||
|
||||
ASSERT (ip->i_d.di_nlink > 0);
|
||||
ip->i_d.di_nlink--;
|
||||
drop_nlink(VFS_I(ip));
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
|
||||
error = 0;
|
||||
if (ip->i_d.di_nlink == 0) {
|
||||
/*
|
||||
* We're dropping the last link to this file.
|
||||
* Move the on-disk inode to the AGI unlinked list.
|
||||
* From xfs_inactive() we will pull the inode from
|
||||
* the list and free it.
|
||||
*/
|
||||
error = xfs_iunlink(tp, ip);
|
||||
}
|
||||
return error;
|
||||
if (VFS_I(ip)->i_nlink)
|
||||
return 0;
|
||||
|
||||
return xfs_iunlink(tp, ip);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1134,8 +1112,6 @@ xfs_bumplink(
|
|||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
||||
|
||||
ASSERT(ip->i_d.di_version > 1);
|
||||
ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
|
||||
ip->i_d.di_nlink++;
|
||||
inc_nlink(VFS_I(ip));
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
return 0;
|
||||
|
@ -1393,7 +1369,6 @@ xfs_create_tmpfile(
|
|||
*/
|
||||
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
|
||||
|
||||
ip->i_d.di_nlink--;
|
||||
error = xfs_iunlink(tp, ip);
|
||||
if (error)
|
||||
goto out_trans_cancel;
|
||||
|
@ -1444,7 +1419,7 @@ xfs_link(
|
|||
|
||||
trace_xfs_link(tdp, target_name);
|
||||
|
||||
ASSERT(!S_ISDIR(sip->i_d.di_mode));
|
||||
ASSERT(!S_ISDIR(VFS_I(sip)->i_mode));
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return -EIO;
|
||||
|
@ -1492,7 +1467,10 @@ xfs_link(
|
|||
|
||||
xfs_bmap_init(&free_list, &first_block);
|
||||
|
||||
if (sip->i_d.di_nlink == 0) {
|
||||
/*
|
||||
* Handle initial link state of O_TMPFILE inode
|
||||
*/
|
||||
if (VFS_I(sip)->i_nlink == 0) {
|
||||
error = xfs_iunlink_remove(tp, sip);
|
||||
if (error)
|
||||
goto error_return;
|
||||
|
@ -1648,7 +1626,7 @@ xfs_release(
|
|||
xfs_mount_t *mp = ip->i_mount;
|
||||
int error;
|
||||
|
||||
if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0))
|
||||
if (!S_ISREG(VFS_I(ip)->i_mode) || (VFS_I(ip)->i_mode == 0))
|
||||
return 0;
|
||||
|
||||
/* If this is a read-only mount, don't do this (would generate I/O) */
|
||||
|
@ -1679,7 +1657,7 @@ xfs_release(
|
|||
}
|
||||
}
|
||||
|
||||
if (ip->i_d.di_nlink == 0)
|
||||
if (VFS_I(ip)->i_nlink == 0)
|
||||
return 0;
|
||||
|
||||
if (xfs_can_free_eofblocks(ip, false)) {
|
||||
|
@ -1883,7 +1861,7 @@ xfs_inactive(
|
|||
* If the inode is already free, then there can be nothing
|
||||
* to clean up here.
|
||||
*/
|
||||
if (ip->i_d.di_mode == 0) {
|
||||
if (VFS_I(ip)->i_mode == 0) {
|
||||
ASSERT(ip->i_df.if_real_bytes == 0);
|
||||
ASSERT(ip->i_df.if_broot_bytes == 0);
|
||||
return;
|
||||
|
@ -1895,7 +1873,7 @@ xfs_inactive(
|
|||
if (mp->m_flags & XFS_MOUNT_RDONLY)
|
||||
return;
|
||||
|
||||
if (ip->i_d.di_nlink != 0) {
|
||||
if (VFS_I(ip)->i_nlink != 0) {
|
||||
/*
|
||||
* force is true because we are evicting an inode from the
|
||||
* cache. Post-eof blocks must be freed, lest we end up with
|
||||
|
@ -1907,7 +1885,7 @@ xfs_inactive(
|
|||
return;
|
||||
}
|
||||
|
||||
if (S_ISREG(ip->i_d.di_mode) &&
|
||||
if (S_ISREG(VFS_I(ip)->i_mode) &&
|
||||
(ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 ||
|
||||
ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0))
|
||||
truncate = 1;
|
||||
|
@ -1916,7 +1894,7 @@ xfs_inactive(
|
|||
if (error)
|
||||
return;
|
||||
|
||||
if (S_ISLNK(ip->i_d.di_mode))
|
||||
if (S_ISLNK(VFS_I(ip)->i_mode))
|
||||
error = xfs_inactive_symlink(ip);
|
||||
else if (truncate)
|
||||
error = xfs_inactive_truncate(ip);
|
||||
|
@ -1952,16 +1930,21 @@ xfs_inactive(
|
|||
}
|
||||
|
||||
/*
|
||||
* This is called when the inode's link count goes to 0.
|
||||
* We place the on-disk inode on a list in the AGI. It
|
||||
* will be pulled from this list when the inode is freed.
|
||||
* This is called when the inode's link count goes to 0 or we are creating a
|
||||
* tmpfile via O_TMPFILE. In the case of a tmpfile, @ignore_linkcount will be
|
||||
* set to true as the link count is dropped to zero by the VFS after we've
|
||||
* created the file successfully, so we have to add it to the unlinked list
|
||||
* while the link count is non-zero.
|
||||
*
|
||||
* We place the on-disk inode on a list in the AGI. It will be pulled from this
|
||||
* list when the inode is freed.
|
||||
*/
|
||||
int
|
||||
STATIC int
|
||||
xfs_iunlink(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *ip)
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *ip)
|
||||
{
|
||||
xfs_mount_t *mp;
|
||||
xfs_mount_t *mp = tp->t_mountp;
|
||||
xfs_agi_t *agi;
|
||||
xfs_dinode_t *dip;
|
||||
xfs_buf_t *agibp;
|
||||
|
@ -1971,10 +1954,7 @@ xfs_iunlink(
|
|||
int offset;
|
||||
int error;
|
||||
|
||||
ASSERT(ip->i_d.di_nlink == 0);
|
||||
ASSERT(ip->i_d.di_mode != 0);
|
||||
|
||||
mp = tp->t_mountp;
|
||||
ASSERT(VFS_I(ip)->i_mode != 0);
|
||||
|
||||
/*
|
||||
* Get the agi buffer first. It ensures lock ordering
|
||||
|
@ -2412,10 +2392,10 @@ xfs_ifree(
|
|||
struct xfs_icluster xic = { 0 };
|
||||
|
||||
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
||||
ASSERT(ip->i_d.di_nlink == 0);
|
||||
ASSERT(VFS_I(ip)->i_nlink == 0);
|
||||
ASSERT(ip->i_d.di_nextents == 0);
|
||||
ASSERT(ip->i_d.di_anextents == 0);
|
||||
ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode));
|
||||
ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
|
||||
ASSERT(ip->i_d.di_nblocks == 0);
|
||||
|
||||
/*
|
||||
|
@ -2429,7 +2409,7 @@ xfs_ifree(
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
ip->i_d.di_mode = 0; /* mark incore inode as free */
|
||||
VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
|
||||
ip->i_d.di_flags = 0;
|
||||
ip->i_d.di_dmevmask = 0;
|
||||
ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */
|
||||
|
@ -2439,7 +2419,7 @@ xfs_ifree(
|
|||
* Bump the generation count so no one will be confused
|
||||
* by reincarnations of this inode.
|
||||
*/
|
||||
ip->i_d.di_gen++;
|
||||
VFS_I(ip)->i_generation++;
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
|
||||
if (xic.deleted)
|
||||
|
@ -2526,7 +2506,7 @@ xfs_remove(
|
|||
{
|
||||
xfs_mount_t *mp = dp->i_mount;
|
||||
xfs_trans_t *tp = NULL;
|
||||
int is_dir = S_ISDIR(ip->i_d.di_mode);
|
||||
int is_dir = S_ISDIR(VFS_I(ip)->i_mode);
|
||||
int error = 0;
|
||||
xfs_bmap_free_t free_list;
|
||||
xfs_fsblock_t first_block;
|
||||
|
@ -2580,8 +2560,8 @@ xfs_remove(
|
|||
* If we're removing a directory perform some additional validation.
|
||||
*/
|
||||
if (is_dir) {
|
||||
ASSERT(ip->i_d.di_nlink >= 2);
|
||||
if (ip->i_d.di_nlink != 2) {
|
||||
ASSERT(VFS_I(ip)->i_nlink >= 2);
|
||||
if (VFS_I(ip)->i_nlink != 2) {
|
||||
error = -ENOTEMPTY;
|
||||
goto out_trans_cancel;
|
||||
}
|
||||
|
@ -2771,7 +2751,7 @@ xfs_cross_rename(
|
|||
if (dp1 != dp2) {
|
||||
dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
|
||||
|
||||
if (S_ISDIR(ip2->i_d.di_mode)) {
|
||||
if (S_ISDIR(VFS_I(ip2)->i_mode)) {
|
||||
error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot,
|
||||
dp1->i_ino, first_block,
|
||||
free_list, spaceres);
|
||||
|
@ -2779,7 +2759,7 @@ xfs_cross_rename(
|
|||
goto out_trans_abort;
|
||||
|
||||
/* transfer ip2 ".." reference to dp1 */
|
||||
if (!S_ISDIR(ip1->i_d.di_mode)) {
|
||||
if (!S_ISDIR(VFS_I(ip1)->i_mode)) {
|
||||
error = xfs_droplink(tp, dp2);
|
||||
if (error)
|
||||
goto out_trans_abort;
|
||||
|
@ -2798,7 +2778,7 @@ xfs_cross_rename(
|
|||
ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
|
||||
}
|
||||
|
||||
if (S_ISDIR(ip1->i_d.di_mode)) {
|
||||
if (S_ISDIR(VFS_I(ip1)->i_mode)) {
|
||||
error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot,
|
||||
dp2->i_ino, first_block,
|
||||
free_list, spaceres);
|
||||
|
@ -2806,7 +2786,7 @@ xfs_cross_rename(
|
|||
goto out_trans_abort;
|
||||
|
||||
/* transfer ip1 ".." reference to dp2 */
|
||||
if (!S_ISDIR(ip2->i_d.di_mode)) {
|
||||
if (!S_ISDIR(VFS_I(ip2)->i_mode)) {
|
||||
error = xfs_droplink(tp, dp1);
|
||||
if (error)
|
||||
goto out_trans_abort;
|
||||
|
@ -2903,7 +2883,7 @@ xfs_rename(
|
|||
struct xfs_inode *inodes[__XFS_SORT_INODES];
|
||||
int num_inodes = __XFS_SORT_INODES;
|
||||
bool new_parent = (src_dp != target_dp);
|
||||
bool src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
|
||||
bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode);
|
||||
int spaceres;
|
||||
int error;
|
||||
|
||||
|
@ -3032,12 +3012,12 @@ xfs_rename(
|
|||
* target and source are directories and that target can be
|
||||
* destroyed, or that neither is a directory.
|
||||
*/
|
||||
if (S_ISDIR(target_ip->i_d.di_mode)) {
|
||||
if (S_ISDIR(VFS_I(target_ip)->i_mode)) {
|
||||
/*
|
||||
* Make sure target dir is empty.
|
||||
*/
|
||||
if (!(xfs_dir_isempty(target_ip)) ||
|
||||
(target_ip->i_d.di_nlink > 2)) {
|
||||
(VFS_I(target_ip)->i_nlink > 2)) {
|
||||
error = -EEXIST;
|
||||
goto out_trans_cancel;
|
||||
}
|
||||
|
@ -3144,7 +3124,7 @@ xfs_rename(
|
|||
* intermediate state on disk.
|
||||
*/
|
||||
if (wip) {
|
||||
ASSERT(VFS_I(wip)->i_nlink == 0 && wip->i_d.di_nlink == 0);
|
||||
ASSERT(VFS_I(wip)->i_nlink == 0);
|
||||
error = xfs_bumplink(tp, wip);
|
||||
if (error)
|
||||
goto out_bmap_cancel;
|
||||
|
@ -3462,14 +3442,7 @@ xfs_iflush_int(
|
|||
__func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip);
|
||||
goto corrupt_out;
|
||||
}
|
||||
if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC,
|
||||
mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) {
|
||||
xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
|
||||
"%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x",
|
||||
__func__, ip->i_ino, ip, ip->i_d.di_magic);
|
||||
goto corrupt_out;
|
||||
}
|
||||
if (S_ISREG(ip->i_d.di_mode)) {
|
||||
if (S_ISREG(VFS_I(ip)->i_mode)) {
|
||||
if (XFS_TEST_ERROR(
|
||||
(ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
(ip->i_d.di_format != XFS_DINODE_FMT_BTREE),
|
||||
|
@ -3479,7 +3452,7 @@ xfs_iflush_int(
|
|||
__func__, ip->i_ino, ip);
|
||||
goto corrupt_out;
|
||||
}
|
||||
} else if (S_ISDIR(ip->i_d.di_mode)) {
|
||||
} else if (S_ISDIR(VFS_I(ip)->i_mode)) {
|
||||
if (XFS_TEST_ERROR(
|
||||
(ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
(ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
|
||||
|
@ -3523,12 +3496,11 @@ xfs_iflush_int(
|
|||
ip->i_d.di_flushiter++;
|
||||
|
||||
/*
|
||||
* Copy the dirty parts of the inode into the on-disk
|
||||
* inode. We always copy out the core of the inode,
|
||||
* because if the inode is dirty at all the core must
|
||||
* be.
|
||||
* Copy the dirty parts of the inode into the on-disk inode. We always
|
||||
* copy out the core of the inode, because if the inode is dirty at all
|
||||
* the core must be.
|
||||
*/
|
||||
xfs_dinode_to_disk(dip, &ip->i_d);
|
||||
xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn);
|
||||
|
||||
/* Wrap, we never let the log put out DI_MAX_FLUSH */
|
||||
if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
|
||||
|
@ -3580,10 +3552,6 @@ xfs_iflush_int(
|
|||
*/
|
||||
xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item);
|
||||
|
||||
/* update the lsn in the on disk inode if required */
|
||||
if (ip->i_d.di_version == 3)
|
||||
dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn);
|
||||
|
||||
/* generate the checksum. */
|
||||
xfs_dinode_calc_crc(mp, dip);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef struct xfs_inode {
|
|||
unsigned long i_flags; /* see defined flags below */
|
||||
unsigned int i_delayed_blks; /* count of delay alloc blks */
|
||||
|
||||
xfs_icdinode_t i_d; /* most of ondisk inode */
|
||||
struct xfs_icdinode i_d; /* most of ondisk inode */
|
||||
|
||||
/* VFS inode */
|
||||
struct inode i_vnode; /* embedded VFS inode */
|
||||
|
@ -88,7 +88,7 @@ static inline struct inode *VFS_I(struct xfs_inode *ip)
|
|||
*/
|
||||
static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
|
||||
{
|
||||
if (S_ISREG(ip->i_d.di_mode))
|
||||
if (S_ISREG(VFS_I(ip)->i_mode))
|
||||
return i_size_read(VFS_I(ip));
|
||||
return ip->i_d.di_size;
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ static inline int xfs_isiflocked(struct xfs_inode *ip)
|
|||
*/
|
||||
#define XFS_INHERIT_GID(pip) \
|
||||
(((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
|
||||
((pip)->i_d.di_mode & S_ISGID))
|
||||
(VFS_I(pip)->i_mode & S_ISGID))
|
||||
|
||||
int xfs_release(struct xfs_inode *ip);
|
||||
void xfs_inactive(struct xfs_inode *ip);
|
||||
|
@ -405,8 +405,6 @@ int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
|
|||
struct xfs_bmap_free *);
|
||||
int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *,
|
||||
int, xfs_fsize_t);
|
||||
int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
|
||||
|
||||
void xfs_iext_realloc(xfs_inode_t *, int, int);
|
||||
|
||||
void xfs_iunpin_wait(xfs_inode_t *);
|
||||
|
|
|
@ -135,7 +135,7 @@ xfs_inode_item_size(
|
|||
|
||||
*nvecs += 2;
|
||||
*nbytes += sizeof(struct xfs_inode_log_format) +
|
||||
xfs_icdinode_size(ip->i_d.di_version);
|
||||
xfs_log_dinode_size(ip->i_d.di_version);
|
||||
|
||||
xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
|
||||
if (XFS_IFORK_Q(ip))
|
||||
|
@ -322,6 +322,81 @@ xfs_inode_item_format_attr_fork(
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xfs_inode_to_log_dinode(
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_log_dinode *to,
|
||||
xfs_lsn_t lsn)
|
||||
{
|
||||
struct xfs_icdinode *from = &ip->i_d;
|
||||
struct inode *inode = VFS_I(ip);
|
||||
|
||||
to->di_magic = XFS_DINODE_MAGIC;
|
||||
|
||||
to->di_version = from->di_version;
|
||||
to->di_format = from->di_format;
|
||||
to->di_uid = from->di_uid;
|
||||
to->di_gid = from->di_gid;
|
||||
to->di_projid_lo = from->di_projid_lo;
|
||||
to->di_projid_hi = from->di_projid_hi;
|
||||
|
||||
memset(to->di_pad, 0, sizeof(to->di_pad));
|
||||
memset(to->di_pad3, 0, sizeof(to->di_pad3));
|
||||
to->di_atime.t_sec = inode->i_atime.tv_sec;
|
||||
to->di_atime.t_nsec = inode->i_atime.tv_nsec;
|
||||
to->di_mtime.t_sec = inode->i_mtime.tv_sec;
|
||||
to->di_mtime.t_nsec = inode->i_mtime.tv_nsec;
|
||||
to->di_ctime.t_sec = inode->i_ctime.tv_sec;
|
||||
to->di_ctime.t_nsec = inode->i_ctime.tv_nsec;
|
||||
to->di_nlink = inode->i_nlink;
|
||||
to->di_gen = inode->i_generation;
|
||||
to->di_mode = inode->i_mode;
|
||||
|
||||
to->di_size = from->di_size;
|
||||
to->di_nblocks = from->di_nblocks;
|
||||
to->di_extsize = from->di_extsize;
|
||||
to->di_nextents = from->di_nextents;
|
||||
to->di_anextents = from->di_anextents;
|
||||
to->di_forkoff = from->di_forkoff;
|
||||
to->di_aformat = from->di_aformat;
|
||||
to->di_dmevmask = from->di_dmevmask;
|
||||
to->di_dmstate = from->di_dmstate;
|
||||
to->di_flags = from->di_flags;
|
||||
|
||||
if (from->di_version == 3) {
|
||||
to->di_changecount = inode->i_version;
|
||||
to->di_crtime.t_sec = from->di_crtime.t_sec;
|
||||
to->di_crtime.t_nsec = from->di_crtime.t_nsec;
|
||||
to->di_flags2 = from->di_flags2;
|
||||
|
||||
to->di_ino = ip->i_ino;
|
||||
to->di_lsn = lsn;
|
||||
memset(to->di_pad2, 0, sizeof(to->di_pad2));
|
||||
uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
|
||||
to->di_flushiter = 0;
|
||||
} else {
|
||||
to->di_flushiter = from->di_flushiter;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format the inode core. Current timestamp data is only in the VFS inode
|
||||
* fields, so we need to grab them from there. Hence rather than just copying
|
||||
* the XFS inode core structure, format the fields directly into the iovec.
|
||||
*/
|
||||
static void
|
||||
xfs_inode_item_format_core(
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_log_vec *lv,
|
||||
struct xfs_log_iovec **vecp)
|
||||
{
|
||||
struct xfs_log_dinode *dic;
|
||||
|
||||
dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
|
||||
xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn);
|
||||
xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version));
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called to fill in the vector of log iovecs for the given inode
|
||||
* log item. It fills the first item with an inode log format structure,
|
||||
|
@ -351,10 +426,7 @@ xfs_inode_item_format(
|
|||
ilf->ilf_size = 2; /* format + core */
|
||||
xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format));
|
||||
|
||||
xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE,
|
||||
&ip->i_d,
|
||||
xfs_icdinode_size(ip->i_d.di_version));
|
||||
|
||||
xfs_inode_item_format_core(ip, lv, &vecp);
|
||||
xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
|
||||
if (XFS_IFORK_Q(ip)) {
|
||||
xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
|
||||
|
|
|
@ -114,7 +114,7 @@ xfs_find_handle(
|
|||
handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
|
||||
sizeof(handle.ha_fid.fid_len);
|
||||
handle.ha_fid.fid_pad = 0;
|
||||
handle.ha_fid.fid_gen = ip->i_d.di_gen;
|
||||
handle.ha_fid.fid_gen = inode->i_generation;
|
||||
handle.ha_fid.fid_ino = ip->i_ino;
|
||||
|
||||
hsize = XFS_HSIZE(handle);
|
||||
|
@ -963,7 +963,7 @@ xfs_set_diflags(
|
|||
di_flags |= XFS_DIFLAG_NODEFRAG;
|
||||
if (xflags & FS_XFLAG_FILESTREAM)
|
||||
di_flags |= XFS_DIFLAG_FILESTREAM;
|
||||
if (S_ISDIR(ip->i_d.di_mode)) {
|
||||
if (S_ISDIR(VFS_I(ip)->i_mode)) {
|
||||
if (xflags & FS_XFLAG_RTINHERIT)
|
||||
di_flags |= XFS_DIFLAG_RTINHERIT;
|
||||
if (xflags & FS_XFLAG_NOSYMLINKS)
|
||||
|
@ -972,7 +972,7 @@ xfs_set_diflags(
|
|||
di_flags |= XFS_DIFLAG_EXTSZINHERIT;
|
||||
if (xflags & FS_XFLAG_PROJINHERIT)
|
||||
di_flags |= XFS_DIFLAG_PROJINHERIT;
|
||||
} else if (S_ISREG(ip->i_d.di_mode)) {
|
||||
} else if (S_ISREG(VFS_I(ip)->i_mode)) {
|
||||
if (xflags & FS_XFLAG_REALTIME)
|
||||
di_flags |= XFS_DIFLAG_REALTIME;
|
||||
if (xflags & FS_XFLAG_EXTSIZE)
|
||||
|
@ -1128,14 +1128,14 @@ xfs_ioctl_setattr_check_extsize(
|
|||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode))
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
|
||||
!S_ISDIR(ip->i_d.di_mode))
|
||||
!S_ISDIR(VFS_I(ip)->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (S_ISREG(ip->i_d.di_mode) && ip->i_d.di_nextents &&
|
||||
if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents &&
|
||||
((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1256,9 +1256,9 @@ xfs_ioctl_setattr(
|
|||
* successful return from chown()
|
||||
*/
|
||||
|
||||
if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
|
||||
if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
|
||||
!capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
|
||||
ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
|
||||
VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
|
||||
|
||||
/* Change the ownerships and register project quota modifications */
|
||||
if (xfs_get_projid(ip) != fa->fsx_projid) {
|
||||
|
|
|
@ -459,8 +459,8 @@ xfs_vn_getattr(
|
|||
|
||||
stat->size = XFS_ISIZE(ip);
|
||||
stat->dev = inode->i_sb->s_dev;
|
||||
stat->mode = ip->i_d.di_mode;
|
||||
stat->nlink = ip->i_d.di_nlink;
|
||||
stat->mode = inode->i_mode;
|
||||
stat->nlink = inode->i_nlink;
|
||||
stat->uid = inode->i_uid;
|
||||
stat->gid = inode->i_gid;
|
||||
stat->ino = ip->i_ino;
|
||||
|
@ -506,9 +506,6 @@ xfs_setattr_mode(
|
|||
|
||||
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
||||
|
||||
ip->i_d.di_mode &= S_IFMT;
|
||||
ip->i_d.di_mode |= mode & ~S_IFMT;
|
||||
|
||||
inode->i_mode &= S_IFMT;
|
||||
inode->i_mode |= mode & ~S_IFMT;
|
||||
}
|
||||
|
@ -522,21 +519,12 @@ xfs_setattr_time(
|
|||
|
||||
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
||||
|
||||
if (iattr->ia_valid & ATTR_ATIME) {
|
||||
if (iattr->ia_valid & ATTR_ATIME)
|
||||
inode->i_atime = iattr->ia_atime;
|
||||
ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
|
||||
ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
|
||||
}
|
||||
if (iattr->ia_valid & ATTR_CTIME) {
|
||||
if (iattr->ia_valid & ATTR_CTIME)
|
||||
inode->i_ctime = iattr->ia_ctime;
|
||||
ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
|
||||
ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
|
||||
}
|
||||
if (iattr->ia_valid & ATTR_MTIME) {
|
||||
if (iattr->ia_valid & ATTR_MTIME)
|
||||
inode->i_mtime = iattr->ia_mtime;
|
||||
ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
|
||||
ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -661,9 +649,9 @@ xfs_setattr_nonsize(
|
|||
* The set-user-ID and set-group-ID bits of a file will be
|
||||
* cleared upon successful return from chown()
|
||||
*/
|
||||
if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
|
||||
if ((inode->i_mode & (S_ISUID|S_ISGID)) &&
|
||||
!capable(CAP_FSETID))
|
||||
ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
|
||||
inode->i_mode &= ~(S_ISUID|S_ISGID);
|
||||
|
||||
/*
|
||||
* Change the ownerships and register quota modifications
|
||||
|
@ -773,7 +761,7 @@ xfs_setattr_size(
|
|||
|
||||
ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
|
||||
ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
|
||||
ASSERT(S_ISREG(ip->i_d.di_mode));
|
||||
ASSERT(S_ISREG(inode->i_mode));
|
||||
ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
|
||||
ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
|
||||
|
||||
|
@ -991,21 +979,13 @@ xfs_vn_update_time(
|
|||
}
|
||||
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
if (flags & S_CTIME) {
|
||||
if (flags & S_CTIME)
|
||||
inode->i_ctime = *now;
|
||||
ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
|
||||
ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
|
||||
}
|
||||
if (flags & S_MTIME) {
|
||||
if (flags & S_MTIME)
|
||||
inode->i_mtime = *now;
|
||||
ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
|
||||
ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
|
||||
}
|
||||
if (flags & S_ATIME) {
|
||||
if (flags & S_ATIME)
|
||||
inode->i_atime = *now;
|
||||
ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
|
||||
ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
|
||||
}
|
||||
|
||||
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
|
||||
return xfs_trans_commit(tp);
|
||||
|
@ -1232,8 +1212,6 @@ xfs_setup_inode(
|
|||
/* make the inode look hashed for the writeback code */
|
||||
hlist_add_fake(&inode->i_hash);
|
||||
|
||||
inode->i_mode = ip->i_d.di_mode;
|
||||
set_nlink(inode, ip->i_d.di_nlink);
|
||||
inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid);
|
||||
inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid);
|
||||
|
||||
|
@ -1249,14 +1227,7 @@ xfs_setup_inode(
|
|||
break;
|
||||
}
|
||||
|
||||
inode->i_generation = ip->i_d.di_gen;
|
||||
i_size_write(inode, ip->i_d.di_size);
|
||||
inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec;
|
||||
inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
|
||||
inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
|
||||
inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
|
||||
inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
|
||||
inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
|
||||
xfs_diflags_to_iflags(inode, ip);
|
||||
|
||||
ip->d_ops = ip->i_mount->m_nondir_inode_ops;
|
||||
|
|
|
@ -57,6 +57,7 @@ xfs_bulkstat_one_int(
|
|||
{
|
||||
struct xfs_icdinode *dic; /* dinode core info pointer */
|
||||
struct xfs_inode *ip; /* incore inode pointer */
|
||||
struct inode *inode;
|
||||
struct xfs_bstat *buf; /* return buffer */
|
||||
int error = 0; /* error value */
|
||||
|
||||
|
@ -77,30 +78,33 @@ xfs_bulkstat_one_int(
|
|||
|
||||
ASSERT(ip != NULL);
|
||||
ASSERT(ip->i_imap.im_blkno != 0);
|
||||
inode = VFS_I(ip);
|
||||
|
||||
dic = &ip->i_d;
|
||||
|
||||
/* xfs_iget returns the following without needing
|
||||
* further change.
|
||||
*/
|
||||
buf->bs_nlink = dic->di_nlink;
|
||||
buf->bs_projid_lo = dic->di_projid_lo;
|
||||
buf->bs_projid_hi = dic->di_projid_hi;
|
||||
buf->bs_ino = ino;
|
||||
buf->bs_mode = dic->di_mode;
|
||||
buf->bs_uid = dic->di_uid;
|
||||
buf->bs_gid = dic->di_gid;
|
||||
buf->bs_size = dic->di_size;
|
||||
buf->bs_atime.tv_sec = dic->di_atime.t_sec;
|
||||
buf->bs_atime.tv_nsec = dic->di_atime.t_nsec;
|
||||
buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
|
||||
buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
|
||||
buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
|
||||
buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec;
|
||||
|
||||
buf->bs_nlink = inode->i_nlink;
|
||||
buf->bs_atime.tv_sec = inode->i_atime.tv_sec;
|
||||
buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec;
|
||||
buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec;
|
||||
buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec;
|
||||
buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec;
|
||||
buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec;
|
||||
buf->bs_gen = inode->i_generation;
|
||||
buf->bs_mode = inode->i_mode;
|
||||
|
||||
buf->bs_xflags = xfs_ip2xflags(ip);
|
||||
buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
|
||||
buf->bs_extents = dic->di_nextents;
|
||||
buf->bs_gen = dic->di_gen;
|
||||
memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
|
||||
buf->bs_dmevmask = dic->di_dmevmask;
|
||||
buf->bs_dmstate = dic->di_dmstate;
|
||||
|
|
|
@ -2865,7 +2865,7 @@ xfs_recover_inode_owner_change(
|
|||
return -ENOMEM;
|
||||
|
||||
/* instantiate the inode */
|
||||
xfs_dinode_from_disk(&ip->i_d, dip);
|
||||
xfs_inode_from_disk(ip, dip);
|
||||
ASSERT(ip->i_d.di_version >= 3);
|
||||
|
||||
error = xfs_iformat_fork(ip, dip);
|
||||
|
@ -2911,7 +2911,7 @@ xlog_recover_inode_pass2(
|
|||
int error;
|
||||
int attr_index;
|
||||
uint fields;
|
||||
xfs_icdinode_t *dicp;
|
||||
struct xfs_log_dinode *ldip;
|
||||
uint isize;
|
||||
int need_free = 0;
|
||||
|
||||
|
@ -2964,8 +2964,8 @@ xlog_recover_inode_pass2(
|
|||
error = -EFSCORRUPTED;
|
||||
goto out_release;
|
||||
}
|
||||
dicp = item->ri_buf[1].i_addr;
|
||||
if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
|
||||
ldip = item->ri_buf[1].i_addr;
|
||||
if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) {
|
||||
xfs_alert(mp,
|
||||
"%s: Bad inode log record, rec ptr 0x%p, ino %Ld",
|
||||
__func__, item, in_f->ilf_ino);
|
||||
|
@ -3001,13 +3001,13 @@ xlog_recover_inode_pass2(
|
|||
* to skip replay when the on disk inode is newer than the log one
|
||||
*/
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
|
||||
ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
|
||||
/*
|
||||
* Deal with the wrap case, DI_MAX_FLUSH is less
|
||||
* than smaller numbers
|
||||
*/
|
||||
if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
|
||||
dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) {
|
||||
ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
trace_xfs_log_recover_inode_skip(log, in_f);
|
||||
|
@ -3017,13 +3017,13 @@ xlog_recover_inode_pass2(
|
|||
}
|
||||
|
||||
/* Take the opportunity to reset the flush iteration count */
|
||||
dicp->di_flushiter = 0;
|
||||
ldip->di_flushiter = 0;
|
||||
|
||||
if (unlikely(S_ISREG(dicp->di_mode))) {
|
||||
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
(dicp->di_format != XFS_DINODE_FMT_BTREE)) {
|
||||
if (unlikely(S_ISREG(ldip->di_mode))) {
|
||||
if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
(ldip->di_format != XFS_DINODE_FMT_BTREE)) {
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
|
||||
XFS_ERRLEVEL_LOW, mp, dicp);
|
||||
XFS_ERRLEVEL_LOW, mp, ldip);
|
||||
xfs_alert(mp,
|
||||
"%s: Bad regular inode log record, rec ptr 0x%p, "
|
||||
"ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
|
||||
|
@ -3031,12 +3031,12 @@ xlog_recover_inode_pass2(
|
|||
error = -EFSCORRUPTED;
|
||||
goto out_release;
|
||||
}
|
||||
} else if (unlikely(S_ISDIR(dicp->di_mode))) {
|
||||
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
(dicp->di_format != XFS_DINODE_FMT_BTREE) &&
|
||||
(dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
|
||||
} else if (unlikely(S_ISDIR(ldip->di_mode))) {
|
||||
if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
(ldip->di_format != XFS_DINODE_FMT_BTREE) &&
|
||||
(ldip->di_format != XFS_DINODE_FMT_LOCAL)) {
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
|
||||
XFS_ERRLEVEL_LOW, mp, dicp);
|
||||
XFS_ERRLEVEL_LOW, mp, ldip);
|
||||
xfs_alert(mp,
|
||||
"%s: Bad dir inode log record, rec ptr 0x%p, "
|
||||
"ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
|
||||
|
@ -3045,32 +3045,32 @@ xlog_recover_inode_pass2(
|
|||
goto out_release;
|
||||
}
|
||||
}
|
||||
if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
|
||||
if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
|
||||
XFS_ERRLEVEL_LOW, mp, dicp);
|
||||
XFS_ERRLEVEL_LOW, mp, ldip);
|
||||
xfs_alert(mp,
|
||||
"%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
|
||||
"dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
|
||||
__func__, item, dip, bp, in_f->ilf_ino,
|
||||
dicp->di_nextents + dicp->di_anextents,
|
||||
dicp->di_nblocks);
|
||||
ldip->di_nextents + ldip->di_anextents,
|
||||
ldip->di_nblocks);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_release;
|
||||
}
|
||||
if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
|
||||
if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
|
||||
XFS_ERRLEVEL_LOW, mp, dicp);
|
||||
XFS_ERRLEVEL_LOW, mp, ldip);
|
||||
xfs_alert(mp,
|
||||
"%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
|
||||
"dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__,
|
||||
item, dip, bp, in_f->ilf_ino, dicp->di_forkoff);
|
||||
item, dip, bp, in_f->ilf_ino, ldip->di_forkoff);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_release;
|
||||
}
|
||||
isize = xfs_icdinode_size(dicp->di_version);
|
||||
isize = xfs_log_dinode_size(ldip->di_version);
|
||||
if (unlikely(item->ri_buf[1].i_len > isize)) {
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
|
||||
XFS_ERRLEVEL_LOW, mp, dicp);
|
||||
XFS_ERRLEVEL_LOW, mp, ldip);
|
||||
xfs_alert(mp,
|
||||
"%s: Bad inode log record length %d, rec ptr 0x%p",
|
||||
__func__, item->ri_buf[1].i_len, item);
|
||||
|
@ -3078,8 +3078,8 @@ xlog_recover_inode_pass2(
|
|||
goto out_release;
|
||||
}
|
||||
|
||||
/* The core is in in-core format */
|
||||
xfs_dinode_to_disk(dip, dicp);
|
||||
/* recover the log dinode inode into the on disk inode */
|
||||
xfs_log_dinode_to_disk(ldip, dip);
|
||||
|
||||
/* the rest is in on-disk format */
|
||||
if (item->ri_buf[1].i_len > isize) {
|
||||
|
@ -4409,8 +4409,8 @@ xlog_recover_process_one_iunlink(
|
|||
if (error)
|
||||
goto fail_iput;
|
||||
|
||||
ASSERT(ip->i_d.di_nlink == 0);
|
||||
ASSERT(ip->i_d.di_mode != 0);
|
||||
ASSERT(VFS_I(ip)->i_nlink == 0);
|
||||
ASSERT(VFS_I(ip)->i_mode != 0);
|
||||
|
||||
/* setup for the next pass */
|
||||
agino = be32_to_cpu(dip->di_next_unlinked);
|
||||
|
|
|
@ -865,7 +865,7 @@ xfs_mountfs(
|
|||
|
||||
ASSERT(rip != NULL);
|
||||
|
||||
if (unlikely(!S_ISDIR(rip->i_d.di_mode))) {
|
||||
if (unlikely(!S_ISDIR(VFS_I(rip)->i_mode))) {
|
||||
xfs_warn(mp, "corrupted root inode %llu: not a directory",
|
||||
(unsigned long long)rip->i_ino);
|
||||
xfs_iunlock(rip, XFS_ILOCK_EXCL);
|
||||
|
|
|
@ -1272,7 +1272,7 @@ xfs_rtpick_extent(
|
|||
|
||||
ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
|
||||
|
||||
seqp = (__uint64_t *)&mp->m_rbmip->i_d.di_atime;
|
||||
seqp = (__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime;
|
||||
if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) {
|
||||
mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
|
||||
*seqp = 0;
|
||||
|
|
|
@ -75,18 +75,10 @@ xfs_trans_ichgtime(
|
|||
|
||||
tv = current_fs_time(inode->i_sb);
|
||||
|
||||
if ((flags & XFS_ICHGTIME_MOD) &&
|
||||
!timespec_equal(&inode->i_mtime, &tv)) {
|
||||
if (flags & XFS_ICHGTIME_MOD)
|
||||
inode->i_mtime = tv;
|
||||
ip->i_d.di_mtime.t_sec = tv.tv_sec;
|
||||
ip->i_d.di_mtime.t_nsec = tv.tv_nsec;
|
||||
}
|
||||
if ((flags & XFS_ICHGTIME_CHG) &&
|
||||
!timespec_equal(&inode->i_ctime, &tv)) {
|
||||
if (flags & XFS_ICHGTIME_CHG)
|
||||
inode->i_ctime = tv;
|
||||
ip->i_d.di_ctime.t_sec = tv.tv_sec;
|
||||
ip->i_d.di_ctime.t_nsec = tv.tv_nsec;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -125,7 +117,7 @@ xfs_trans_log_inode(
|
|||
*/
|
||||
if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) &&
|
||||
IS_I_VERSION(VFS_I(ip))) {
|
||||
ip->i_d.di_changecount = ++VFS_I(ip)->i_version;
|
||||
VFS_I(ip)->i_version++;
|
||||
flags |= XFS_ILOG_CORE;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче