All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jordi Pujol <jordipujolp@gmail.com>
To: linux-fsdevel@vger.kernel.org, Miklos Szeredi <miklos@szeredi.hu>
Subject: overlayfs patches for ovl_copy_up & ovl_rename
Date: Wed, 4 May 2011 16:59:38 +0200	[thread overview]
Message-ID: <201105041659.38427.jordipujolp@gmail.com> (raw)

[-- Attachment #1: Type: Text/Plain, Size: 912 bytes --]

Hello,

Here are some comments obtained from past days testing overlayfs in Live 
systems,

- to improve copy_up performance I have redesigned the procedure,
it traverses the tree looking for the topmost lower dentry, anotating the 
concerning dentries and locking them; after, for each dentry from top to 
bottom, it copies the inodes and releases the dentry.

- a repeated line is found in overlayfs.h

- a few days ago we talked about an error when repetitive sed instructions 
were executed, also it happens in other processes, like mantaining list of 
installed files for actual packages,
that is solved in ovl_rename issuing a dget for the old-dentry and parent 
dentries. (This code is inspired on rename.c from unionfs)

Now Overlayfs is working properly on my desktop Live system, it is fast and 
reliable,

Thanks,

Jordi Pujol

Live never ending Tale
GNU/Linux Live forever!
http://livenet.selfip.com

[-- Attachment #2: 12-copy-up-stack.patch --]
[-- Type: text/x-patch, Size: 2890 bytes --]

--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -315,69 +315,70 @@ out_free_link:
 	return err;
 }
 
-int ovl_copy_up(struct dentry *dentry)
+/* Optimize by not copying up the file first and truncating later */
+int ovl_copy_up_truncate(struct dentry *dentry, loff_t size)
 {
 	int err;
+	struct dentry *next;
+	struct dentry *parent;
+	struct path lowerpath;
+	struct kstat stat;
+	enum ovl_path_type type;
+	struct dentry **adentry;
+	struct dentry **adentryr;
+	int sc, st, i;
 
 	err = 0;
-	while (!err) {
-		struct dentry *next;
-		struct dentry *parent;
-		struct path lowerpath;
-		struct kstat stat;
-		enum ovl_path_type type = ovl_path_type(dentry);
-
-		if (type != OVL_PATH_LOWER)
-			break;
 
-		next = dget(dentry);
-		/* find the topmost dentry not yet copied up */
-		for (;;) {
-			parent = dget_parent(next);
-
-			type = ovl_path_type(parent);
-			if (type != OVL_PATH_LOWER)
+	/* look for dentries that are pending to copy */
+	st = 5;
+	adentry = kmalloc(st * sizeof(struct dentry *), GFP_KERNEL);
+	if (!adentry)
+		return -ENOMEM;
+
+	next = dentry;
+	for (sc = 0; ; sc++) {
+		if (sc >= st) {
+			st += 5;
+			adentryr = krealloc(adentry, st * sizeof(struct dentry *), GFP_KERNEL);
+			if (!adentryr) {
+				err = -ENOMEM;
 				break;
-
-			dput(next);
-			next = parent;
+			}
+			adentry = adentryr;
 		}
 
-		ovl_path_lower(next, &lowerpath);
-		err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat);
-		if (!err)
-			err = ovl_copy_up_one(parent, next, &lowerpath, &stat);
+		adentry[sc] = dget(next);
+		type = ovl_path_type(adentry[sc]);
+		if (type != OVL_PATH_LOWER) {
+			dput(adentry[sc]);
+			break;
+		}
+		next = adentry[sc]->d_parent;
+	}
 
-		dput(parent);
-		dput(next);
+	/* copy the dentries */
+	for (i = sc - 1; i >= 0; i--) {
+		if (!err) {
+			parent = dget_parent(adentry[i]);
+			ovl_path_lower(adentry[i], &lowerpath);
+			err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat);
+			if (!err) {
+				if (i == 0 && size >= 0 && size < stat.size)
+					stat.size = size;
+				err = ovl_copy_up_one(parent, adentry[i], &lowerpath, &stat);
+			}
+			dput(parent);
+		}
+		dput(adentry[i]);
 	}
 
+	kfree(adentry);
+
 	return err;
 }
 
-/* Optimize by not copying up the file first and truncating later */
-int ovl_copy_up_truncate(struct dentry *dentry, loff_t size)
+int ovl_copy_up(struct dentry *dentry)
 {
-	int err;
-	struct kstat stat;
-	struct path lowerpath;
-	struct dentry *parent = dget_parent(dentry);
-
-	err = ovl_copy_up(parent);
-	if (err)
-		goto out_dput_parent;
-
-	ovl_path_lower(dentry, &lowerpath);
-	err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat);
-	if (err)
-		goto out_dput_parent;
-
-	if (size < stat.size)
-		stat.size = size;
-
-	err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
-
-out_dput_parent:
-	dput(parent);
-	return err;
+	return ovl_copy_up_truncate(dentry, -1LL);
 }

