Skip to content

Commit

Permalink
Illumos 3139 - zdb dies when it tries to determine path of unlinked file
Browse files Browse the repository at this point in the history
3139 zdb dies when it tries to determine path of unlinked file
Reviewed by: Matt Ahrens <[email protected]>
Reviewed by: Christopher Siden <[email protected]>
Reviewed by: Eric Schrock <[email protected]>
Approved by: Dan McDonald <[email protected]>

References:
  illumos/illumos-gate@1ce39b5
  https://www.illumos.org/issues/3139

Ported-by: kernelOfTruth [email protected]
Signed-off-by: Brian Behlendorf <[email protected]>
  • Loading branch information
Jeremy Jones authored and behlendorf committed Jan 5, 2016
1 parent cfe86c0 commit b23ad7f
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions module/zfs/zfs_znode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1820,13 +1820,16 @@ zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, void *tag)
* or not the object is an extended attribute directory.
*/
static int
zfs_obj_to_pobj(sa_handle_t *hdl, sa_attr_type_t *sa_table, uint64_t *pobjp,
int *is_xattrdir)
zfs_obj_to_pobj(objset_t *osp, sa_handle_t *hdl, sa_attr_type_t *sa_table,
uint64_t *pobjp, int *is_xattrdir)
{
uint64_t parent;
uint64_t pflags;
uint64_t mode;
uint64_t parent_mode;
sa_bulk_attr_t bulk[3];
sa_handle_t *sa_hdl;
dmu_buf_t *sa_db;
int count = 0;
int error;

Expand All @@ -1840,9 +1843,32 @@ zfs_obj_to_pobj(sa_handle_t *hdl, sa_attr_type_t *sa_table, uint64_t *pobjp,
if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0)
return (error);

*pobjp = parent;
/*
* When a link is removed its parent pointer is not changed and will
* be invalid. There are two cases where a link is removed but the
* file stays around, when it goes to the delete queue and when there
* are additional links.
*/
error = zfs_grab_sa_handle(osp, parent, &sa_hdl, &sa_db, FTAG);
if (error != 0)
return (error);

error = sa_lookup(sa_hdl, ZPL_MODE, &parent_mode, sizeof (parent_mode));
zfs_release_sa_handle(sa_hdl, sa_db, FTAG);
if (error != 0)
return (error);

*is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode);

/*
* Extended attributes can be applied to files, directories, etc.
* Otherwise the parent must be a directory.
*/
if (!*is_xattrdir && !S_ISDIR(parent_mode))
return (EINVAL);

*pobjp = parent;

return (0);
}

Expand Down Expand Up @@ -1891,7 +1917,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
if (prevdb)
zfs_release_sa_handle(prevhdl, prevdb, FTAG);

if ((error = zfs_obj_to_pobj(sa_hdl, sa_table, &pobj,
if ((error = zfs_obj_to_pobj(osp, sa_hdl, sa_table, &pobj,
&is_xattrdir)) != 0)
break;

Expand Down

0 comments on commit b23ad7f

Please sign in to comment.