From: Jan Blunck <jblunck@suse.de>
To: Valerie Aurora <vaurora@redhat.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Theodore Tso <tytso@mit.edu>,
linux-ext4@vger.kernel.org, David Woodhouse <dwmw2@infradead.org>
Subject: Re: [PATCH 13/35] fallthru: ext2 fallthru support
Date: Mon, 19 Apr 2010 14:40:25 +0200 [thread overview]
Message-ID: <20100419124025.GG10776@bolzano.suse.de> (raw)
In-Reply-To: <1271372682-21225-14-git-send-email-vaurora@redhat.com>
On Thu, Apr 15, Valerie Aurora wrote:
> Add support for fallthru directory entries to ext2.
>
> XXX - Makes up inode number for fallthru entry
> XXX - Might be better implemented as special symlinks
Better not. David Woodhouse actually convinced me of moving away from the
special symlink approach. The whiteouts have been implemented as special
symlinks before.
What makes you think that it would be beneficial to do so?
Thanks,
Jan
> Cc: Theodore Tso <tytso@mit.edu>
> Cc: linux-ext4@vger.kernel.org
> Signed-off-by: Valerie Aurora <vaurora@redhat.com>
> Signed-off-by: Jan Blunck <jblunck@suse.de>
> ---
> fs/ext2/dir.c | 92 ++++++++++++++++++++++++++++++++++++++++++++--
> fs/ext2/ext2.h | 1 +
> fs/ext2/namei.c | 22 +++++++++++
> include/linux/ext2_fs.h | 1 +
> 4 files changed, 112 insertions(+), 4 deletions(-)
>
> diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
> index 030bd46..f3b4aff 100644
> --- a/fs/ext2/dir.c
> +++ b/fs/ext2/dir.c
> @@ -219,7 +219,8 @@ static inline int ext2_match (int len, const char * const name,
> {
> if (len != de->name_len)
> return 0;
> - if (!de->inode && (de->file_type != EXT2_FT_WHT))
> + if (!de->inode && ((de->file_type != EXT2_FT_WHT) &&
> + (de->file_type != EXT2_FT_FALLTHRU)))
> return 0;
> return !memcmp(name, de->name, len);
> }
> @@ -256,6 +257,7 @@ static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
> [EXT2_FT_SOCK] = DT_SOCK,
> [EXT2_FT_SYMLINK] = DT_LNK,
> [EXT2_FT_WHT] = DT_WHT,
> + [EXT2_FT_FALLTHRU] = DT_UNKNOWN,
> };
>
> #define S_SHIFT 12
> @@ -342,6 +344,24 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
> ext2_put_page(page);
> return 0;
> }
> + } else if (de->file_type == EXT2_FT_FALLTHRU) {
> + int over;
> + unsigned char d_type = DT_UNKNOWN;
> +
> + offset = (char *)de - kaddr;
> + /* XXX We don't know the inode number
> + * of the directory entry in the
> + * underlying file system. Should
> + * look it up, either on fallthru
> + * creation at first readdir or now at
> + * filldir time. */
> + over = filldir(dirent, de->name, de->name_len,
> + (n<<PAGE_CACHE_SHIFT) | offset,
> + 123 /* Made up ino */, d_type);
> + if (over) {
> + ext2_put_page(page);
> + return 0;
> + }
> }
> filp->f_pos += ext2_rec_len_from_disk(de->rec_len);
> }
> @@ -463,6 +483,10 @@ ino_t ext2_inode_by_dentry(struct inode *dir, struct dentry *dentry)
> spin_lock(&dentry->d_lock);
> dentry->d_flags |= DCACHE_WHITEOUT;
> spin_unlock(&dentry->d_lock);
> + } else if(!res && de->file_type == EXT2_FT_FALLTHRU) {
> + spin_lock(&dentry->d_lock);
> + dentry->d_flags |= DCACHE_FALLTHRU;
> + spin_unlock(&dentry->d_lock);
> }
> ext2_put_page(page);
> }
> @@ -532,6 +556,7 @@ static ext2_dirent * ext2_append_entry(struct dentry * dentry,
> de->name_len = 0;
> de->rec_len = ext2_rec_len_to_disk(chunk_size);
> de->inode = 0;
> + de->file_type = 0;
> goto got_it;
> }
> if (de->rec_len == 0) {
> @@ -545,6 +570,7 @@ static ext2_dirent * ext2_append_entry(struct dentry * dentry,
> name_len = EXT2_DIR_REC_LEN(de->name_len);
> rec_len = ext2_rec_len_from_disk(de->rec_len);
> if (!de->inode && (de->file_type != EXT2_FT_WHT) &&
> + (de->file_type != EXT2_FT_FALLTHRU) &&
> (rec_len >= reclen))
> goto got_it;
> if (rec_len >= name_len + reclen)
> @@ -587,7 +613,8 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
>
> err = -EEXIST;
> if (ext2_match (namelen, name, de)) {
> - if (de->file_type == EXT2_FT_WHT)
> + if ((de->file_type == EXT2_FT_WHT) ||
> + (de->file_type == EXT2_FT_FALLTHRU))
> goto got_it;
> goto out_unlock;
> }
> @@ -602,7 +629,8 @@ got_it:
> &page, NULL);
> if (err)
> goto out_unlock;
> - if (de->inode || ((de->file_type == EXT2_FT_WHT) &&
> + if (de->inode || (((de->file_type == EXT2_FT_WHT) ||
> + (de->file_type == EXT2_FT_FALLTHRU)) &&
> !ext2_match (namelen, name, de))) {
> ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
> de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
> @@ -627,6 +655,60 @@ out_unlock:
> }
>
> /*
> + * Create a fallthru entry.
> + */
> +int ext2_fallthru_entry (struct inode *dir, struct dentry *dentry)
> +{
> + const char *name = dentry->d_name.name;
> + int namelen = dentry->d_name.len;
> + unsigned short rec_len, name_len;
> + ext2_dirent * de;
> + struct page *page;
> + loff_t pos;
> + int err;
> +
> + de = ext2_append_entry(dentry, &page);
> + if (IS_ERR(de))
> + return PTR_ERR(de);
> +
> + err = -EEXIST;
> + if (ext2_match (namelen, name, de))
> + goto out_unlock;
> +
> + name_len = EXT2_DIR_REC_LEN(de->name_len);
> + rec_len = ext2_rec_len_from_disk(de->rec_len);
> +
> + pos = page_offset(page) +
> + (char*)de - (char*)page_address(page);
> + err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
> + &page, NULL);
> + if (err)
> + goto out_unlock;
> + if (de->inode || (de->file_type == EXT2_FT_WHT) ||
> + (de->file_type == EXT2_FT_FALLTHRU)) {
> + ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
> + de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
> + de->rec_len = ext2_rec_len_to_disk(name_len);
> + de = de1;
> + }
> + de->name_len = namelen;
> + memcpy(de->name, name, namelen);
> + de->inode = 0;
> + de->file_type = EXT2_FT_FALLTHRU;
> + err = ext2_commit_chunk(page, pos, rec_len);
> + dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
> + EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
> + mark_inode_dirty(dir);
> + /* OFFSET_CACHE */
> +out_put:
> + ext2_put_page(page);
> + return err;
> +out_unlock:
> + unlock_page(page);
> + goto out_put;
> +}
> +
> +/*
> * ext2_delete_entry deletes a directory entry by merging it with the
> * previous entry. Page is up-to-date. Releases the page.
> */
> @@ -711,7 +793,9 @@ int ext2_whiteout_entry (struct inode * dir, struct dentry * dentry,
> */
> if (ext2_match (namelen, name, de))
> de->inode = 0;
> - if (de->inode || (de->file_type == EXT2_FT_WHT)) {
> + if (de->inode || (((de->file_type == EXT2_FT_WHT) ||
> + (de->file_type == EXT2_FT_FALLTHRU)) &&
> + !ext2_match (namelen, name, de))) {
> ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
> de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
> de->rec_len = ext2_rec_len_to_disk(name_len);
> diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
> index 44d190c..2fa32b3 100644
> --- a/fs/ext2/ext2.h
> +++ b/fs/ext2/ext2.h
> @@ -108,6 +108,7 @@ extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct qstr *,
> extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
> extern int ext2_whiteout_entry (struct inode *, struct dentry *,
> struct ext2_dir_entry_2 *, struct page *);
> +extern int ext2_fallthru_entry (struct inode *, struct dentry *);
> extern int ext2_empty_dir (struct inode *);
> extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
> extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int);
> diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
> index 12195a5..f28154c 100644
> --- a/fs/ext2/namei.c
> +++ b/fs/ext2/namei.c
> @@ -349,6 +349,7 @@ static int ext2_whiteout(struct inode *dir, struct dentry *dentry,
> goto out;
>
> spin_lock(&new_dentry->d_lock);
> + new_dentry->d_flags &= ~DCACHE_FALLTHRU;
> new_dentry->d_flags |= DCACHE_WHITEOUT;
> spin_unlock(&new_dentry->d_lock);
> d_add(new_dentry, NULL);
> @@ -367,6 +368,26 @@ out:
> return err;
> }
>
> +/*
> + * Create a fallthru entry.
> + */
> +static int ext2_fallthru (struct inode *dir, struct dentry *dentry)
> +{
> + int err;
> +
> + dquot_initialize(dir);
> +
> + err = ext2_fallthru_entry(dir, dentry);
> + if (err)
> + return err;
> +
> + d_instantiate(dentry, NULL);
> + spin_lock(&dentry->d_lock);
> + dentry->d_flags |= DCACHE_FALLTHRU;
> + spin_unlock(&dentry->d_lock);
> + return 0;
> +}
> +
> static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
> struct inode * new_dir, struct dentry * new_dentry )
> {
> @@ -470,6 +491,7 @@ const struct inode_operations ext2_dir_inode_operations = {
> .rmdir = ext2_rmdir,
> .mknod = ext2_mknod,
> .whiteout = ext2_whiteout,
> + .fallthru = ext2_fallthru,
> .rename = ext2_rename,
> #ifdef CONFIG_EXT2_FS_XATTR
> .setxattr = generic_setxattr,
> diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
> index 20468bd..cb3d400 100644
> --- a/include/linux/ext2_fs.h
> +++ b/include/linux/ext2_fs.h
> @@ -577,6 +577,7 @@ enum {
> EXT2_FT_SOCK = 6,
> EXT2_FT_SYMLINK = 7,
> EXT2_FT_WHT = 8,
> + EXT2_FT_FALLTHRU = 9,
> EXT2_FT_MAX
> };
>
> --
> 1.6.3.3
>
Regards,
Jan
--
Jan Blunck <jblunck@suse.de>
next prev parent reply other threads:[~2010-04-19 12:40 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-15 23:04 [PATCH 00/35] Union mounts - everything but the xattrs Valerie Aurora
2010-04-15 23:04 ` [PATCH 01/35] VFS: Make lookup_hash() return a struct path Valerie Aurora
2010-04-15 23:04 ` [PATCH 02/35] VFS: Add read-only users count to superblock Valerie Aurora
[not found] ` <1271372682-21225-4-git-send-email-vaurora@redhat.com>
2010-04-15 23:04 ` [PATCH 04/35] whiteout/NFSD: Don't return information about whiteouts to userspace Valerie Aurora
2010-04-15 23:04 ` [PATCH 05/35] whiteout: Add vfs_whiteout() and whiteout inode operation Valerie Aurora
2010-04-15 23:04 ` [PATCH 06/35] whiteout: Set S_OPAQUE inode flag when creating directories Valerie Aurora
2010-04-15 23:04 ` [PATCH 07/35] whiteout: Allow removal of a directory with whiteouts Valerie Aurora
2010-04-15 23:04 ` [PATCH 08/35] whiteout: tmpfs whiteout support Valerie Aurora
2010-04-15 23:04 ` [PATCH 09/35] whiteout: Split of ext2_append_link() from ext2_add_link() Valerie Aurora
2010-04-15 23:04 ` [PATCH 10/35] whiteout: ext2 whiteout support Valerie Aurora
2010-04-15 23:04 ` [PATCH 11/35] whiteout: jffs2 " Valerie Aurora
2010-04-15 23:04 ` [PATCH 12/35] fallthru: Basic fallthru definitions Valerie Aurora
2010-04-15 23:04 ` [PATCH 13/35] fallthru: ext2 fallthru support Valerie Aurora
2010-04-15 23:04 ` [PATCH 14/35] fallthru: jffs2 " Valerie Aurora
2010-04-15 23:04 ` [PATCH 15/35] fallthru: tmpfs " Valerie Aurora
2010-04-15 23:04 ` [PATCH 16/35] union-mount: Writable overlays/union mounts documentation Valerie Aurora
2010-04-15 23:04 ` [PATCH 17/35] union-mount: Introduce MNT_UNION and MS_UNION flags Valerie Aurora
2010-04-15 23:04 ` [PATCH 18/35] union-mount: Introduce union_mount structure and basic operations Valerie Aurora
2010-04-15 23:04 ` [PATCH 19/35] union-mount: Drive the union cache via dcache Valerie Aurora
2010-04-15 23:04 ` [PATCH 20/35] union-mount: Implement union lookup Valerie Aurora
2010-04-15 23:04 ` [PATCH 21/35] union-mount: Support for mounting union mount file systems Valerie Aurora
2010-04-15 23:04 ` [PATCH 22/35] union-mount: Call do_whiteout() on unlink and rmdir in unions Valerie Aurora
2010-04-15 23:04 ` [PATCH 23/35] union-mount: Copy up directory entries on first readdir() Valerie Aurora
2010-04-15 23:04 ` [PATCH 24/35] VFS: Split inode_permission() and create path_permission() Valerie Aurora
2010-04-15 23:04 ` [PATCH 25/35] VFS: Create user_path_nd() to lookup both parent and target Valerie Aurora
2010-04-15 23:04 ` [PATCH 26/35] union-mount: In-kernel copyup routines Valerie Aurora
2010-04-15 23:04 ` [PATCH 27/35] union-mount: Implement union-aware access()/faccessat() Valerie Aurora
2010-04-15 23:04 ` [PATCH 28/35] union-mount: Implement union-aware link() Valerie Aurora
2010-04-15 23:04 ` [PATCH 29/35] union-mount: Implement union-aware rename() Valerie Aurora
2010-04-15 23:04 ` [PATCH 30/35] union-mount: Implement union-aware writable open() Valerie Aurora
2010-04-15 23:04 ` [PATCH 31/35] union-mount: Implement union-aware chown() Valerie Aurora
2010-04-15 23:04 ` [PATCH 32/35] union-mount: Implement union-aware truncate() Valerie Aurora
2010-04-15 23:04 ` [PATCH 33/35] union-mount: Implement union-aware chmod()/fchmodat() Valerie Aurora
2010-04-15 23:04 ` [PATCH 34/35] union-mount: Implement union-aware lchown() Valerie Aurora
2010-04-15 23:04 ` [PATCH 35/35] union-mount: Implement union-aware utimensat() Valerie Aurora
2010-04-20 16:30 ` [PATCH 16/35] union-mount: Writable overlays/union mounts documentation Miklos Szeredi
2010-04-28 20:19 ` Valerie Aurora
2010-04-29 9:33 ` Miklos Szeredi
2010-04-29 20:20 ` Valerie Aurora
2010-05-10 12:57 ` Miklos Szeredi
2010-05-17 19:55 ` Valerie Aurora
2010-04-29 16:10 ` J. R. Okajima
2010-04-19 12:40 ` Jan Blunck [this message]
2010-04-19 13:02 ` [PATCH 13/35] fallthru: ext2 fallthru support David Woodhouse
2010-04-19 13:23 ` Jan Blunck
2010-04-19 13:30 ` Jamie Lokier
2010-04-19 14:12 ` Jan Blunck
2010-04-19 14:23 ` Valerie Aurora
2010-04-19 14:53 ` Miklos Szeredi
2010-04-20 21:34 ` Jamie Lokier
2010-04-21 8:42 ` Jan Blunck
2010-04-21 9:22 ` Jamie Lokier
2010-04-21 9:34 ` Miklos Szeredi
2010-04-21 9:52 ` Jamie Lokier
2010-04-21 10:17 ` Miklos Szeredi
2010-04-21 17:36 ` Jamie Lokier
2010-04-21 21:34 ` Valerie Aurora
2010-04-21 21:38 ` Valerie Aurora
2010-04-21 22:10 ` Jamie Lokier
2010-04-22 10:30 ` J. R. Okajima
2010-04-20 21:40 ` Jamie Lokier
2010-04-19 13:03 ` [PATCH 11/35] whiteout: jffs2 whiteout support David Woodhouse
2010-04-19 14:26 ` Valerie Aurora
2010-04-16 15:59 ` [PATCH 04/35] whiteout/NFSD: Don't return information about whiteouts to userspace J. Bruce Fields
2010-04-19 12:37 ` Jan Blunck
2010-04-19 13:54 ` J. Bruce Fields
2010-04-15 23:45 ` [PATCH 03/35] autofs4: Save autofs trigger's vfsmount in super block info Valerie Aurora
2010-04-21 22:06 ` [PATCH 00/35] Union mounts - everything but the xattrs Randy Dunlap
2010-04-21 23:35 ` Valerie Aurora
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=20100419124025.GG10776@bolzano.suse.de \
--to=jblunck@suse.de \
--cc=dwmw2@infradead.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=vaurora@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome