OSDN Git Service

VFS: Split DCACHE_FILE_TYPE into regular and special types
authorDavid Howells <dhowells@redhat.com>
Thu, 29 Jan 2015 12:02:29 +0000 (12:02 +0000)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 22 Feb 2015 16:38:38 +0000 (11:38 -0500)
Split DCACHE_FILE_TYPE into DCACHE_REGULAR_TYPE (dentries representing regular
files) and DCACHE_SPECIAL_TYPE (representing blockdev, chardev, FIFO and
socket files).

d_is_reg() and d_is_special() are added to detect these subtypes and
d_is_file() is left as the union of the two.

This allows a number of places that use S_ISREG(dentry->d_inode->i_mode) to
use d_is_reg(dentry) instead.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c
include/linux/dcache.h

index e33a093..c71e373 100644 (file)
@@ -1677,7 +1677,7 @@ EXPORT_SYMBOL(d_set_fallthru);
 
 static unsigned d_flags_for_inode(struct inode *inode)
 {
-       unsigned add_flags = DCACHE_FILE_TYPE;
+       unsigned add_flags = DCACHE_REGULAR_TYPE;
 
        if (!inode)
                return DCACHE_MISS_TYPE;
@@ -1690,13 +1690,21 @@ static unsigned d_flags_for_inode(struct inode *inode)
                        else
                                inode->i_opflags |= IOP_LOOKUP;
                }
-       } else if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) {
-               if (unlikely(inode->i_op->follow_link))
+               goto type_determined;
+       }
+
+       if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) {
+               if (unlikely(inode->i_op->follow_link)) {
                        add_flags = DCACHE_SYMLINK_TYPE;
-               else
-                       inode->i_opflags |= IOP_NOFOLLOW;
+                       goto type_determined;
+               }
+               inode->i_opflags |= IOP_NOFOLLOW;
        }
 
+       if (unlikely(!S_ISREG(inode->i_mode)))
+               add_flags = DCACHE_SPECIAL_TYPE;
+
+type_determined:
        if (unlikely(IS_AUTOMOUNT(inode)))
                add_flags |= DCACHE_NEED_AUTOMOUNT;
        return add_flags;
index 728f5d3..d835879 100644 (file)
@@ -219,8 +219,9 @@ struct dentry_operations {
 #define DCACHE_WHITEOUT_TYPE           0x00100000 /* Whiteout dentry (stop pathwalk) */
 #define DCACHE_DIRECTORY_TYPE          0x00200000 /* Normal directory */
 #define DCACHE_AUTODIR_TYPE            0x00300000 /* Lookupless directory (presumed automount) */
-#define DCACHE_SYMLINK_TYPE            0x00400000 /* Symlink (or fallthru to such) */
-#define DCACHE_FILE_TYPE               0x00500000 /* Other file type (or fallthru to such) */
+#define DCACHE_REGULAR_TYPE            0x00400000 /* Regular file type (or fallthru to such) */
+#define DCACHE_SPECIAL_TYPE            0x00500000 /* Other file type (or fallthru to such) */
+#define DCACHE_SYMLINK_TYPE            0x00600000 /* Symlink (or fallthru to such) */
 
 #define DCACHE_MAY_FREE                        0x00800000
 #define DCACHE_FALLTHRU                        0x01000000 /* Fall through to lower layer */
@@ -455,9 +456,19 @@ static inline bool d_is_symlink(const struct dentry *dentry)
        return __d_entry_type(dentry) == DCACHE_SYMLINK_TYPE;
 }
 
+static inline bool d_is_reg(const struct dentry *dentry)
+{
+       return __d_entry_type(dentry) == DCACHE_REGULAR_TYPE;
+}
+
+static inline bool d_is_special(const struct dentry *dentry)
+{
+       return __d_entry_type(dentry) == DCACHE_SPECIAL_TYPE;
+}
+
 static inline bool d_is_file(const struct dentry *dentry)
 {
-       return __d_entry_type(dentry) == DCACHE_FILE_TYPE;
+       return d_is_reg(dentry) || d_is_special(dentry);
 }
 
 static inline bool d_is_negative(const struct dentry *dentry)