[-- Attachment #3: 14-rename-locked.patch --]
[-- Type: text/x-patch, Size: 891 bytes --]

--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -512,12 +512,17 @@ static int ovl_rename(struct inode *oldd
 	old_upperdir = ovl_dentry_upper(old->d_parent);
 	new_upperdir = ovl_dentry_upper(new->d_parent);
 
+	(void) dget(old_upperdir);
+	(void) dget(new_upperdir);
+
 	trap = lock_rename(new_upperdir, old_upperdir);
 
 	olddentry = ovl_dentry_upper(old);
-	newdentry = ovl_dentry_upper(new);
-	if (newdentry) {
-		dget(newdentry);
+	(void) dget(olddentry);
+
+	if (!ovl_is_whiteout(new) &&
+	(newdentry = ovl_dentry_upper(new))) {
+		(void) dget(newdentry);
 	} else {
 		new_create = true;
 		newdentry = ovl_lookup_create(new_upperdir, new);
@@ -570,7 +575,13 @@ static int ovl_rename(struct inode *oldd
 out_dput:
 	dput(newdentry);
 out_unlock:
+	dput(olddentry);
+
 	unlock_rename(new_upperdir, old_upperdir);
+
+	dput(old_upperdir);
+	dput(new_upperdir);
+
 	return err;
 }
 

[-- Attachment #4: 13-remove-repeated-declaration.patch --]
[-- Type: text/x-patch, Size: 458 bytes --]

--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -33,7 +33,6 @@
 void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque);
 bool ovl_is_whiteout(struct dentry *dentry);
 void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry);
-void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque);
 int ovl_do_lookup(struct dentry *dentry);
 
 struct dentry *ovl_upper_create(struct dentry *upperdir, struct dentry *dentry,

             reply	other threads:[~2011-05-04 14:59 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-04 14:59 Jordi Pujol [this message]
2011-05-05  9:06 ` overlayfs patches for ovl_copy_up & ovl_rename Miklos Szeredi
2011-05-09  6:38   ` Jordi Pujol
2011-05-10 16:20     ` Miklos Szeredi
2011-05-17  8:43       ` Miklos Szeredi
2011-05-17 17:18         ` Jordi Pujol
2011-05-17 18:07           ` Miklos Szeredi
2011-05-18  7:44             ` Jordi Pujol
2011-05-18  8:42               ` Miklos Szeredi
2011-05-19  7:47                 ` Jordi Pujol
2011-05-19  8:49                   ` Miklos Szeredi
2011-05-19  9:24                     ` Jordi Pujol
2011-05-19  9:52                       ` Miklos Szeredi
2011-05-19 13:34                         ` Jordi Pujol
2011-05-21  5:10                       ` Jordi Pujol
2011-05-23  9:21                         ` Miklos Szeredi
2011-05-24 15:53                           ` Jordi Pujol
2011-05-27 15:03                           ` Jordi Pujol
2011-05-31  9:01                             ` Miklos Szeredi
2011-05-19  8:52                   ` Jordi Pujol

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=201105041659.38427.jordipujolp@gmail.com \
    --to=jordipujolp@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /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.