All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Smid <david-0RIiUExYzkzCfDggNXIi3w@public.gmane.org>
To: Ryusuke Konishi <ryusuke-sG5X7nlA6pw@public.gmane.org>,
	users-JrjvKiOkagjYtjvyW6yDsg@public.gmane.org
Subject: Re: pp (protection period) mount option
Date: Wed, 02 Dec 2009 18:20:10 +0100	[thread overview]
Message-ID: <4B16A1CA.9050608@unity-linux.org> (raw)
In-Reply-To: <20091202.010205.38314732.ryusuke-sG5X7nlA6pw@public.gmane.org>

Ryusuke Konishi napsal(a):
> On Wed, 02 Dec 2009 00:44:22 +0900 (JST), Ryusuke Konishi <ryusuke-sG5X7nlA6pw@public.gmane.org> wrote:
>> Hi,
>> On Sat, 28 Nov 2009 22:16:31 +0100, David Smid <david-0RIiUExYzkzCfDggNXIi3w@public.gmane.org>
>> wrote:
>>> Thanks you for your valuable comments.
>>>
>>> You are right, of course. No kernel code changes are needed.
>>> Here is my take #2.
>>>
>>> David
>> Thank you, David.  I reviewed the patch in detail, and no worrisome
>> point found.
>>
>> During tests, I noticed that remount doesn't work for this option:
>>
>>   For instance, after doing
>>   # mount -t nilfs2 -o pp=600 /dev/sdb1 /test
>>   # mount -t nilfs2 -o remount,pp=400 /dev/sdb1 /test
> 
> Ryusuke

Good point, remount should definitely work because it is quite useful to change
pp on the fly.

This patch should work.

David



--- sbin/mount/mount.nilfs2.h.mount_pp_opt	2009-07-19 16:53:00.000000000 +0200
+++ sbin/mount/mount.nilfs2.h	2009-12-02 10:27:26.000000000 +0100
@@ -13,12 +13,13 @@
 #define NILFS2_FS_NAME		"nilfs2"
 #define CLEANERD_NAME		"nilfs_cleanerd"
 #define PIDOPT_NAME		"gcpid"
+#define PPOPT_NAME		"pp"

 #define CLEANERD_WAIT_RETRY_COUNT	3
 #define CLEANERD_WAIT_RETRY_INTERVAL	2  /* in seconds */


-extern int start_cleanerd(const char *, const char *, pid_t *);
+extern int start_cleanerd(const char *, const char *, unsigned long, pid_t *);
 extern int stop_cleanerd(const char *, pid_t);
 extern int check_cleanerd(const char *, pid_t);

--- sbin/mount/cleaner_ctl.c.mount_pp_opt	2009-07-19 16:53:00.000000000 +0200
+++ sbin/mount/cleaner_ctl.c	2009-12-02 18:16:16.000000000 +0100
@@ -45,6 +45,7 @@

 const char cleanerd[] = "/sbin/" CLEANERD_NAME;
 const char cleanerd_nofork_opt[] = "-n";
+const char cleanerd_protperiod_opt[] = "-p";

 extern char *progname;

@@ -54,12 +55,14 @@
 	return (kill(pid, 0) == 0);
 }

