Re: [PATCH] xfs_io: changes to statx interface [ver #3]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/29/17 11:49 AM, David Howells wrote:
> Here's my third attempt at changing Eric's statx patch.  I've got rid of the
> compare option to statx and added a raw output option to stat.  They're still
> not directly comparable since the stat output lacks some fields, but it will
> hopefully be possible to load them into associative arrays in bash and compare
> them that way.

Thanks for working on this; comments below.

But - do you plan to send this as (a) formal patch(es) with signed-off-by
etc?  Or do you want me to just fold this into my patch with some
sort of Changes-inspired-by: David Howells <dhowells@xxxxxxxxxx> tag? ;)

The changes to stat_f should be their own standalone patch, I think.

(meh, it's kind of unfortunate that the current stat_f does more
than just stat, isn't it?)

I may make further changes so that a bare "statx" prints exactly the
same info as a bare "stat", and a new "-r" to each one dumps the raw
stat[x] structure.  Just for some symmetry...

> ---
> diff --git a/io/stat.c b/io/stat.c
> index a7aebcd..d2ea854 100644
> --- a/io/stat.c
> +++ b/io/stat.c
> @@ -44,6 +44,35 @@ filesize(void)
>  	return st.st_size;
>  }
>  
> +static int
> +dump_raw_stat(struct stat *st)
> +{
> +	if (fstat(file->fd, st) < 0) {
> +		perror("fstat");
> +		return -1;
> +	}
> +
> +	printf("stat.blksize: %lu\n", st->st_blksize);
> +	printf("stat.nlink: %lu\n", st->st_nlink);
> +	printf("stat.uid: %u\n", st->st_uid);
> +	printf("stat.gid: %u\n", st->st_gid);
> +	printf("stat.mode: 0%o\n", st->st_mode);
> +	printf("stat.ino: %lu\n", st->st_ino);
> +	printf("stat.size: %lu\n", st->st_size);
> +	printf("stat.blocks: %lu\n", st->st_blocks);
> +	printf("stat.atime.tv_sec: %ld\n", st->st_atim.tv_sec);
> +	printf("stat.atime.tv_nsec: %ld\n", st->st_atim.tv_nsec);
> +	printf("stat.ctime.tv_sec: %ld\n", st->st_ctim.tv_sec);
> +	printf("stat.ctime.tv_nsec: %ld\n", st->st_ctim.tv_nsec);
> +	printf("stat.mtime.tv_sec: %ld\n", st->st_mtim.tv_sec);
> +	printf("stat.mtime.tv_nsec: %ld\n", st->st_mtim.tv_nsec);
> +	printf("stat.rdev_major: %u\n", major(st->st_rdev));
> +	printf("stat.rdev_minor: %u\n", minor(st->st_rdev));
> +	printf("stat.dev_major: %u\n", major(st->st_dev));
> +	printf("stat.dev_minor: %u\n", minor(st->st_dev));
> +	return 0;
> +}
> +
>  static char *
>  filetype(mode_t mode)
>  {
> @@ -74,7 +103,23 @@ stat_f(
>  	struct dioattr	dio;
>  	struct fsxattr	fsx, fsxa;
>  	struct stat	st;
> -	int		verbose = (argc == 2 && !strcmp(argv[1], "-v"));
> +	int		c, verbose = 0, raw = 0;
> +
> +	while ((c = getopt(argc, argv, "rv")) != EOF) {
> +		switch (c) {
> +		case 'r':
> +			raw = 1;
> +			break;
> +		case 'v':
> +			verbose = 1;
> +			break;
> +		default:
> +			return command_usage(&stat_cmd);
> +		}
> +	}
> +
> +	if (raw)
> +		return dump_raw_stat(&st);
>  
>  	printf(_("fd.path = \"%s\"\n"), file->name);
>  	printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"),
> @@ -189,12 +234,9 @@ statx_help(void)
>  " Display extended file status.\n"
>  "\n"
>  " Options:\n"
> -" -m mask -- Specify the field mask for the statx call (default STATX_ALL)\n"
> -" -A -- Suppress terminal automount traversal\n"
> +" -m mask -- Specify the field mask for the statx call (can also be 'basic' or 'all'; default STATX_ALL)\n"
>  " -D -- Don't sync attributes with the server\n"
>  " -F -- Force the attributes to be sync'd with the server\n"
> -" -L -- Follow symlinks (statx link target)\n"
> -" -O -- Add only basic stats (STATX_BASIC_STATS) to default mask\n"

ok, I like the basic/all/mask better, yes.

>  "\n"));
>  }
>  
> @@ -202,28 +244,28 @@ statx_help(void)
>  static void
>  dump_statx(struct statx *stx)
>  {
> -	printf("stx_mask: 0x%x\n", stx->stx_mask);
> -	printf("stx_blksize: %u\n", stx->stx_blksize);
> -	printf("stx_attributes: 0x%llx\n", stx->stx_attributes);
> -	printf("stx_nlink: %u\n", stx->stx_nlink);
> -	printf("stx_uid: %u\n", stx->stx_uid);
> -	printf("stx_gid: %u\n", stx->stx_gid);
> -	printf("stx_mode: 0%o\n", stx->stx_mode);
> -	printf("stx_ino: %llu\n", stx->stx_ino);
> -	printf("stx_size: %llu\n", stx->stx_size);
> -	printf("stx_blocks: %llu\n", stx->stx_blocks);
> -	printf("stx_atime.tv_sec: %lld\n", stx->stx_atime.tv_sec);
> -	printf("stx_atime.tv_nsec: %d\n", stx->stx_atime.tv_nsec);
> -	printf("stx_btime.tv_sec: %lld\n", stx->stx_btime.tv_sec);
> -	printf("stx_btime.tv_nsec: %d\n", stx->stx_btime.tv_nsec);
> -	printf("stx_ctime.tv_sec: %lld\n", stx->stx_ctime.tv_sec);
> -	printf("stx_ctime.tv_nsec: %d\n", stx->stx_ctime.tv_nsec);
> -	printf("stx_mtime.tv_sec: %lld\n", stx->stx_mtime.tv_sec);
> -	printf("stx_mtime.tv_nsec: %d\n", stx->stx_mtime.tv_nsec);
> -	printf("stx_rdev_major: %u\n", stx->stx_rdev_major);
> -	printf("stx_rdev_minor: %u\n", stx->stx_rdev_minor);
> -	printf("stx_dev_major: %u\n", stx->stx_dev_major);
> -	printf("stx_dev_minor: %u\n", stx->stx_dev_minor);
> +	printf("stat.mask: 0x%x\n", stx->stx_mask);

Seems a little weird to be printing something that looks
like structure.member, when it's not actually the structure
or member name, but I suppose it facilitates parsing the output
for testing?

> +	printf("stat.blksize: %u\n", stx->stx_blksize);
> +	printf("stat.attributes: 0x%llx\n", stx->stx_attributes);
> +	printf("stat.nlink: %u\n", stx->stx_nlink);
> +	printf("stat.uid: %u\n", stx->stx_uid);
> +	printf("stat.gid: %u\n", stx->stx_gid);
> +	printf("stat.mode: 0%o\n", stx->stx_mode);
> +	printf("stat.ino: %llu\n", stx->stx_ino);
> +	printf("stat.size: %llu\n", stx->stx_size);
> +	printf("stat.blocks: %llu\n", stx->stx_blocks);
> +	printf("stat.atime.tv_sec: %lld\n", stx->stx_atime.tv_sec);
> +	printf("stat.atime.tv_nsec: %d\n", stx->stx_atime.tv_nsec);
> +	printf("stat.btime.tv_sec: %lld\n", stx->stx_btime.tv_sec);
> +	printf("stat.btime.tv_nsec: %d\n", stx->stx_btime.tv_nsec);
> +	printf("stat.ctime.tv_sec: %lld\n", stx->stx_ctime.tv_sec);
> +	printf("stat.ctime.tv_nsec: %d\n", stx->stx_ctime.tv_nsec);
> +	printf("stat.mtime.tv_sec: %lld\n", stx->stx_mtime.tv_sec);
> +	printf("stat.mtime.tv_nsec: %d\n", stx->stx_mtime.tv_nsec);
> +	printf("stat.rdev_major: %u\n", stx->stx_rdev_major);
> +	printf("stat.rdev_minor: %u\n", stx->stx_rdev_minor);
> +	printf("stat.dev_major: %u\n", stx->stx_dev_major);
> +	printf("stat.dev_minor: %u\n", stx->stx_dev_minor);
>  }
>  
>  /*
> @@ -239,16 +281,18 @@ statx_f(
>  {
>  	int		c;
>  	struct statx	stx;
> -	int		atflag = AT_SYMLINK_NOFOLLOW;
> -	unsigned int	m_mask = 0;	/* mask requested with -m */
> -	int		Oflag = 0, mflag = 0;	/* -O or -m was used */
> +	int		atflag = 0;
>  	unsigned int	mask = STATX_ALL;
>  
> -	while ((c = getopt(argc, argv, "m:FDLOA")) != EOF) {
> +	while ((c = getopt(argc, argv, "m:FD")) != EOF) {
>  		switch (c) {
>  		case 'm':
> -			m_mask = atoi(optarg);
> -			mflag = 1;
> +			if (strcmp(optarg, "basic") == 0)
> +				mask = STATX_BASIC_STATS;
> +			else if (strcmp(optarg, "all") == 0)
> +				mask = STATX_ALL;
> +			else
> +				mask = strtoul(optarg, NULL, 0);

best to check for failure here I suppose, but I've already got 
that in my current patch.

>  			break;
>  		case 'F':
>  			atflag &= ~AT_STATX_SYNC_TYPE;
> @@ -258,38 +302,19 @@ statx_f(
>  			atflag &= ~AT_STATX_SYNC_TYPE;
>  			atflag |= AT_STATX_DONT_SYNC;
>  			break;
> -		case 'L':
> -			atflag &= ~AT_SYMLINK_NOFOLLOW;
> -			break;
> -		case 'O':
> -			mask = STATX_BASIC_STATS;
> -			Oflag = 1;
> -			break;
> -		case 'A':
> -			atflag |= AT_NO_AUTOMOUNT;
> -			break;
>  		default:
>  			return command_usage(&statx_cmd);
>  		}
>  	}
>  
> -	if (Oflag && mflag) {
> -		printf("Cannot specify both -m mask and -O\n");
> -		return 0;
> -	}
> -
> -	/* -m overrides any other mask options */
> -	if (mflag)
> -		mask = m_mask;
> -
>  	memset(&stx, 0xbf, sizeof(stx));
> -	if (statx(AT_FDCWD, file->name, atflag, mask, &stx) < 0) {
> +
> +	if (statx(file->fd, NULL, atflag, mask, &stx) < 0) {
>  		perror("statx");
>  		return 0;
>  	}
> -
> +	

whitespace ;)

>  	dump_statx(&stx);
> -
>  	return 0;
>  }
>  
> @@ -301,7 +326,7 @@ stat_init(void)
>  	stat_cmd.argmin = 0;
>  	stat_cmd.argmax = 1;
>  	stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
> -	stat_cmd.args = _("[-v]");
> +	stat_cmd.args = _("[-rv]");
>  	stat_cmd.oneline = _("information about the currently open file");
>  
>  	statfs_cmd.name = "statfs";
> @@ -315,7 +340,7 @@ stat_init(void)
>  	statx_cmd.argmin = 0;
>  	statx_cmd.argmax = -1;
>  	statx_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
> -	statx_cmd.args = _("[-O | -m mask][-FDLAP]");
> +	statx_cmd.args = _("[-m basic | -m all | -m <mask>][-FD]");
>  	statx_cmd.oneline =
>   _("extended information about the currently open file");
>  	statx_cmd.help = statx_help;
> diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8
> index 77ba760..486ad11 100644
> --- a/man/man8/xfs_io.8
> +++ b/man/man8/xfs_io.8
> @@ -876,24 +876,29 @@ Only available in expert mode and requires privileges.
>  Force the filesystem to shutdown (with or without flushing the log).
>  Only available in expert mode and requires privileges.
>  .TP
> -.BR stat " [ " \-v " ]"
> +.BR stat " [ \-" rv " ]"
>  Selected statistics from
>  .BR stat (2)
>  and the XFS_IOC_GETXATTR system call on the current file. If the
>  .B \-v
>  option is specified, the atime (last access), mtime
> -(last modify), and ctime (last change) timestamps are also displayed.
> +(last modify), and ctime (last change) timestamps are also displayed. If the
> +.B \-r
> +option is specified, the raw output will be dumped in the same form as the
> +output for the statx command, but with some fields missing.
>  .TP
> -.BR statx " [ " \-O " | " "\-m mask" " ][ \-" FDLA " ]"
> +.BR statx " [ " "\-m mask" " ][ \-" FD " ]"
>  Extended information from the statx syscall.
>  .RS 1.0i
>  .PD 0
>  .TP 0.4i
>  .B \-m mask
> -Specify the field mask for the statx call (default STATX_ALL)
> -.TP
> -.B \-O
> -Add only basic stats (STATX_BASIC_STATS) to default mask
> +Specify the field mask for the statx call as an decimal, hex or octal integer
> +or
> +.RI \" basic "\" or \"" all \"
> +to specify the basic stats that
> +.IR stat ()
> +returns or all the stats known by the header file.  All is the default.
>  .TP
>  .B \-F
>  Force the attributes to be sync'd with the server
> @@ -901,12 +906,6 @@ Force the attributes to be sync'd with the server
>  .B \-D
>  Don't sync attributes with the server
>  .TP
> -.B \-L
> -Follow symlinks (statx link target)
> -.TP
> -.B \-A
> -Suppress terminal automount traversal
> -.TP
>  .RE
>  .IP
>  .TP
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux