Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965280AbbBCItv (ORCPT ); Tue, 3 Feb 2015 03:49:51 -0500 Received: from mail-pa0-f54.google.com ([209.85.220.54]:39837 "EHLO mail-pa0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754630AbbBCItr convert rfc822-to-8bit (ORCPT ); Tue, 3 Feb 2015 03:49:47 -0500 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Re: [PATCH v3 1/1] ioctl-fat.2: new manpage for the ioctl fat API From: Andreas Dilger In-Reply-To: <1422042884-10824-1-git-send-email-xypron.glpk@gmx.de> Date: Tue, 3 Feb 2015 01:49:44 -0700 Cc: "Michael Kerrisk (man-pages)" , Ogawa Hirofumi , Linux Filesystem Development List , LKML , linux-man Content-Transfer-Encoding: 8BIT Message-Id: <5984550D-1518-490C-9A3F-3F9B1FA2EA00@dilger.ca> References: <1422042884-10824-1-git-send-email-xypron.glpk@gmx.de> To: Heinrich Schuchardt X-Mailer: Apple Mail (2.2070.6) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 13780 Lines: 508 On Jan 23, 2015, at 12:54 PM, Heinrich Schuchardt wrote: > > The ioctl(2) system call may be used to retrieve information about > the fat file system and to set file attributes. > > This new manpage describes the details. > > Michael Kerrisk suggested to CC linux-fsdevel@vger.kernel.org and > linux-kernel@vger.kernel.org for review. > > version 3: correct typos > version 2: consider comments by Michael Kerrisk > verison 1: original patch > > Signed-by: Heinrich Schuchardt > --- > man2/ioctl-fat.2 | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 442 insertions(+) > create mode 100644 man2/ioctl-fat.2 > > diff --git a/man2/ioctl-fat.2 b/man2/ioctl-fat.2 > new file mode 100644 > index 0000000..80891d8 > --- /dev/null > +++ b/man2/ioctl-fat.2 > @@ -0,0 +1,442 @@ > +.\" Copyright (C) 2014, Heinrich Schuchardt > +.\" > +.\" %%%LICENSE_START(VERBATIM) > +.\" Permission is granted to make and distribute verbatim copies of this > +.\" manual provided the copyright notice and this permission notice are > +.\" preserved on all copies. > +.\" > +.\" Permission is granted to copy and distribute modified versions of > +.\" this manual under the conditions for verbatim copying, provided that > +.\" the entire resulting derived work is distributed under the terms of > +.\" a permission notice identical to this one. > +.\" > +.\" Since the Linux kernel and libraries are constantly changing, this > +.\" manual page may be incorrect or out-of-date. The author(s) assume. > +.\" no responsibility for errors or omissions, or for damages resulting. > +.\" from the use of the information contained herein. The author(s) may. > +.\" not have taken the same level of care in the production of this. > +.\" manual, which is licensed free of charge, as they might when working. There are extraneous periods at the end of each of these lines. > +.\" professionally. > +.\" > +.\" Formatted or processed versions of this manual, if unaccompanied by > +.\" the source, must acknowledge the copyright and authors of this work. > +.\" %%%LICENSE_END > +.TH IOCTl-FAT 2 2015-01-23 "Linux" "Linux Programmer's Manual" > +.SH "NAME" > +ioctl-fat \- manipulating the FAT filesystem > +.SH SYNOPSIS > +.nf > +.B #include > +.br > +.B #include > +.sp > +.BI "int ioctl(int " fd ", FAT_IOCTL_GET_ATTRIBUTES, uint32_t * " attr); > +.BI "int ioctl(int " fd ", FAT_IOCTL_SET_ATTRIBUTES, uint32_t * " attr); > +.BI "int ioctl(int " fd ", FAT_IOCTL_GET_VOLUME_ID, uint32_t * " id); > +.BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_BOTH, > +.BI " struct __fat_dirent[2] " entry); > +.BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_SHORT, > +.BI " struct __fat_dirent[2] " entry); > +.SH DESCRIPTION > +The > +.BR ioctl (2) > +function can be used to read and write metadata of the FAT filesystems that > +are not accessible using other system calls. > +.SS Reading and setting file attributes > +Files and directories in the FAT filesystem possess an attribute bit mask that > +can be read with > +.B FAT_IOCTL_GET_ATTRIBUTES > +and written with > +.BR FAT_IOCTL_SET_ATTRIBUTES . > +.PP > +The > +.I fd > +argument contains a file descriptor for the file or directory. > +It is sufficient to create the file descriptor by calling > +.BR open (2) > +with the > +.B O_RDONLY > +flag. > +.PP > +The > +.I attr > +argument contains a pointer to the bit mask. > +The bits of the bit mask are > +.TP > +.B ATTR_RO > +This bit specifies that the file or directory is read-only. It's too bad that these constants have such generic names. It would be better to use MSDOS_ATTR_* or FAT_ATTR_*, since these are also exposed to userspace, but are only used by FAT. > +.TP > +.B ATTR_HIDDEN > +This bit specifies that the file or directory is hidden. > +.TP > +.B ATTR_SYS > +This bit specifies that the file is a system file. It might be useful if the FS_IOC_GETFLAGS ioctl was implemented for FAT, and this was mapped to FS_IMMUTABLE_FL as it is in the kernel, so that the more common lsattr and chattr commands worked on it, as they do with ext*, btrfs, xfs, reiserfs, etc. I guess these aren't problems with the man page per-se, but something for the FAT developers to think about. Cheers, Andreas > +.TP > +.B ATTR_VOLUME > +This bit specifies that the file is a volume label. > +This attribute is read-only. > +.TP > +.B ATTR_DIR > +This bit specifies that this is a directory. > +This attribute is read-only. > +.TP > +.B ATTR_ARCH > +This bit indicates that this file or directory should be archived. > +It is set when a file is created or modified. > +It is reset by an archiving system. > +.PP > +The zero value > +.B ATTR_NONE > +can be used to indicate that no attribute bit is set. > +.SS Reading the volume label > +Fat filesystems are identified by a volume label. > +The volume label can be read with > +.BR FAT_IOCTL_GET_VOLUME_ID . > +.PP > +The > +.I fd > +argument can be a file descriptor for any file or directory of the > +filesystem. > +It is sufficient to create the file descriptor by calling > +.BR open (2) > +with the > +.B O_RDONLY > +flag. > +.PP > +The > +.I id > +argument is a pointer to the field that will be filled with the volume ID. > +Typically the volume label is displayed to the user as a group of two > +16-bit fields. > +.PP > +.in +4n > +.nf > +printf("Volume ID %4x-%4x\\n", id >> 16, id & 0xFFFF); > +.fi > +.in > +.SS Reading short file names of a directory > +A file or directory on a FAT filesystem always has a short filename > +consisting of up to 8 capital letters, optionally followed by a period > +and up to 3 capital letters for the file extension. > +If the actual filename does not fit into this scheme, it is stored > +as a long filename of up to 255 UTF-16 characters. > +.PP > +The short filenames in a directory can be read with > +.BR VFAT_IOCTL_READDIR_SHORT . > +.B VFAT_IOCTL_READDIR_BOTH > +reads both the short and the long filenames. > +.PP > +The > +.I fd > +argument must be a file descriptor for a directory. > +It is sufficient to create the file descriptor by calling > +.BR open (2) > +with the > +.B O_RDONLY > +flag. > +The file descriptor can be only used once to iterate over the directory > +entries by calling > +.BR ioctl (2) > +repeatedly. > +.PP > +The > +.I entry > +argument is a two-element array of the following structures. > + > +.in +4n > +.nf > +struct __fat_dirent { > + long d_ino; > + __kernel_off_t d_off; > + uint32_t short d_reclen; > + char d_name[256]; > +}; > +.fi > +.in > +.PP > +The first entry in the array is for the short filename. > +The second entry is for the long filename. > +.PP > +Field > +.I d_reclen > +specifies the length of the filename in field > +.IR d_name . > +A length of 0 for the short filename signals that the end of the directory > +has been reached. > +.SH RETURN VALUE > +On error, -1 is returned, and errno is set to indicate the error. > +.SH ERRORS > +.TP > +.B ENOTDIR > +This error is returned by > +.B VFAT_IOCTL_READDIR_SHORT > +and > +.B VFAT_IOCTL_READDIR_SHORT > +if the file descriptor does not point to a directory. > +.TP > +.B ENOTTY > +This error signals that the file descriptor is not for a FAT filesystem. > +.PP > +For further error values see > +.BR ioctl (2). > +.SH VERSIONS > +.B FAT_IOCTL_GET_VOLUME_ID > +was introduced in version 3.11 of the Linux kernel. > +.PP > +.BR FAT_IOCTL_GET_ATTRIBUTES , > +.BR FAT_IOCTL_SET_ATTRIBUTES , > +.BR VFAT_IOCTL_READDIR_BOTH , > +and > +.B VFAT_IOCTL_READDIR_SHORT > +were introduced before version 2.6.28 of the Linux kernel. > +.SH "CONFORMING TO" > +This API is Linux-specific. > +.SH EXAMPLE > +.SS Toggling the archive flag > +The following program demonstrates the usage of the ioctl API to manipulate > +file attributes. > +It reads and displays the archive attribute of a file. > +After inverting the value of the attribute, it reads and displays it again. > +.PP > +The following was recorded when applying the program for the file > +.IR /mnt/user/foo . > +.SS Example output > +.in +4n > +.nf > +# ./toggle_archive_flag /mnt/user/foo > +Archive flag is set > +Toggling archive flag > +Archive flag is not set > +.fi > +.in > +.SS Program source > +.in +4n > +.nf > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* > + * Read file attributes of a file on a FAT filesystem. > + * Output the state of the archive flag. > + */ > +static uint32_t > +readattr(int fd) > +{ > + uint32_t attr; > + int ret; > + > + ret = ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, &attr); > + if (ret == \-1) { > + perror("ioctl"); > + exit(EXIT_FAILURE); > + } > + > + if (attr & ATTR_ARCH) > + printf("Archive flag is set\\n"); > + else > + printf("Archive flag is not set\\n"); > + > + return attr; > +} > + > +int > +main(int argc, char *argv[]) > +{ > + uint32_t attr; > + int fd; > + int ret; > + > + if (argc != 2) { > + printf("Usage: %s FILENAME\\n", argv[0]); > + exit(EXIT_FAILURE); > + } > + > + fd = open(argv[1], O_RDONLY); > + if (fd == \-1) { > + perror("open"); > + exit(EXIT_FAILURE); > + } > + > + /* > + * Read and display the FAT file attributes. > + */ > + attr = readattr(fd); > + > + /* > + * Invert archive attribute. > + */ > + printf("Toggling archive flag\\n"); > + attr ^= ATTR_ARCH; > + > + /* > + * Write the changed FAT file attributes. > + */ > + ret = ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr); > + if (ret == \-1) { > + perror("ioctl"); > + exit(EXIT_FAILURE); > + } > + > + /* > + * Read and display the FAT file attributes. > + */ > + readattr(fd); > + > + close(fd); > + > + return EXIT_SUCCESS; > +} > +.fi > +.in > +.SS Reading the volume label > +The following program demonstrates the usage of the ioctl API to > +display the volume label of a FAT filesystem. > +.PP > +The following output was recorded when applying the program for > +directory > +.IR /mnt/user . > +.SS Example output > +.in +4n > +.nf > +$ ./display_volume_id /mnt/user > +Volume ID 6443-6241 > +.fi > +.in > +.SS Program source > +.in +4n > +.nf > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +int > +main(int argc, char *argv[]) > +{ > + uint32_t id; > + int fd; > + int ret; > + > + if (argc != 2) { > + printf("Usage: %s FILENAME\\n", argv[0]); > + exit(EXIT_FAILURE); > + } > + > + fd = open(argv[1], O_RDONLY); > + if (fd == \-1) { > + perror("open"); > + exit(EXIT_FAILURE); > + } > + > + /* > + * Read volume ID. > + */ > + ret = ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &id); > + if (ret == \-1) { > + perror("ioctl"); > + exit(EXIT_FAILURE); > + } > + > + /* > + * Format the output as two groups of 16 bits each. > + */ > + printf("Volume ID %4x\-%4x\\n", id >> 16, id & 0xFFFF); > + > + close(fd); > + > + return EXIT_SUCCESS; > +} > +.fi > +.in > +.SS Listing a directory > +The following program demonstrates the usage of the ioctl API to > +list a directory. > +.PP > +The following was recorded when applying the program for the directory > +.IR /mnt/user . > +.SS Example output > +.in +4n > +.nf > +$ ./fat_dir /mnt/user > +\[char46] -> '' > +\[char46]. -> '' > +ALONGF~1.TXT -> 'a long filename.txt' > +UPPER.TXT -> '' > +LOWER.TXT -> 'lower.txt' > +.fi > +.in > +.SS Program source > +.in +4n > +.nf > +#include > +#include > +#include > +#include > +#include > +#include > + > +int > +main(int argc, char *argv[]) > +{ > + struct __fat_dirent entry[2]; > + int fd; > + int ret; > + > + if (argc != 2) { > + printf("Usage: %s DIRECTORY\\n", argv[0]); > + exit(EXIT_FAILURE); > + } > + > + /* > + * Open file descriptor for the directory. > + */ > + fd = open(argv[1], O_RDONLY | O_DIRECTORY); > + if (fd == \-1) { > + perror("open"); > + exit(EXIT_FAILURE); > + } > + > + for (;;) { > + > + /* > + * Read next directory entry. > + */ > + ret = ioctl( fd, VFAT_IOCTL_READDIR_BOTH, entry); > + > + /* > + * If an error occurs, the return value is \-1. > + * If d_reclen is zero, the end of the directory > + * list has been reached. > + */ > + if (ret == \-1 || entry[0].d_reclen == 0) > + break; > + > + /* > + * Write both the short name and the long name. > + */ > + printf("%s \-> '%s'\\n", entry[0].d_name, entry[1].d_name); > + } > + if (ret == \-1) { > + perror("VFAT_IOCTL_READDIR_BOTH"); > + exit(EXIT_FAILURE); > + } > + > + /* > + * Close the file descriptor. > + */ > + close(fd); > + > + return EXIT_SUCCESS; > +} > +.fi > +.in > +.SH SEE ALSO > +.BR ioctl (2) > -- > 2.1.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Cheers, Andreas -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/