-int start_cleanerd(const char *device, const char *mntdir, pid_t *ppid)
+int start_cleanerd(const char *device, const char *mntdir,
+		   unsigned long protperiod, pid_t *ppid)
 {
-	const char *dargs[5];
+	const char *dargs[7];
 	struct stat statbuf;
 	int i = 0;
 	int res;
+	char buf[256];

 	if (stat(cleanerd, &statbuf) != 0) {
 		error(_("Warning: %s not found"), CLEANERD_NAME);
@@ -80,6 +83,11 @@
 		}
 		dargs[i++] = cleanerd;
 		dargs[i++] = cleanerd_nofork_opt;
+		if (protperiod != ULONG_MAX) {
+			dargs[i++] = cleanerd_protperiod_opt;
+			snprintf(buf, sizeof(buf), "%lu", protperiod);
+			dargs[i++] = buf;
+		}
 		dargs[i++] = device;
 		dargs[i++] = mntdir;
 		dargs[i] = NULL;
--- sbin/mount/umount.nilfs2.c.mount_pp_opt	2009-07-19 16:53:00.000000000 +0200
+++ sbin/mount/umount.nilfs2.c	2009-12-02 18:15:37.000000000 +0100
@@ -69,6 +69,9 @@
 const char gcpid_opt_fmt[] = PIDOPT_NAME "=%d";
 typedef int gcpid_opt_t;

+const char pp_opt_fmt[] = PPOPT_NAME "=%lu";
+typedef unsigned long pp_opt_t;
+
 struct umount_options {
 	int flags;
 	int force;
@@ -317,6 +320,7 @@
 	int res, alive = 0;
 	const char *loopdev;
 	pid_t pid;
+	pp_opt_t prot_period;

 	if (streq (node, "/") || streq (node, "root"))
 		nomtab++;
@@ -349,7 +353,11 @@
 				      progname, spec);
 			}
 		} else if (alive && !check_cleanerd(spec, pid)) {
-			if (start_cleanerd(spec, node, &pid) == 0) {
+			if (find_opt(mc->m.mnt_opts, pp_opt_fmt, &prot_period)
+			    < 0)
+				prot_period = ULONG_MAX;
+
+			if (start_cleanerd(spec, node, prot_period, &pid) == 0) {
 				if (verbose)
 					printf(_("%s: restarted %s(pid=%d)\n"),
 					       progname, CLEANERD_NAME,
--- sbin/mount/mount.nilfs2.c.mount_pp_opt	2009-07-19 16:53:00.000000000 +0200
+++ sbin/mount/mount.nilfs2.c	2009-12-02 18:14:50.000000000 +0100
@@ -71,6 +71,9 @@
 const char gcpid_opt_fmt[] = PIDOPT_NAME "=%d";
 typedef int gcpid_opt_t;

+const char pp_opt_fmt[] = PPOPT_NAME "=%lu";
+typedef unsigned long pp_opt_t;
+
 struct mount_options {
 	char *fstype;
 	char *opts;
@@ -225,16 +228,43 @@
 	*opts = newopts;
 }

-static char *fix_extra_opts_string(const char *extra_opts, pid_t gcpid)
+static void update_pp_opt(char **opts, pp_opt_t protection_period)
+{
+	char buf[256], *newopts;
+	pp_opt_t oldpp;
+
+	*buf = 0;
+	if (protection_period != ULONG_MAX) {
+		snprintf(buf, sizeof(buf), pp_opt_fmt, protection_period);
+	}
+	newopts = change_opt(*opts, pp_opt_fmt, &oldpp, buf);
+	my_free(*opts);
+	*opts = newopts;
+}
+
+static char *fix_extra_opts_string(const char *extra_opts, pid_t gcpid,
+				   pp_opt_t protection_period)
 {
 	char buf[256];
 	gcpid_opt_t id;
+	pp_opt_t pp;
+	char *tmpres;
+	char *res;

 	buf[0] = '\0';
 	if (gcpid)
 		snprintf(buf, sizeof(buf), gcpid_opt_fmt, (int)gcpid);
 	/* The gcpid option will be removed if gcpid == 0 */
-	return change_opt(extra_opts, gcpid_opt_fmt, &id, buf);
+	tmpres = change_opt(extra_opts, gcpid_opt_fmt, &id, buf);
+	
+	buf[0] = '\0';
+	if (protection_period != ULONG_MAX)
+		snprintf(buf, sizeof(buf), pp_opt_fmt, protection_period);
+	/* The pp option will be removed if pp == ULONG_MAX */
+	res = change_opt(tmpres, pp_opt_fmt, &pp, buf);
+
+	my_free(tmpres);
+	return res;
 }

 /*
@@ -312,6 +342,7 @@
 	pid_t gcpid;
 	int type;
 	int mounted;
+	pp_opt_t protperiod;
 };

 static int check_mtab(void)
@@ -348,6 +379,7 @@
 {
 	struct mntentchn *mc;
 	gcpid_opt_t pid;
+	pp_opt_t prot_period;
 	int res = -1;

 	if (!(mo->flags & MS_REMOUNT) && mounted(NULL, mi->mntdir)) {
@@ -359,6 +391,9 @@
 	mi->gcpid = 0;
 	mi->optstr = NULL;
 	mi->mounted = mounted(mi->device, mi->mntdir);
+	mi->protperiod = ULONG_MAX;
+	if (find_opt(mo->extra_opts, pp_opt_fmt, &prot_period) >= 0)
+		mi->protperiod = prot_period;

 	if (mo->flags & MS_BIND)
 		return 0;
@@ -375,15 +410,13 @@
 		goto failed;
 	case MS_RDONLY: /* ro-mount (a rw-mount exists) */
 		break;
-	case MS_REMOUNT: /* rw->rw remount */
-		if (check_remount_dir(mc, mi->mntdir) < 0)
-			goto failed;
-		if (find_opt(mc->m.mnt_opts, gcpid_opt_fmt, &pid) >= 0)
-			mi->gcpid = pid;
-		mi->optstr = xstrdup(mc->m.mnt_opts); /* previous opts */
-		mi->type = RW2RW_REMOUNT;
-		break;
-	case MS_RDONLY | MS_REMOUNT:  /* rw->ro remount */
+	case MS_REMOUNT | MS_RDONLY: /* rw->ro remount */
+		mi->type = RW2RO_REMOUNT;
+		mi->protperiod = ULONG_MAX;
+		/* fallthrough */
+	case MS_REMOUNT:
+		if (!(mo->flags & MS_RDONLY))
+			mi->type = RW2RW_REMOUNT; /* rw->rw remount */			
 		if (check_remount_dir(mc, mi->mntdir) < 0)
 			goto failed;
 		pid = 0;
@@ -395,7 +428,6 @@
 		}
 		mi->gcpid = pid;
 		mi->optstr = xstrdup(mc->m.mnt_opts); /* previous opts */
-		mi->type = RW2RO_REMOUNT;
 		break;
 	}

@@ -408,9 +440,13 @@
 do_mount_one(struct nilfs_mount_info *mi, const struct mount_options *mo)
 {
 	int res, errsv;
+	char *exopts;
+	pp_opt_t prot_period;
+
+	exopts = change_opt(mo->extra_opts, pp_opt_fmt, &prot_period, "");

 	res = mount(mi->device, mi->mntdir, fstype, mo->flags & ~MS_NOSYS,
-		    mo->extra_opts);
+		    exopts);
 	if (!res)
 		goto out;

@@ -425,15 +461,19 @@
 		      progname, mi->device, mi->mntdir, strerror(errsv));
 		break;
 	}
-	if (mi->type != RW2RO_REMOUNT)
+	if (mi->type != RW2RO_REMOUNT && mi->type != RW2RW_REMOUNT)
 		goto out;
+	/* Cleaner daemon was stopped and it needs to run */
+	/* because filesystem is still mounted */
 	if (check_mtab()) {
 		/* Restarting cleaner daemon */
-		if (start_cleanerd(mi->device, mi->mntdir, &mi->gcpid) == 0) {
+		if (start_cleanerd(mi->device, mi->mntdir, mi->protperiod,
+				   &mi->gcpid) == 0) {
 			if (verbose)
 				printf(_("%s: restarted %s\n"),
 				       progname, CLEANERD_NAME);
 			update_gcpid_opt(&mi->optstr, mi->gcpid);
+			update_pp_opt(&mi->optstr, mi->protperiod);
 			update_mtab_entry(mi->device, mi->mntdir, fstype,
 					  mi->optstr, 0, 0, !mi->mounted);
 		} else {
@@ -443,31 +483,39 @@
 	} else
 		printf(_("%s not restarted\n"), CLEANERD_NAME);
  out:
+	my_free(exopts);
 	return res;
 }

 static void update_mount_state(struct nilfs_mount_info *mi,
 			       const struct mount_options *mo)
 {
-	pid_t pid = (mi->type == RW2RW_REMOUNT) ? mi->gcpid : 0;
+	pid_t pid = fake ? mi->gcpid : 0;
 	char *exopts;
 	int rungc;

+	if (mo->flags & MS_RDONLY)
+		mi->protperiod = ULONG_MAX;
+
 	rungc = !(mo->flags & MS_RDONLY) && !(mo->flags & MS_BIND) &&
-		(mi->type != RW2RW_REMOUNT || mi->gcpid == 0);
+		(pid == 0);
 	if (!check_mtab()) {
 		if (rungc)
 			printf(_("%s not started\n"), CLEANERD_NAME);
 		return;
 	}
 	if (rungc) {
-		if (start_cleanerd(mi->device, mi->mntdir, &pid) < 0)
+		if (start_cleanerd(mi->device, mi->mntdir, mi->protperiod,
+				   &pid) < 0)
 			error(_("%s aborted"), CLEANERD_NAME);
 		else if (verbose)
 			printf(_("%s: started %s\n"), progname, CLEANERD_NAME);
-	}
+	} else
+		if (!fake)
+			pid = 0;
+	
 	my_free(mi->optstr);
-	exopts = fix_extra_opts_string(mo->extra_opts, pid);
+	exopts = fix_extra_opts_string(mo->extra_opts, pid, mi->protperiod);
 	mi->optstr = fix_opts_string(((mo->flags & ~MS_NOMTAB) | MS_NETDEV),
 				     exopts, NULL);
 		
--- man/mount.nilfs2.8.mount_pp_opt	2009-07-19 16:53:00.000000000 +0200
+++ man/mount.nilfs2.8	2009-12-02 10:27:26.000000000 +0100
@@ -103,6 +103,12 @@
 remount the file system read-only, or panic and halt the system.)  The
 default is continue.
 .TP
