All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bharata B Rao <bharata@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org, Jan Blunck <j.blunck@tu-harburg.de>
Subject: [RFC][PATCH 13/14] ext3 whiteout support
Date: Mon, 14 May 2007 15:14:50 +0530	[thread overview]
Message-ID: <20070514094450.GO4139@in.ibm.com> (raw)
In-Reply-To: <20070514093722.GB4139@in.ibm.com>

From: Bharata B Rao <bharata@linux.vnet.ibm.com>
Subject: ext3 whiteout support

Introduce whiteout support for ext3.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: Jan Blunck <jblunck@suse.de>
---
 fs/ext3/dir.c           |    2 -
 fs/ext3/namei.c         |   62 ++++++++++++++++++++++++++++++++++++++++++++----
 fs/ext3/super.c         |   11 +++++++-
 include/linux/ext3_fs.h |    5 +++
 4 files changed, 72 insertions(+), 8 deletions(-)

--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -29,7 +29,7 @@
 #include <linux/rbtree.h>
 
 static unsigned char ext3_filetype_table[] = {
-	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK, DT_WHT
 };
 
 static int ext3_readdir(struct file *, void *, filldir_t);
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1071,6 +1071,7 @@ static unsigned char ext3_type_by_mode[S
 	[S_IFIFO >> S_SHIFT]	= EXT3_FT_FIFO,
 	[S_IFSOCK >> S_SHIFT]	= EXT3_FT_SOCK,
 	[S_IFLNK >> S_SHIFT]	= EXT3_FT_SYMLINK,
+	[S_IFWHT >> S_SHIFT]	= EXT3_FT_WHT,
 };
 
 static inline void ext3_set_de_type(struct super_block *sb,
@@ -1786,7 +1787,7 @@ out_stop:
 /*
  * routine to check that the specified directory is empty (for rmdir)
  */
-static int empty_dir (struct inode * inode)
+static int empty_dir (handle_t *handle, struct inode * inode)
 {
 	unsigned long offset;
 	struct buffer_head * bh;
@@ -1848,8 +1849,28 @@ static int empty_dir (struct inode * ino
 			continue;
 		}
 		if (le32_to_cpu(de->inode)) {
-			brelse (bh);
-			return 0;
+			/* If this is a whiteout, remove it */
+			if (de->file_type == EXT3_FT_WHT) {
+				unsigned long ino = le32_to_cpu(de->inode);
+				struct inode *tmp_inode = iget(inode->i_sb, ino);
+				if (!tmp_inode) {
+					brelse (bh);
+					return 0;
+				}
+
+				if (ext3_delete_entry(handle, inode, de, bh)) {
+					iput(tmp_inode);
+					brelse (bh);
+					return 0;
+				}
+
+				tmp_inode->i_ctime = inode->i_ctime;
+				tmp_inode->i_nlink--;
+				iput(tmp_inode);
+			} else {
+				brelse (bh);
+				return 0;
+			}
 		}
 		offset += le16_to_cpu(de->rec_len);
 		de = (struct ext3_dir_entry_2 *)
@@ -2031,7 +2052,7 @@ static int ext3_rmdir (struct inode * di
 		goto end_rmdir;
 
 	retval = -ENOTEMPTY;
-	if (!empty_dir (inode))
+	if (!empty_dir (handle, inode))
 		goto end_rmdir;
 
 	retval = ext3_delete_entry(handle, dir, de, bh);
@@ -2060,6 +2081,36 @@ end_rmdir:
 	return retval;
 }
 
+static int ext3_whiteout(struct inode *dir, struct dentry *dentry)
+{
+	struct inode * inode;
+	int err, retries = 0;
+	handle_t *handle;
+
+retry:
+	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
+					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+					2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	if (IS_DIRSYNC(dir))
+		handle->h_sync = 1;
+
+	inode = ext3_new_inode (handle, dir, S_IFWHT | S_IRUGO);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out_stop;
+
+	err = ext3_add_nondir(handle, dentry, inode);
+
+out_stop:
+	ext3_journal_stop(handle);
+	if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+		goto retry;
+	return err;
+}
+
 static int ext3_unlink(struct inode * dir, struct dentry *dentry)
 {
 	int retval;
@@ -2261,7 +2312,7 @@ static int ext3_rename (struct inode * o
 	if (S_ISDIR(old_inode->i_mode)) {
 		if (new_inode) {
 			retval = -ENOTEMPTY;
-			if (!empty_dir (new_inode))
+			if (!empty_dir (handle, new_inode))
 				goto end_rename;
 		}
 		retval = -EIO;
@@ -2377,6 +2428,7 @@ const struct inode_operations ext3_dir_i
 	.mkdir		= ext3_mkdir,
 	.rmdir		= ext3_rmdir,
 	.mknod		= ext3_mknod,
+	.whiteout	= ext3_whiteout,
 	.rename		= ext3_rename,
 	.setattr	= ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1492,6 +1492,15 @@ static int ext3_fill_super (struct super
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
 		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
 
+	if ((sb->s_flags & MS_UNION) && !(sb->s_flags & MS_RDONLY)) {
+		if (!EXT3_HAS_INCOMPAT_FEATURE(sb,
+				EXT3_FEATURE_INCOMPAT_WHITEOUT)) {
+			sb->s_flags |= MS_RDONLY;
+			ext3_warning(sb, __FUNCTION__,
+			"no whiteout support, mounting filesystem read-only");
+		}
+	}
+
 	if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
 	    (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -2748,7 +2757,7 @@ static struct file_system_type ext3_fs_t
 	.name		= "ext3",
 	.get_sb		= ext3_get_sb,
 	.kill_sb	= kill_block_super,
-	.fs_flags	= FS_REQUIRES_DEV,
+	.fs_flags	= FS_REQUIRES_DEV | FS_WHT,
 };
 
 static int __init init_ext3_fs(void)
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -63,6 +63,7 @@
 #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
 #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
 #define EXT3_JOURNAL_INO	 8	/* Journal inode */
+#define EXT3_WHT_INO		 9	/* Whiteout inode */
 
 /* First non-reserved inode for old ext3 filesystems */
 #define EXT3_GOOD_OLD_FIRST_INO	11
@@ -582,6 +583,7 @@ static inline int ext3_valid_inum(struct
 #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
 #define EXT3_FEATURE_INCOMPAT_META_BG		0x0010
+#define EXT3_FEATURE_INCOMPAT_WHITEOUT		0x0020
 
 #define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
 #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
@@ -648,8 +650,9 @@ struct ext3_dir_entry_2 {
 #define EXT3_FT_FIFO		5
 #define EXT3_FT_SOCK		6
 #define EXT3_FT_SYMLINK		7
+#define EXT3_FT_WHT		8
 
-#define EXT3_FT_MAX		8
+#define EXT3_FT_MAX		9
 
 /*
  * EXT3_DIR_PAD defines the directory entries boundaries

  parent reply	other threads:[~2007-05-14  9:38 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-14  9:37 [RFC][PATCH 0/14] VFS based Union Mount(v1) Bharata B Rao
2007-05-14  9:38 ` [RFC][PATCH 1/14] Add union mount documentation Bharata B Rao
2007-05-14  9:39 ` [RFC][PATCH 2/14] Add a new mount flag (MNT_UNION) for union mount Bharata B Rao
2007-05-14 20:38   ` Jan Engelhardt
2007-05-15  8:16     ` Bharata B Rao
2007-05-15 12:06       ` Eric Van Hensbergen
2007-05-15 12:53         ` Jan Blunck
2007-05-14  9:39 ` [RFC][PATCH 3/14] Add the whiteout file type Bharata B Rao
2007-05-14 20:39   ` Jan Engelhardt
2007-05-15  6:00     ` Jan Blunck
2007-05-14  9:40 ` [RFC][PATCH 4/14] Add config options for union mount Bharata B Rao
2007-05-14  9:40 ` [RFC][PATCH 5/14] Introduce union stack Bharata B Rao
2007-05-14  9:40   ` Bharata B Rao
2007-05-14 20:23   ` Badari Pulavarty
2007-05-14 20:51     ` Jan Engelhardt
2007-05-19 10:18     ` Paul Dickson
2007-05-22 16:35       ` Jan Engelhardt
2007-05-23 13:25       ` Serge E. Hallyn
2007-05-14 20:48   ` Jan Engelhardt
2007-05-15  7:19     ` Jan Blunck
2007-05-14 22:40   ` Badari Pulavarty
2007-05-14 22:40     ` Badari Pulavarty
2007-05-15  6:28     ` Bharata B Rao
2007-05-14  9:41 ` [RFC][PATCH 6/14] Union-mount dentry reference counting Bharata B Rao
2007-05-14 20:57   ` Jan Engelhardt
2007-05-14  9:41 ` [RFC][PATCH 7/14] Union-mount mounting Bharata B Rao
2007-05-14  9:41   ` Bharata B Rao
2007-05-15  7:29   ` Jan Engelhardt
2007-05-16  5:04     ` Bharata B Rao
2007-05-14  9:42 ` [RFC][PATCH 8/14] Union-mount lookup Bharata B Rao
2007-05-15  7:57   ` Jan Engelhardt
2007-05-16  5:08     ` Bharata B Rao
2007-05-16 19:28       ` Jan Engelhardt
2007-05-16 20:06         ` Serge E. Hallyn
2007-05-15 14:00   ` Trond Myklebust
2007-05-18 11:05     ` Bharata B Rao
2007-05-14  9:42 ` [RFC][PATCH 9/14] Union-mount readdir Bharata B Rao
2007-05-14 10:43   ` Carsten Otte
2007-05-14 11:15     ` Bharata B Rao
2007-05-14  9:43 ` [RFC][PATCH 10/14] In-kernel file copy between union mounted filesystems Bharata B Rao
2007-05-16  7:57   ` Jan Engelhardt
2007-05-18 11:10     ` Bharata B Rao
2007-05-18 13:47       ` Shaya Potter
2007-05-22  3:13         ` Bharata B Rao
2007-05-22  6:25           ` Jan Engelhardt
2007-05-22  8:38             ` Bharata B Rao
2007-05-22 12:35               ` Shaya Potter
2007-05-23 10:41                 ` Bharata B Rao
2007-05-14  9:43 ` [RFC][PATCH 11/14] VFS whiteout handling Bharata B Rao
2007-05-16  8:06   ` Jan Engelhardt
2007-05-14  9:44 ` [RFC][PATCH 12/14] ext2 whiteout support Bharata B Rao
2007-05-16  8:07   ` Jan Engelhardt
2007-05-14  9:44 ` Bharata B Rao [this message]
2007-05-14 20:16   ` [RFC][PATCH 13/14] ext3 " Badari Pulavarty
2007-05-15  6:26     ` Bharata B Rao
2007-05-15  8:31       ` Jan Blunck
2007-05-14 20:17   ` Andreas Dilger
2007-05-14 20:35     ` Jan Blunck
2007-05-15 14:28       ` Theodore Tso
2007-05-14  9:45 ` [RFC][PATCH 14/14] tmpfs " Bharata B Rao
2007-05-14 16:13   ` Hugh Dickins
2007-05-14 19:20     ` Jan Blunck
2007-05-14 19:35       ` Hugh Dickins

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=20070514094450.GO4139@in.ibm.com \
    --to=bharata@linux.vnet.ibm.com \
    --cc=j.blunck@tu-harburg.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.