Skip to content

Commit

Permalink
Iterate over ZPL_LINKDIRS to find siblings test
Browse files Browse the repository at this point in the history
$ cd /d
$ mkdir dir1 dir2
$ touch dir1/file1.txt
$ for i in dir1/file2.txt dir2/file3.txt dir2/file4.txt
> do
> ln dir1/file1.txt $i
> done

$ ls -lR
.:
total 0
drwxr-xr-x 1 WDKRemoteUser 197121 0 Nov 19 17:22 dir1/
drwxr-xr-x 1 WDKRemoteUser 197121 0 Nov 19 17:22 dir2/

./dir1:
total 0
-rw-r--r-- 4 WDKRemoteUser 197121 0 Nov 19 17:21 file1.txt
-rw-r--r-- 4 WDKRemoteUser 197121 0 Nov 19 17:21 file2.txt

./dir2:
total 0
-rw-r--r-- 4 WDKRemoteUser 197121 0 Nov 19 17:21 file3.txt
-rw-r--r-- 4 WDKRemoteUser 197121 0 Nov 19 17:21 file4.txt

$ fsutil hardlink list /d/dir2/file3.txt

FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5429:file_hard_link_information(): file_hard_link_information:
FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5514:file_hard_link_information(): Linkdir 0: 4
FFFF950564FC8080: dprintf: zfs_znode.c:1077:zfs_zget_ext(): +zget 4
FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5532:file_hard_link_information(): Linkdir 4 has entry file1.txt
FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5532:file_hard_link_information(): Linkdir 4 has entry file2.txt
FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5514:file_hard_link_information(): Linkdir 1: 7
FFFF950564FC8080: dprintf: zfs_znode.c:1077:zfs_zget_ext(): +zget 7
FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5532:file_hard_link_information(): Linkdir 7 has entry file3.txt
FFFF950564FC8080: dprintf: zfs_vnops_windows_lib.c:5532:file_hard_link_information(): Linkdir 7 has entry file4.txt

Signed-off-by: Jorgen Lundman <[email protected]>
  • Loading branch information
lundman committed Nov 19, 2024
1 parent 08a5bb2 commit 8096f5c
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions module/os/windows/zfs/zfs_vnops_windows_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -5485,6 +5485,66 @@ file_hard_link_information(PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = bytes_needed;

/* Lets test iterating ZPL_LINKDIRS */

#define ZFS_LINKDIR_OBJ(lde) BF64_GET((lde), 0, 48)

/*
* We build paths leading up to root of this dataset, it is
* Up to the caller to handle mountpoint location, ie for
* "/pool/dataset/directory/file.txt" it could be
* "/directory/file.txt" if dataset is mounted at "/pool/dataset"
*/
int ldsize = 0;

(void) sa_size(zp->z_sa_hdl, SA_ZPL_LINKDIRS(zfsvfs), &ldsize);
if (ldsize > 0) {
znode_t *dzp;
zap_cursor_t zc;
zap_attribute_t zap;
ino64_t objnum;
objset_t *os;

os = zfsvfs->z_os;
uint64_t *ld = kmem_alloc(ldsize, KM_SLEEP);

VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_LINKDIRS(zfsvfs),
ld, ldsize) == 0);
for (int i = 0; i < ldsize / sizeof (uint64_t); i++) {
dprintf("Linkdir %d: %llu\n", i,
ZFS_LINKDIR_OBJ(ld[i]));

// The same Directory can be listed multiple times, so
// do a quick scan of previous directories.
for (int j = 0; j < i; j++)
if (ZFS_LINKDIR_OBJ(ld[i]) ==
ZFS_LINKDIR_OBJ(ld[j]))
continue;

// List directory, looking for matches with zp->z_id
if (zfs_zget(zfsvfs, ZFS_LINKDIR_OBJ(ld[i]), &dzp) != 0)
continue;

zap_cursor_init(&zc, os, dzp->z_id);

while (zap_cursor_retrieve(&zc, &zap) == 0) {
objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
if (objnum == zp->z_id) {
dprintf("Linkdir %llu has entry %s\n",
ZFS_LINKDIR_OBJ(ld[i]),
zap.za_name);
}
zap_cursor_advance(&zc);
}

zap_cursor_fini(&zc);
zrele(dzp);
}
kmem_free(ld, ldsize);
}
/* Lets test iterating ZPL_LINKDIRS */


out:
if (dvp != NULL)
VN_RELE(dvp);
Expand Down

0 comments on commit 8096f5c

Please sign in to comment.