summaryrefslogtreecommitdiffstats
path: root/include/linux/dcache.h
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-03-29 13:47:12 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2018-07-11 09:58:38 +0200
commitb3fbfad7aeaf8ee36216e1d14b5d7be27ba612de (patch)
tree61299cecd2c49902ff831813daa81926bacd69db /include/linux/dcache.h
parent4c7b877a5c90bcf80d42086d246981f0686d1e27 (diff)
downloadbarebox-b3fbfad7aeaf8ee36216e1d14b5d7be27ba612de.tar.gz
barebox-b3fbfad7aeaf8ee36216e1d14b5d7be27ba612de.tar.xz
fs: dentry cache implementation
This adds the Linux dentry cache implementation to barebox. Until now every filesystem driver resolves the full path to a file for itself. This leads to code duplication and is error prone since resolving paths is a complicated task. Also it can narrow down the lookup performance since barebox only knows ASCII paths and has no way of caching lookups. With this patch we get the Linux dcache implementation. The path resolving code from fs/namei.c is nearly taken as-is, minus the RCU and locking code. Dcaching is made simple as of now: We simply cache everything and never release any dentries. Although we do reference counting for inodes and dentries it is effectively not used yet. We never free anything until a fs is unmounted in which case we free everything no matter if references are taken or not. This patch also contains a wrapper in fs/legacy.c to support filesystems with the old API. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'include/linux/dcache.h')
-rw-r--r--include/linux/dcache.h109
1 files changed, 107 insertions, 2 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index dfb466722c..16244129bf 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -53,6 +53,10 @@ struct dentry {
spinlock_t d_lock; /* per dentry lock */
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
+
+ unsigned int d_count;
+ const struct dentry_operations *d_op;
+
/*
* The next three fields are touched by __d_lookup. Place them here
* so they all fit in a cache line.
@@ -65,8 +69,8 @@ struct dentry {
/*
* d_child and d_rcu can share memory
*/
+ struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
- struct list_head d_alias; /* inode alias list */
unsigned long d_time; /* used by d_revalidate */
struct super_block *d_sb; /* The root of the dentry tree */
void *d_fsdata; /* fs-specific data */
@@ -74,7 +78,108 @@ struct dentry {
struct dcookie_struct *d_cookie; /* cookie, if any */
#endif
int d_mounted;
- unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
+ unsigned char *name; /* all names */
+};
+
+struct dentry_operations {
};
+struct dentry * d_make_root(struct inode *);
+void d_add(struct dentry *, struct inode *);
+struct dentry * d_alloc_anon(struct super_block *);
+void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op);
+void d_instantiate(struct dentry *dentry, struct inode *inode);
+void d_delete(struct dentry *);
+struct dentry *dget(struct dentry *);
+void dput(struct dentry *);
+
+#define DCACHE_ENTRY_TYPE 0x00700000
+#define DCACHE_MISS_TYPE 0x00000000 /* Negative dentry (maybe fallthru to nowhere) */
+#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_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_FALLTHRU 0x01000000 /* Fall through to lower layer */
+#define DCACHE_CANT_MOUNT 0x00000100
+#define DCACHE_MOUNTED 0x00010000 /* is a mountpoint */
+#define DCACHE_NEED_AUTOMOUNT 0x00020000 /* handle automount on this dir */
+#define DCACHE_MANAGED_DENTRY \
+ (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT)
+
+static inline bool d_mountpoint(const struct dentry *dentry)
+{
+ return dentry->d_flags & DCACHE_MOUNTED;
+}
+
+/*
+ * Directory cache entry type accessor functions.
+ */
+static inline unsigned __d_entry_type(const struct dentry *dentry)
+{
+ return dentry->d_flags & DCACHE_ENTRY_TYPE;
+}
+
+static inline bool d_is_miss(const struct dentry *dentry)
+{
+ return __d_entry_type(dentry) == DCACHE_MISS_TYPE;
+}
+
+static inline bool d_can_lookup(const struct dentry *dentry)
+{
+ return __d_entry_type(dentry) == DCACHE_DIRECTORY_TYPE;
+}
+
+static inline bool d_is_autodir(const struct dentry *dentry)
+{
+ return __d_entry_type(dentry) == DCACHE_AUTODIR_TYPE;
+}
+
+static inline bool d_is_dir(const struct dentry *dentry)
+{
+ return d_can_lookup(dentry) || d_is_autodir(dentry);
+}
+
+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_is_reg(dentry) || d_is_special(dentry);
+}
+
+static inline bool d_is_negative(const struct dentry *dentry)
+{
+ // TODO: check d_is_whiteout(dentry) also.
+ return d_is_miss(dentry);
+}
+
+static inline bool d_is_positive(const struct dentry *dentry)
+{
+ return !d_is_negative(dentry);
+}
+
+static inline struct inode *d_inode(const struct dentry *dentry)
+{
+ return dentry->d_inode;
+}
+
+#define IS_ROOT(x) ((x) == (x)->d_parent)
+
+char *dpath(struct dentry *dentry, struct dentry *root);
+
#endif /* __LINUX_DCACHE_H */