fs/adfs: add time stamp and file type helpers
authorRussell King <rmk+kernel@armlinux.org.uk>
Tue, 4 Jun 2019 13:50:24 +0000 (14:50 +0100)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 27 Jun 2019 00:14:14 +0000 (20:14 -0400)
Add some helpers to check whether the inode has a time stamp and file
type, and to parse the file type from the load address.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/adfs/adfs.h
fs/adfs/dir.c
fs/adfs/inode.c
fs/adfs/super.c

index 9eb9bea..b7e844d 100644 (file)
@@ -9,6 +9,15 @@
 #define ADFS_BAD_FRAG           1
 #define ADFS_ROOT_FRAG          2
 
+#define ADFS_FILETYPE_NONE     ((u16)~0)
+
+/* RISC OS 12-bit filetype is stored in load_address[19:8] */
+static inline u16 adfs_filetype(u32 loadaddr)
+{
+       return (loadaddr & 0xfff00000) == 0xfff00000 ?
+              (loadaddr >> 8) & 0xfff : ADFS_FILETYPE_NONE;
+}
+
 #define ADFS_NDA_OWNER_READ    (1 << 0)
 #define ADFS_NDA_OWNER_WRITE   (1 << 1)
 #define ADFS_NDA_LOCKED                (1 << 2)
@@ -27,12 +36,20 @@ struct adfs_inode_info {
        __u32           parent_id;      /* parent indirect disc address */
        __u32           loadaddr;       /* RISC OS load address         */
        __u32           execaddr;       /* RISC OS exec address         */
-       unsigned int    filetype;       /* RISC OS file type            */
        unsigned int    attr;           /* RISC OS permissions          */
-       unsigned int    stamped:1;      /* RISC OS file has date/time   */
        struct inode vfs_inode;
 };
 
+static inline struct adfs_inode_info *ADFS_I(struct inode *inode)
+{
+       return container_of(inode, struct adfs_inode_info, vfs_inode);
+}
+
+static inline bool adfs_inode_is_stamped(struct inode *inode)
+{
+       return (ADFS_I(inode)->loadaddr & 0xfff00000) == 0xfff00000;
+}
+
 /*
  * Forward-declare this
  */
@@ -68,11 +85,6 @@ static inline struct adfs_sb_info *ADFS_SB(struct super_block *sb)
        return sb->s_fs_info;
 }
 
-static inline struct adfs_inode_info *ADFS_I(struct inode *inode)
-{
-       return container_of(inode, struct adfs_inode_info, vfs_inode);
-}
-
 /*
  * Directory handling
  */
@@ -105,9 +117,6 @@ struct object_info {
        __u8            attr;                   /* RISC OS attributes   */
        unsigned int    name_len;               /* name length          */
        char            name[ADFS_MAX_NAME_LEN];/* file name            */
-
-       /* RISC OS file type (12-bit: derived from loadaddr) */
-       __u16           filetype;
 };
 
 struct adfs_dir_ops {
index 01ffd47..77503d1 100644 (file)
@@ -38,20 +38,14 @@ void adfs_object_fixup(struct adfs_dir *dir, struct object_info *obj)
        if (obj->name_len <= 2 && dots == obj->name_len)
                obj->name[0] = '^';
 
-       obj->filetype = -1;
-
        /*
-        * object is a file and is filetyped and timestamped?
-        * RISC OS 12-bit filetype is stored in load_address[19:8]
+        * If the object is a file, and the user requested the ,xyz hex
+        * filetype suffix to the name, check the filetype and append.
         */
-       if ((0 == (obj->attr & ADFS_NDA_DIRECTORY)) &&
-           (0xfff00000 == (0xfff00000 & obj->loadaddr))) {
-               obj->filetype = (__u16) ((0x000fff00 & obj->loadaddr) >> 8);
-
-               /* optionally append the ,xyz hex filetype suffix */
-               if (ADFS_SB(dir->sb)->s_ftsuffix) {
-                       __u16 filetype = obj->filetype;
+       if (!(obj->attr & ADFS_NDA_DIRECTORY) && ADFS_SB(dir->sb)->s_ftsuffix) {
+               u16 filetype = adfs_filetype(obj->loadaddr);
 
+               if (filetype != ADFS_FILETYPE_NONE) {
                        obj->name[obj->name_len++] = ',';
                        obj->name[obj->name_len++] = hex_asc_lo(filetype >> 8);
                        obj->name[obj->name_len++] = hex_asc_lo(filetype >> 4);
index 5f5af66..d61c745 100644 (file)
@@ -97,7 +97,7 @@ adfs_atts2mode(struct super_block *sb, struct inode *inode)
                return S_IFDIR | S_IXUGO | mode;
        }
 
-       switch (ADFS_I(inode)->filetype) {
+       switch (adfs_filetype(ADFS_I(inode)->loadaddr)) {
        case 0xfc0:     /* LinkFS */
                return S_IFLNK|S_IRWXUGO;
 
@@ -177,7 +177,7 @@ adfs_adfs2unix_time(struct timespec64 *tv, struct inode *inode)
                                                        2208988800000000000LL;
        s64 nsec;
 
-       if (ADFS_I(inode)->stamped == 0)
+       if (!adfs_inode_is_stamped(inode))
                goto cur_time;
 
        high = ADFS_I(inode)->loadaddr & 0xFF; /* top 8 bits of timestamp */
@@ -216,7 +216,7 @@ adfs_unix2adfs_time(struct inode *inode, unsigned int secs)
 {
        unsigned int high, low;
 
-       if (ADFS_I(inode)->stamped) {
+       if (adfs_inode_is_stamped(inode)) {
                /* convert 32-bit seconds to 40-bit centi-seconds */
                low  = (secs & 255) * 100;
                high = (secs / 256) * 100 + (low >> 8) + 0x336e996a;
@@ -266,8 +266,6 @@ adfs_iget(struct super_block *sb, struct object_info *obj)
        ADFS_I(inode)->loadaddr  = obj->loadaddr;
        ADFS_I(inode)->execaddr  = obj->execaddr;
        ADFS_I(inode)->attr      = obj->attr;
-       ADFS_I(inode)->filetype  = obj->filetype;
-       ADFS_I(inode)->stamped   = ((obj->loadaddr & 0xfff00000) == 0xfff00000);
 
        inode->i_mode    = adfs_atts2mode(sb, inode);
        adfs_adfs2unix_time(&inode->i_mtime, inode);
index d029ae1..89b159c 100644 (file)
@@ -490,7 +490,6 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
        root_obj.size      = ADFS_NEWDIR_SIZE;
        root_obj.attr      = ADFS_NDA_DIRECTORY   | ADFS_NDA_OWNER_READ |
                             ADFS_NDA_OWNER_WRITE | ADFS_NDA_PUBLIC_READ;
-       root_obj.filetype  = -1;
 
        /*
         * If this is a F+ disk with variable length directories,