From: arnd@arndb.de
To: linux-fsdevel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hch@lst.de
Subject: [RFC 6/7] cramfs: read directory entries from dcache
Date: Sat, 31 May 2008 17:20:19 +0200 [thread overview]
Message-ID: <20080531153511.204364754@arndb.de> (raw)
In-Reply-To: 20080531152013.031903990@arndb.de
[-- Attachment #1: 0006-cramfs-read-directory-entries-from-dcache.patch --]
[-- Type: text/plain, Size: 3954 bytes --]
When we create new files in a mounted cramfs, they
only appear in the dcache, so we need to have a combined
dcache_readdir plus cramfs_readdir to get all of them.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
fs/cramfs/inode.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 0d3ac80..e7d2b47 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -324,6 +324,46 @@ static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf)
return 0;
}
+/* Relationship between i_mode and the DT_xxx types */
+static inline unsigned char dt_type(struct inode *inode)
+{
+ return (inode->i_mode >> 12) & 15;
+}
+
+static int cramfs_readdir_cache(struct file *filp, void *dirent, filldir_t filldir)
+{
+ struct dentry *dentry = filp->f_path.dentry;
+ struct dentry *cursor = filp->private_data;
+ struct list_head *p, *q = &cursor->d_u.d_child;
+
+ /* taken from dcache_readdir */
+ spin_lock(&dcache_lock);
+ if (filp->f_pos == 2)
+ list_move(q, &dentry->d_subdirs);
+
+ for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
+ struct dentry *next;
+ next = list_entry(p, struct dentry, d_u.d_child);
+ if (d_unhashed(next) || !next->d_inode ||
+ next->d_inode->i_private) // FIXME: renames are broken
+ continue;
+
+ spin_unlock(&dcache_lock);
+ if (filldir(dirent, next->d_name.name,
+ next->d_name.len, filp->f_pos,
+ next->d_inode->i_ino,
+ dt_type(next->d_inode)) < 0)
+ return 0;
+ spin_lock(&dcache_lock);
+ /* next is still alive */
+ list_move(q, p);
+ p = q;
+ filp->f_pos++;
+ }
+ spin_unlock(&dcache_lock);
+ return 0;
+}
+
/*
* Read a cramfs directory entry.
*/
@@ -407,8 +447,59 @@ static int cramfs_readdir_ondisk(struct dentry *dentry, void *dirent,
static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
- return cramfs_readdir_ondisk(filp->f_dentry, dirent,
+ loff_t offset = filp->f_pos;
+ struct dentry *dentry = filp->f_path.dentry;
+ int ret;
+
+ ret = 0;
+ if (offset < dentry->d_inode->i_size)
+ ret = cramfs_readdir_ondisk(dentry, dirent,
filldir, &filp->f_pos);
+ if (ret)
+ return ret;
+
+ return cramfs_readdir_cache(filp, dirent, filldir);
+}
+
+static loff_t cramfs_dir_lseek(struct file *file, loff_t offset, int origin)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ mutex_lock(&inode->i_mutex);
+ switch (origin) {
+ case 1:
+ offset += file->f_pos;
+ case 0:
+ if (offset >= 0)
+ break;
+ default:
+ mutex_unlock(&inode->i_mutex);
+ return -EINVAL;
+ }
+
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ if (file->f_pos >= inode->i_size) {
+ struct list_head *p;
+ struct dentry *cursor = file->private_data;
+ loff_t n = file->f_pos - inode->i_size;
+
+ spin_lock(&dcache_lock);
+ list_del(&cursor->d_u.d_child);
+ p = file->f_path.dentry->d_subdirs.next;
+ while (n && p != &file->f_path.dentry->d_subdirs) {
+ struct dentry *next;
+ next = list_entry(p, struct dentry, d_u.d_child);
+ if (!d_unhashed(next) && next->d_inode &&
+ !next->d_inode->i_private) // FIXME: renames are broken)
+ n--;
+ p = p->next;
+ }
+ list_add_tail(&cursor->d_u.d_child, p);
+ spin_unlock(&dcache_lock);
+ }
+ }
+ mutex_unlock(&inode->i_mutex);
+ return offset;
}
int cramfs_unlink(struct inode *dir, struct dentry *dentry)
@@ -588,9 +679,12 @@ static const struct address_space_operations cramfs_aops = {
* A directory can only readdir
*/
static const struct file_operations cramfs_directory_operations = {
- .llseek = generic_file_llseek,
- .read = generic_read_dir,
+ .open = dcache_dir_open,
+ .release = dcache_dir_close,
+ .llseek = cramfs_dir_lseek,
+ .fsync = simple_sync_file,
.readdir = cramfs_readdir,
+ .read = generic_read_dir,
};
static const struct inode_operations cramfs_dir_inode_operations = {
--
1.5.4.3
--
next prev parent reply other threads:[~2008-05-31 15:39 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20080531152013.031903990@arndb.de>
2008-05-31 15:20 ` [RFC 1/7] cramfs: allow remount rw arnd
2008-05-31 15:20 ` [RFC 2/7] cramfs: create unique inode numbers arnd
2008-06-01 16:50 ` Jörn Engel
2008-06-01 16:50 ` Jörn Engel
2008-06-01 21:24 ` Arnd Bergmann
2008-06-01 21:24 ` Arnd Bergmann
2008-06-02 5:42 ` Jörn Engel
2008-06-02 5:42 ` Jörn Engel
2008-05-31 15:20 ` [RFC 3/7] cramfs: allow unlinking of files arnd
2008-06-01 16:54 ` Jörn Engel
2008-06-01 16:54 ` Jörn Engel
2008-06-01 21:28 ` Arnd Bergmann
2008-06-01 21:28 ` Arnd Bergmann
2008-05-31 15:20 ` [RFC 4/7] cramfs: allow rmdir arnd
2008-05-31 15:20 ` [RFC 5/7] cramfs: allow writing to existing files arnd
2008-05-31 15:20 ` arnd [this message]
2008-05-31 15:20 ` [RFC 7/7] cramfs: add missing inode operations arnd
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080531153511.204364754@arndb.de \
--to=arnd@arndb.de \
--cc=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.