xfs_io parent -p display parent pointer information for file. xfs_io parent -c check parent pointer consistency for filesystem. --- include/handle.h | 6 ++-- include/jdm.h | 14 +++------ include/parent.h | 13 ++++---- include/xfs_fs.h | 11 +++++++ io/parent.c | 56 +++++++++++++++++++++++--------------- libhandle/handle.c | 78 +++++++++++++++++++++++++++++++++++++++++++---------- libhandle/jdm.c | 48 ++++++++++++++++++++++---------- 7 files changed, 158 insertions(+), 68 deletions(-) Index: b/include/handle.h =================================================================== --- a/include/handle.h +++ b/include/handle.h @@ -24,7 +24,7 @@ extern "C" { struct fsdmidata; struct attrlist_cursor; -struct parent; +struct xfs_parent; extern int path_to_handle (char *__path, void **__hanp, size_t *__hlen); extern int path_to_fshandle (char *__path, void **__fshanp, size_t *__fshlen); @@ -41,10 +41,10 @@ extern int attr_list_by_handle (void *_ size_t __bufsize, int __flags, struct attrlist_cursor *__cursor); extern int parents_by_handle(void *__hanp, size_t __hlen, - struct parent *__buf, size_t __bufsize, + struct xfs_parent *__buf, size_t __bufsize, unsigned int *__count); extern int parentpaths_by_handle(void *__hanp, size_t __hlen, - struct parent *__buf, size_t __bufsize, + struct xfs_parent *__buf, size_t __bufsize, unsigned int *__count); extern int fssetdm_by_handle (void *__hanp, size_t __hlen, struct fsdmidata *__fsdmi); Index: b/include/jdm.h =================================================================== --- a/include/jdm.h +++ b/include/jdm.h @@ -24,7 +24,7 @@ typedef void jdm_filehandle_t; /* fileha struct xfs_bstat; struct attrlist_cursor; -struct parent; +struct xfs_parent; extern jdm_fshandle_t * jdm_getfshandle( char *mntpnt); @@ -62,16 +62,12 @@ jdm_attr_list( jdm_fshandle_t *fshp, struct attrlist_cursor *cursor); extern int -jdm_parents( jdm_fshandle_t *fshp, - xfs_bstat_t *statp, - struct parent *bufp, size_t bufsz, - unsigned int *count); +jdm_parents( jdm_fshandle_t *fshp, struct xfs_bstat *statp, + struct xfs_parent *bufp, size_t bufsz, unsigned int *count); extern int -jdm_parentpaths( jdm_fshandle_t *fshp, - xfs_bstat_t *statp, - struct parent *bufp, size_t bufsz, - unsigned int *count); +jdm_parentpaths( jdm_fshandle_t *fshp, struct xfs_bstat *statp, + struct xfs_parent *bufp, size_t bufsz, unsigned int *count); /* macro for determining the size of a structure member */ #define sizeofmember( t, m ) sizeof( ( ( t * )0 )->m ) Index: b/include/parent.h =================================================================== --- a/include/parent.h +++ b/include/parent.h @@ -18,12 +18,13 @@ #ifndef __PARENT_H__ #define __PARENT_H__ -typedef struct parent { - __u64 p_ino; - __u32 p_gen; - __u16 p_reclen; - char p_name[1]; -} parent_t; +struct xfs_parent { + uint64_t p_ino; /*parent inode number */ + uint32_t p_offset; /* entry offset in parent inode */ + uint16_t p_reclen; /* name length */ + uint16_t p_spare; /* padding for future */ + char p_name[1]; /* name */ +}; typedef struct parent_cursor { __u32 opaque[4]; /* an opaque cookie */ Index: b/include/xfs_fs.h =================================================================== --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -438,6 +438,15 @@ typedef struct xfs_fsop_attrmulti_handle struct xfs_attr_multiop __user *ops; /* attr_multi data */ } xfs_fsop_attrmulti_handlereq_t; + +typedef struct xfs_fsop_parentlist_handlereq { + struct xfs_fsop_handlereq hreq; /* handle interface structure */ + __u32 flags; /* which namespace to use */ + __u32 buflen; /* length of buffer supplied */ + __u32 __user *ocount; /* output count ptr */ + void __user *buffer; /* returned names */ +} xfs_fsop_parentlist_handlereq_t; + /* * per machine unique filesystem identifier types. */ @@ -553,6 +562,8 @@ typedef struct xfs_swapext #define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq) #define XFS_IOC_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom) #define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t) +#define XFS_IOC_GETPARENTS_BY_HANDLE _IOWR('X', 126, struct xfs_fsop_parentlist_handlereq) +#define XFS_IOC_GETPARENTPATHS_BY_HANDLE _IOWR('X', 127, struct xfs_fsop_parentlist_handlereq) /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ Index: b/io/parent.c =================================================================== --- a/io/parent.c +++ b/io/parent.c @@ -39,14 +39,16 @@ static char *mntpt; * check out a parent entry to see if the values seem valid */ static void -check_parent_entry(xfs_bstat_t *bstatp, parent_t *parent) +check_parent_entry( + struct xfs_bstat *bstatp, + struct xfs_parent *parent) { int sts; char fullpath[PATH_MAX]; struct stat statbuf; char *str; - sprintf(fullpath, _("%s%s"), mntpt, parent->p_name); + sprintf(fullpath, _("%s/%s"), mntpt, parent->p_name); sts = lstat(fullpath, &statbuf); if (sts != 0) { @@ -121,19 +123,23 @@ check_parent_entry(xfs_bstat_t *bstatp, } static void -check_parents(parent_t *parentbuf, size_t *parentbuf_size, - jdm_fshandle_t *fshandlep, xfs_bstat_t *statp) +check_parents( + struct xfs_parent *parentbuf, + size_t *parentbuf_size, + jdm_fshandle_t *fshandlep, + struct xfs_bstat *statp) { - int error, i; - __u32 count; - parent_t *entryp; + int error, i; + __u32 count = 0; + struct xfs_parent *entryp; do { error = jdm_parentpaths(fshandlep, statp, parentbuf, *parentbuf_size, &count); if (error == ERANGE) { *parentbuf_size *= 2; - parentbuf = (parent_t *)realloc(parentbuf, *parentbuf_size); + parentbuf = (struct xfs_parent *)realloc(parentbuf, + *parentbuf_size); } else if (error) { fprintf(stderr, _("parentpaths failed for ino %llu: %s\n"), (unsigned long long) statp->bs_ino, @@ -154,13 +160,18 @@ check_parents(parent_t *parentbuf, size_ entryp = parentbuf; for (i = 0; i < count; i++) { check_parent_entry(statp, entryp); - entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); + entryp = (struct xfs_parent*) (((char*)entryp) + + entryp->p_reclen); } } static int -do_bulkstat(parent_t *parentbuf, size_t *parentbuf_size, xfs_bstat_t *bstatbuf, - int fsfd, jdm_fshandle_t *fshandlep) +do_bulkstat( + struct xfs_parent *parentbuf, + size_t *parentbuf_size, + struct xfs_bstat *bstatbuf, + int fsfd, + jdm_fshandle_t *fshandlep) { __s32 buflenout; __u64 lastino = 0; @@ -233,7 +244,7 @@ parent_check(void) { int fsfd; jdm_fshandle_t *fshandlep; - parent_t *parentbuf; + struct xfs_parent *parentbuf; size_t parentbuf_size = PARENTBUF_SZ; xfs_bstat_t *bstatbuf; @@ -254,7 +265,7 @@ parent_check(void) /* allocate buffers */ bstatbuf = (xfs_bstat_t *)calloc(BSTATBUF_SZ, sizeof(xfs_bstat_t)); - parentbuf = (parent_t *)malloc(parentbuf_size); + parentbuf = (struct xfs_parent *)malloc(parentbuf_size); if (!bstatbuf || !parentbuf) { fprintf(stderr, _("unable to allocate buffers: %s\n"), strerror(errno)); @@ -276,13 +287,15 @@ parent_check(void) } static void -print_parent_entry(parent_t *parent, int fullpath) +print_parent_entry( + struct xfs_parent *parent, + int fullpath) { - printf(_("p_ino = %llu\n"), (unsigned long long) parent->p_ino); - printf(_("p_gen = %u\n"), parent->p_gen); + printf(_("p_ino = %llu\n"), (unsigned long long) parent->p_ino); + printf(_("p_offset = %u\n"), parent->p_offset); printf(_("p_reclen = %u\n"), parent->p_reclen); if (fullpath) - printf(_("p_name = \"%s%s\"\n"), mntpt, parent->p_name); + printf(_("p_name = \"%s/%s\"\n"), mntpt, parent->p_name); else printf(_("p_name = \"%s\"\n"), parent->p_name); } @@ -295,8 +308,8 @@ parent_list(int fullpath) int error, i; int retval = 1; __u32 count; - parent_t *entryp; - parent_t *parentbuf = NULL; + struct xfs_parent *entryp; + struct xfs_parent *parentbuf = NULL; char *path = file->name; int pb_size = PARENTBUF_SZ; @@ -318,7 +331,7 @@ parent_list(int fullpath) } do { - parentbuf = (parent_t *)realloc(parentbuf, pb_size); + parentbuf = (struct xfs_parent *)realloc(parentbuf, pb_size); if (!parentbuf) { fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"), progname, strerror(errno)); @@ -357,7 +370,8 @@ parent_list(int fullpath) entryp = parentbuf; for (i = 0; i < count; i++) { print_parent_entry(entryp, fullpath); - entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); + entryp = (struct xfs_parent *) (((char*)entryp) + + entryp->p_reclen); } retval = 0; Index: b/libhandle/handle.c =================================================================== --- a/libhandle/handle.c +++ b/libhandle/handle.c @@ -405,27 +405,77 @@ attr_list_by_handle( int parents_by_handle( - void *hanp, - size_t hlen, - parent_t *buf, - size_t bufsiz, - unsigned int *count) + void *hanp, + size_t hlen, + struct xfs_parent *buf, + size_t bufsiz, + unsigned int *count) { - errno = EOPNOTSUPP; - return -1; + int error, fd; + char *path; + char buffer[MAXPATHLEN+1]; + unsigned int buflen = MAXPATHLEN; + struct xfs_fsop_parentlist_handlereq plheq; + + if ((fd = handle_to_fsfd(hanp, &path)) < 0) + return -1; + + plheq.hreq.fd = 0; + plheq.hreq.path = NULL; + plheq.hreq.oflags = O_LARGEFILE; + plheq.hreq.ihandle = hanp; + plheq.hreq.ihandlen = hlen; + plheq.hreq.ohandle = buffer; + plheq.hreq.ohandlen = &buflen; + plheq.flags = 0x0040; + plheq.buffer = buf; + plheq.buflen = bufsiz; + plheq.ocount = count; + + /* prevent needless EINVAL from the kernel */ + if (plheq.buflen > XATTR_LIST_MAX) + plheq.buflen = XATTR_LIST_MAX; + + error = xfsctl(path, fd, XFS_IOC_GETPARENTS_BY_HANDLE, &plheq); + return error; } int parentpaths_by_handle( - void *hanp, - size_t hlen, - parent_t *buf, - size_t bufsiz, - unsigned int *count) + void *hanp, + size_t hlen, + struct xfs_parent *buf, + size_t bufsiz, + unsigned int *count) { - errno = EOPNOTSUPP; - return -1; + int error, fd; + char *path; + char buffer[MAXPATHLEN+1]; + unsigned int buflen = MAXPATHLEN; + struct xfs_fsop_parentlist_handlereq plheq; + + if ((fd = handle_to_fsfd(hanp, &path)) < 0) + return -1; + + plheq.hreq.fd = 0; + plheq.hreq.path = NULL; + plheq.hreq.oflags = O_LARGEFILE; + plheq.hreq.ihandle = hanp; + plheq.hreq.ihandlen = hlen; + plheq.hreq.ohandle = buffer; + plheq.hreq.ohandlen = &buflen; + plheq.flags = 0x0040; + plheq.buffer = buf; + plheq.buflen = bufsiz; + plheq.ocount = count; + + /* prevent needless EINVAL from the kernel */ + if (plheq.buflen > XATTR_LIST_MAX) + plheq.buflen = XATTR_LIST_MAX; + + error = xfsctl(path, fd, XFS_IOC_GETPARENTPATHS_BY_HANDLE, &plheq); + return error; } int Index: b/libhandle/jdm.c =================================================================== --- a/libhandle/jdm.c +++ b/libhandle/jdm.c @@ -18,8 +18,8 @@ #include <xfs/xfs.h> #include <xfs/handle.h> -#include <xfs/jdm.h> #include <xfs/parent.h> +#include <xfs/jdm.h> /* internal fshandle - typecast to a void for external use */ #define FSHANDLE_SZ 8 @@ -178,21 +178,39 @@ jdm_attr_list( jdm_fshandle_t *fshp, } int -jdm_parents( jdm_fshandle_t *fshp, - xfs_bstat_t *statp, - parent_t *bufp, size_t bufsz, - unsigned int *count) -{ - errno = EOPNOTSUPP; - return -1; +jdm_parents( + jdm_fshandle_t *fshp, + struct xfs_bstat *statp, + struct xfs_parent *bufp, + size_t bufsz, + unsigned int *count) +{ + struct xfs_handle *handle = (struct xfs_handle *) fshp; + + handle->ha_fid.fid_ino = statp->bs_ino; + handle->ha_fid.fid_gen = statp->bs_gen; + handle->ha_fid.fid_len = + sizeof(handle->ha_fid) - sizeof(handle->ha_fid.fid_len); + + return parents_by_handle(handle, sizeof(struct xfs_handle), bufp, + bufsz, count); } int -jdm_parentpaths( jdm_fshandle_t *fshp, - xfs_bstat_t *statp, - parent_t *bufp, size_t bufsz, - unsigned int *count) -{ - errno = EOPNOTSUPP; - return -1; +jdm_parentpaths( + jdm_fshandle_t *fshp, + struct xfs_bstat *statp, + struct xfs_parent *bufp, + size_t bufsz, + unsigned int *count) +{ + struct xfs_handle *handle = (struct xfs_handle *) fshp; + + handle->ha_fid.fid_ino = statp->bs_ino; + handle->ha_fid.fid_gen = statp->bs_gen; + handle->ha_fid.fid_len = + sizeof(handle->ha_fid) - sizeof(handle->ha_fid.fid_len); + + return parentpaths_by_handle(handle, sizeof(struct xfs_handle), bufp, + bufsz, count); } _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs