linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Erez Zadok <ezk@cs.sunysb.edu>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	viro@ftp.linux.org.uk, hch@infradead.org,
	Erez Zadok <ezk@cs.sunysb.edu>, Hugh Dickins <hugh@veritas.com>
Subject: [PATCH 08/16] Unionfs: release lower resources on successful rmdir
Date: Mon, 26 Nov 2007 11:44:05 -0500	[thread overview]
Message-ID: <1196095456701-git-send-email-ezk@cs.sunysb.edu> (raw)
In-Reply-To: <11960954531503-git-send-email-ezk@cs.sunysb.edu>

This patch prevents those resources from lingering around until memory
pressure would have forced them out.  The patch also properly handles
directories that have been rmdir'ed which are still some process's cwd.

CC: Hugh Dickins <hugh@veritas.com>

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
---
 fs/unionfs/inode.c  |    3 ++-
 fs/unionfs/mmap.c   |    5 ++++-
 fs/unionfs/unlink.c |   33 ++++++++++++++++++++++++++++-----
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index 9c144be..ef61d9c 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -944,7 +944,8 @@ static int unionfs_permission(struct inode *inode, int mask,
 		 * dentry+inode.  This should be equivalent to issuing
 		 * __unionfs_d_revalidate_chain on nd.dentry here.
 		 */
-		err = -ESTALE;	/* force revalidate */
+		if (is_file)	/* dirs can be unlinked but chdir'ed to */
+			err = -ESTALE;	/* force revalidate */
 		goto out;
 	}
 
diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c
index 1e10280..3f65e52 100644
--- a/fs/unionfs/mmap.c
+++ b/fs/unionfs/mmap.c
@@ -123,8 +123,11 @@ static int unionfs_writepages(struct address_space *mapping,
 	struct inode *inode;
 
 	inode = mapping->host;
+	if (ibstart(inode) < 0 && ibend(inode) < 0)
+		goto out;
 	lower_inode = unionfs_lower_inode(inode);
-	BUG_ON(!lower_inode);
+	if (!lower_inode)
+		goto out;
 
 	if (!mapping_cap_writeback_dirty(lower_inode->i_mapping))
 		goto out;
diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
index a8de672..f65245d 100644
--- a/fs/unionfs/unlink.c
+++ b/fs/unionfs/unlink.c
@@ -148,6 +148,7 @@ int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
 	int err = 0;
 	struct unionfs_dir_state *namelist = NULL;
+	int dstart, dend;
 
 	unionfs_read_lock(dentry->d_sb);
 	unionfs_lock_dentry(dentry);
@@ -164,28 +165,50 @@ int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
 		goto out;
 
 	err = unionfs_rmdir_first(dir, dentry, namelist);
+	dstart = dbstart(dentry);
+	dend = dbend(dentry);
 	/* create whiteout */
 	if (!err) {
-		err = create_whiteout(dentry, dbstart(dentry));
+		err = create_whiteout(dentry, dstart);
 	} else {
 		int new_err;
 
-		if (dbstart(dentry) == 0)
+		if (dstart == 0)
 			goto out;
 
 		/* exit if the error returned was NOT -EROFS */
 		if (!IS_COPYUP_ERR(err))
 			goto out;
 
-		new_err = create_whiteout(dentry, dbstart(dentry) - 1);
+		new_err = create_whiteout(dentry, dstart - 1);
 		if (new_err != -EEXIST)
 			err = new_err;
 	}
 
 out:
-	/* call d_drop so the system "forgets" about us */
-	if (!err)
+	/*
+	 * Drop references to lower dentry/inode so storage space for them
+	 * can be reclaimed.  Then, call d_drop so the system "forgets"
+	 * about us.
+	 */
+	if (!err) {
+		struct inode *inode = dentry->d_inode;
+		BUG_ON(!inode);
+		iput(unionfs_lower_inode_idx(inode, dstart));
+		unionfs_set_lower_inode_idx(inode, dstart, NULL);
+		dput(unionfs_lower_dentry_idx(dentry, dstart));
+		unionfs_set_lower_dentry_idx(dentry, dstart, NULL);
+		/*
+		 * If the last directory is unlinked, then mark istart/end
+		 * as -1, (to maintain the invariant that if there are no
+		 * lower objects, then branch index start and end are set to
+		 * -1).
+		 */
+		if (!unionfs_lower_inode_idx(inode, dstart) &&
+		    !unionfs_lower_inode_idx(inode, dend))
+			ibstart(inode) = ibend(inode) = -1;
 		d_drop(dentry);
+	}
 
 	if (namelist)
 		free_rdstate(namelist);
-- 
1.5.2.2


  parent reply	other threads:[~2007-11-26 16:45 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-26 16:43 [GIT PULL -mm] 00/16 Unionfs updates/fixes/cleanups Erez Zadok
2007-11-26 16:43 ` [PATCH 01/16] Unionfs: use f_path instead of f_dentry/mnt Erez Zadok
2007-11-26 16:43 ` [PATCH 02/16] Unionfs: minor cleanup in writepage Erez Zadok
2007-11-26 16:44 ` [PATCH 03/16] Unionfs: minor coding standards applied Erez Zadok
2007-11-26 16:44 ` [PATCH 04/16] Unionfs: minor cleanup in the debugging infrastructure Erez Zadok
2007-11-26 16:44 ` [PATCH 05/16] Unionfs: set lower mnt after mkdir which resulted in copyup Erez Zadok
2007-11-26 16:44 ` [PATCH 06/16] Unionfs: handle whiteouts more efficiently in filldir Erez Zadok
2007-11-26 16:44 ` [PATCH 07/16] Unionfs: remove useless debugging messages Erez Zadok
2007-11-26 16:44 ` Erez Zadok [this message]
2007-11-26 16:44 ` [PATCH 09/16] Unionfs: don't create whiteouts on rightmost branch Erez Zadok
2007-11-26 16:44 ` [PATCH 10/16] Unionfs: create opaque directories' whiteouts unconditionally Erez Zadok
2007-11-26 16:44 ` [PATCH 11/16] Unionfs: update times in setattr Erez Zadok
2007-11-26 16:44 ` [PATCH 12/16] Unionfs: reintroduce a bmap method Erez Zadok
2007-11-26 16:44 ` [PATCH 13/16] Unionfs: support splice(2) Erez Zadok
2007-11-26 16:44 ` [PATCH 14/16] Unionfs: prevent multiple writers to lower_page Erez Zadok
2007-11-26 16:44 ` [PATCH 15/16] Unionfs: update our inode size correctly upon partial write Erez Zadok
2007-11-26 16:44 ` [PATCH 16/16] Unionfs: use generic_file_aio_read/write Erez Zadok

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=1196095456701-git-send-email-ezk@cs.sunysb.edu \
    --to=ezk@cs.sunysb.edu \
    --cc=akpm@linux-foundation.org \
    --cc=hch@infradead.org \
    --cc=hugh@veritas.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@ftp.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;
as well as URLs for NNTP newsgroup(s).