+.BR pp=\fP\fIprotection-period\fP
+Specify the \fIprotection-period\fP for the cleaner daemon (in
+seconds). nilfs_cleanerd never deletes recent checkpoints whose
+elapsed time from its creation is smaller than
+\fIprotection-period\fP.
+.TP
 .BR order=relaxed " / " order=strict
 Specify order semantics for file data.  Metadata is always written to
 follow the POSIX semantics about the order of filesystem operations.

  parent reply	other threads:[~2009-12-02 17:20 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-27 14:21 pp (protection period) mount option David Smid
     [not found] ` <4B0FE052.70307-0RIiUExYzkzCfDggNXIi3w@public.gmane.org>
2009-11-27 16:23   ` Ryusuke Konishi
     [not found]     ` <20091128.012303.54434171.ryusuke-sG5X7nlA6pw@public.gmane.org>
2009-11-28 21:16       ` David Smid
     [not found]         ` <749598c60911281316i40b591b1hcb055b0867617f0e-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-12-01 15:44           ` Ryusuke Konishi
     [not found]             ` <20091202.004422.69931110.ryusuke-sG5X7nlA6pw@public.gmane.org>
2009-12-01 16:02               ` Ryusuke Konishi
     [not found]                 ` <20091202.010205.38314732.ryusuke-sG5X7nlA6pw@public.gmane.org>
2009-12-02 17:20                   ` David Smid [this message]
     [not found]                     ` <4B16A1CA.9050608-0RIiUExYzkzCfDggNXIi3w@public.gmane.org>
2009-12-03 17:22                       ` Ryusuke Konishi

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=4B16A1CA.9050608@unity-linux.org \
    --to=david-0riiuexyzkzcfdggnxii3w@public.gmane.org \
    --cc=ryusuke-sG5X7nlA6pw@public.gmane.org \
    --cc=users-JrjvKiOkagjYtjvyW6yDsg@public.gmane.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.