mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 10:41:49 +02:00
xfs: record inode generation in xattr update log intent items
For parent pointer updates, record the i_generation of the file that is being updated so that we don't accidentally jump generations. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
5773f7f82b
commit
ae673f534a
|
|
@ -1049,7 +1049,7 @@ struct xfs_icreate_log {
|
||||||
struct xfs_attri_log_format {
|
struct xfs_attri_log_format {
|
||||||
uint16_t alfi_type; /* attri log item type */
|
uint16_t alfi_type; /* attri log item type */
|
||||||
uint16_t alfi_size; /* size of this item */
|
uint16_t alfi_size; /* size of this item */
|
||||||
uint32_t __pad; /* pad to 64 bit aligned */
|
uint32_t alfi_igen; /* generation of alfi_ino for pptr ops */
|
||||||
uint64_t alfi_id; /* attri identifier */
|
uint64_t alfi_id; /* attri identifier */
|
||||||
uint64_t alfi_ino; /* the inode for this attr operation */
|
uint64_t alfi_ino; /* the inode for this attr operation */
|
||||||
uint32_t alfi_op_flags; /* marks the op as a set or remove */
|
uint32_t alfi_op_flags; /* marks the op as a set or remove */
|
||||||
|
|
|
||||||
|
|
@ -388,9 +388,14 @@ xfs_attr_log_item(
|
||||||
case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
|
case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
|
||||||
ASSERT(nv->value.i_len == nv->new_value.i_len);
|
ASSERT(nv->value.i_len == nv->new_value.i_len);
|
||||||
|
|
||||||
|
attrp->alfi_igen = VFS_I(args->dp)->i_generation;
|
||||||
attrp->alfi_old_name_len = nv->name.i_len;
|
attrp->alfi_old_name_len = nv->name.i_len;
|
||||||
attrp->alfi_new_name_len = nv->new_name.i_len;
|
attrp->alfi_new_name_len = nv->new_name.i_len;
|
||||||
break;
|
break;
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_SET:
|
||||||
|
attrp->alfi_igen = VFS_I(args->dp)->i_generation;
|
||||||
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
attrp->alfi_name_len = nv->name.i_len;
|
attrp->alfi_name_len = nv->name.i_len;
|
||||||
break;
|
break;
|
||||||
|
|
@ -545,9 +550,6 @@ xfs_attri_validate(
|
||||||
{
|
{
|
||||||
unsigned int op = xfs_attr_log_item_op(attrp);
|
unsigned int op = xfs_attr_log_item_op(attrp);
|
||||||
|
|
||||||
if (attrp->__pad != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (attrp->alfi_op_flags & ~XFS_ATTRI_OP_FLAGS_TYPE_MASK)
|
if (attrp->alfi_op_flags & ~XFS_ATTRI_OP_FLAGS_TYPE_MASK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -639,9 +641,27 @@ xfs_attri_recover_work(
|
||||||
int local;
|
int local;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = xlog_recover_iget(mp, attrp->alfi_ino, &ip);
|
/*
|
||||||
if (error)
|
* Parent pointer attr items record the generation but regular logged
|
||||||
return ERR_PTR(error);
|
* xattrs do not; select the right iget function.
|
||||||
|
*/
|
||||||
|
switch (xfs_attr_log_item_op(attrp)) {
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_SET:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE:
|
||||||
|
error = xlog_recover_iget_handle(mp, attrp->alfi_ino,
|
||||||
|
attrp->alfi_igen, &ip);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error = xlog_recover_iget(mp, attrp->alfi_ino, &ip);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
xfs_irele(ip);
|
||||||
|
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, attrp,
|
||||||
|
sizeof(*attrp));
|
||||||
|
return ERR_PTR(-EFSCORRUPTED);
|
||||||
|
}
|
||||||
|
|
||||||
if (xfs_inode_has_attr_fork(ip)) {
|
if (xfs_inode_has_attr_fork(ip)) {
|
||||||
error = xfs_attri_iread_extents(ip);
|
error = xfs_attri_iread_extents(ip);
|
||||||
|
|
@ -793,6 +813,7 @@ xfs_attr_relog_intent(
|
||||||
new_attrp = &new_attrip->attri_format;
|
new_attrp = &new_attrip->attri_format;
|
||||||
|
|
||||||
new_attrp->alfi_ino = old_attrp->alfi_ino;
|
new_attrp->alfi_ino = old_attrp->alfi_ino;
|
||||||
|
new_attrp->alfi_igen = old_attrp->alfi_igen;
|
||||||
new_attrp->alfi_op_flags = old_attrp->alfi_op_flags;
|
new_attrp->alfi_op_flags = old_attrp->alfi_op_flags;
|
||||||
new_attrp->alfi_value_len = old_attrp->alfi_value_len;
|
new_attrp->alfi_value_len = old_attrp->alfi_value_len;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user