On Wed, May 11, 2022 at 08:39:52AM -0700, Darrick J. Wong wrote: > On Wed, May 11, 2022 at 06:35:13PM +1000, Dave Chinner wrote: > > On Wed, May 11, 2022 at 11:38:51AM +1000, Dave Chinner wrote: > > > On Tue, May 10, 2022 at 06:08:48PM -0700, Darrick J. Wong wrote: > > > > On Wed, May 11, 2022 at 11:06:51AM +1000, Dave Chinner wrote: > > > > > I'm going to leave this for the moment (cleanup note made) because I > > > > > don't want to have to find out that I missed a corner case somewhere > > > > > they hard way right now. It's basically there to stop log recovery > > > > > crashing hard, which only occurs when the experimental larp code is > > > > > running, so I think this is safe to leave for a later cleanup. > > > > > > > > Hmm, in that case, can this become: > > > > > > > > if (!args->dp->i_afp) { > > > > ASSERT(0); > > > > return XFS_DAS_DONE; > > > > } > > > > > > OK. > > > > Ok, now generic/051 has reminded me exactly what this was for. > > > > Shortform attr remove will remove the attr and the attr fork from > > this code: > > > > case XFS_DAS_SF_REMOVE: > > error = xfs_attr_sf_removename(args); > > attr->xattri_dela_state = xfs_attr_complete_op(attr, > > xfs_attr_init_add_state(args)); > > break; > > > > But if we are doing this as part of a REPLACE operation and we > > still need to add the new attr, it calls xfs_attr_init_add_state() > > to get the add state we should start with. That then hits the > > null args->dp->i_afp case because the fork got removed. > > > > This can't happen if we are doing a replace op, so we'd then check > > if it's a shortform attr fork and return XFS_DAS_SF_ADD for the > > replace to then execute. But it's not a replace op, so we can > > have a null attr fork. > > > > I'm going to restore the old code with a comment so that I don't > > forget this again. > > > > /* > > * If called from the completion of a attr remove to determine > > * the next state, the attribute fork may be null. This can occur on > > * a pure remove, but we grab the next state before we check if a > > * replace operation is being performed. Hence if the attr fork is > > * null, it's a pure remove operation and we are done. > > */ > > Ahh, I see -- sf_removename will /never/ kill i_afp if we're doing a > DA_OP_REPLACE or ADDNAME, and leaf_removename also won't do that if > we're doing DA_OP_REPLACE. IOWs, only a removexattr operation can > result in i_afp being freed. > > And the XATTR_CREATE operation always guarantee that i_afp is non-null > before we start, so xfs_attr_defer_add should never be called with > args->dp->i_afp == NULL, hence it'll never hit that state. > > Would you mind adding a sentence to the comment? > > "A pure create ensures the existence of i_afp and never encounters this > state." Sure. -Dave. -- Dave Chinner david@xxxxxxxxxxxxx