All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: IO scheduler based IO controller V10
From: Corrado Zoccolo @ 2009-09-29  7:14 UTC (permalink / raw)
  To: Mike Galbraith
  Cc: Vivek Goyal, Ulrich Lukas, linux-kernel, containers, dm-devel,
	nauman, dpshah, lizf, mikew, fchecconi, paolo.valente, ryov,
	fernando, jmoyer, dhaval, balbir, righi.andrea, m-ikeda, agk,
	akpm, peterz, jmarchan, torvalds, mingo, riel, jens.axboe,
	Tobias Oetiker
In-Reply-To: <1254164034.9820.81.camel@marge.simson.net>

Hi Mike,
On Mon, Sep 28, 2009 at 8:53 PM, Mike Galbraith <efault@gmx.de> wrote:
> On Mon, 2009-09-28 at 14:18 -0400, Vivek Goyal wrote:
>> On Mon, Sep 28, 2009 at 07:51:14PM +0200, Mike Galbraith wrote:
>
>> I guess changing class to IDLE should have helped a bit as now this is
>> equivalent to setting the quantum to 1 and after dispatching one request
>> to disk, CFQ will always expire the writer once. So it might happen that
>> by the the reader preempted writer, we have less number of requests in
>> disk and lesser latency for this reader.
>
> I expected SCHED_IDLE to be better than setting quantum to 1, because
> max is quantum*4 if you aren't IDLE.  But that's not what happened.  I
> just retested with all knobs set back to stock, fairness off, and
> quantum set to 1 with everything running nice 0.  2.8 seconds avg :-/

Idle doesn't work very well for async writes, since the writer process
will just send its writes to the page cache.
The real writeback will happen in the context of a kernel thread, with
best effort scheduling class.

>
>> > I saw
>> > the reference to Vivek's patch, and gave it a shot.  Makes a large
>> > difference.
>> >                                                            Avg
>> > perf stat     12.82     7.19     8.49     5.76     9.32    8.7     anticipatory
>> >               16.24   175.82   154.38   228.97   147.16  144.5     noop
>> >               43.23    57.39    96.13   148.25   180.09  105.0     deadline
>> >                9.15    14.51     9.39    15.06     9.90   11.6     cfq fairness=0 dd=nice 0
>> >               12.22     9.85    12.55     9.88    15.06   11.9     cfq fairness=0 dd=nice 19
>> >                9.77    13.19    11.78    17.40     9.51   11.9     cfq fairness=0 dd=SCHED_IDLE
>> >                4.59     2.74     4.70     3.45     4.69    4.0     cfq fairness=1 dd=nice 0
>> >                3.79     4.66     2.66     5.15     3.03    3.8     cfq fairness=1 dd=nice 19
>> >                2.79     4.73     2.79     4.02     2.50    3.3     cfq fairness=1 dd=SCHED_IDLE
>> >
>>
>> Hmm.., looks like average latency went down only in  case of fairness=1
>> and not in case of fairness=0. (Looking at previous mail, average vanilla
>> cfq latencies were around 12 seconds).
>
> Yup.
>
>> Are you running all this in root group or have you put writers and readers
>> into separate cgroups?
>
> No cgroups here.
>
>> If everything is running in root group, then I am curious why latency went
>> down in case of fairness=1. The only thing fairness=1 parameter does is
>> that it lets complete all the requests from previous queue before start
>> dispatching from next queue. On top of this is valid only if no preemption
>> took place. In your test case, konsole should preempt the writer so
>> practically fairness=1 might not make much difference.
>
> fairness=1 very definitely makes a very large difference.  All of those
> cfq numbers were logged in back to back runs.
>
>> In fact now Jens has committed a patch which achieves the similar effect as
>> fairness=1 for async queues.
>
> Yeah, I was there yesterday.  I speculated that that would hurt my
> reader, but rearranging things didn't help one bit.  Playing with merge,
> I managed to give dd ~7% more throughput, and injured poor reader even
> more.  (problem analysis via hammer/axe not always most effective;)
>
>> commit 5ad531db6e0f3c3c985666e83d3c1c4d53acccf9
>> Author: Jens Axboe <jens.axboe@oracle.com>
>> Date:   Fri Jul 3 12:57:48 2009 +0200
>>
>>     cfq-iosched: drain device queue before switching to a sync queue
>>
>>     To lessen the impact of async IO on sync IO, let the device drain of
>>     any async IO in progress when switching to a sync cfqq that has idling
>>     enabled.
>>
>>
>> If everything is in separate cgroups, then we should have seen latency
>> improvements in case of fairness=0 case also. I am little perplexed here..
>>
>> Thanks
>> Vivek
>
>

Thanks,
Corrado


-- 
__________________________________________________________________________

dott. Corrado Zoccolo                          mailto:czoccolo@gmail.com
PhD - Department of Computer Science - University of Pisa, Italy
--------------------------------------------------------------------------
The self-confidence of a warrior is not the self-confidence of the average
man. The average man seeks certainty in the eyes of the onlooker and calls
that self-confidence. The warrior seeks impeccability in his own eyes and
calls that humbleness.
                               Tales of Power - C. Castaneda

^ permalink raw reply

* Re: IO scheduler based IO controller V10
From: Corrado Zoccolo @ 2009-09-29  7:14 UTC (permalink / raw)
  To: Mike Galbraith
  Cc: Tobias Oetiker, dhaval-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	jens.axboe-QHcLZuEGTsvQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
	balbir-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	paolo.valente-rcYM44yAMweonA0d6jMUrA,
	jmarchan-H+wXaHxf7aLQT0dZR+AlfA, fernando-gVGce1chcLdL9jVzuh4AOg,
	Ulrich Lukas, jmoyer-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
	riel-H+wXaHxf7aLQT0dZR+AlfA, fchecconi-Re5JQEeQqe8AvxtiuMwx3w,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	righi.andrea-Re5JQEeQqe8AvxtiuMwx3w,
	torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
In-Reply-To: <1254164034.9820.81.camel-YqMYhexLQo1vAv1Ojkdn7Q@public.gmane.org>

Hi Mike,
On Mon, Sep 28, 2009 at 8:53 PM, Mike Galbraith <efault@gmx.de> wrote:
> On Mon, 2009-09-28 at 14:18 -0400, Vivek Goyal wrote:
>> On Mon, Sep 28, 2009 at 07:51:14PM +0200, Mike Galbraith wrote:
>
>> I guess changing class to IDLE should have helped a bit as now this is
>> equivalent to setting the quantum to 1 and after dispatching one request
>> to disk, CFQ will always expire the writer once. So it might happen that
>> by the the reader preempted writer, we have less number of requests in
>> disk and lesser latency for this reader.
>
> I expected SCHED_IDLE to be better than setting quantum to 1, because
> max is quantum*4 if you aren't IDLE.  But that's not what happened.  I
> just retested with all knobs set back to stock, fairness off, and
> quantum set to 1 with everything running nice 0.  2.8 seconds avg :-/

Idle doesn't work very well for async writes, since the writer process
will just send its writes to the page cache.
The real writeback will happen in the context of a kernel thread, with
best effort scheduling class.

>
>> > I saw
>> > the reference to Vivek's patch, and gave it a shot.  Makes a large
>> > difference.
>> >                                                            Avg
>> > perf stat     12.82     7.19     8.49     5.76     9.32    8.7     anticipatory
>> >               16.24   175.82   154.38   228.97   147.16  144.5     noop
>> >               43.23    57.39    96.13   148.25   180.09  105.0     deadline
>> >                9.15    14.51     9.39    15.06     9.90   11.6     cfq fairness=0 dd=nice 0
>> >               12.22     9.85    12.55     9.88    15.06   11.9     cfq fairness=0 dd=nice 19
>> >                9.77    13.19    11.78    17.40     9.51   11.9     cfq fairness=0 dd=SCHED_IDLE
>> >                4.59     2.74     4.70     3.45     4.69    4.0     cfq fairness=1 dd=nice 0
>> >                3.79     4.66     2.66     5.15     3.03    3.8     cfq fairness=1 dd=nice 19
>> >                2.79     4.73     2.79     4.02     2.50    3.3     cfq fairness=1 dd=SCHED_IDLE
>> >
>>
>> Hmm.., looks like average latency went down only in  case of fairness=1
>> and not in case of fairness=0. (Looking at previous mail, average vanilla
>> cfq latencies were around 12 seconds).
>
> Yup.
>
>> Are you running all this in root group or have you put writers and readers
>> into separate cgroups?
>
> No cgroups here.
>
>> If everything is running in root group, then I am curious why latency went
>> down in case of fairness=1. The only thing fairness=1 parameter does is
>> that it lets complete all the requests from previous queue before start
>> dispatching from next queue. On top of this is valid only if no preemption
>> took place. In your test case, konsole should preempt the writer so
>> practically fairness=1 might not make much difference.
>
> fairness=1 very definitely makes a very large difference.  All of those
> cfq numbers were logged in back to back runs.
>
>> In fact now Jens has committed a patch which achieves the similar effect as
>> fairness=1 for async queues.
>
> Yeah, I was there yesterday.  I speculated that that would hurt my
> reader, but rearranging things didn't help one bit.  Playing with merge,
> I managed to give dd ~7% more throughput, and injured poor reader even
> more.  (problem analysis via hammer/axe not always most effective;)
>
>> commit 5ad531db6e0f3c3c985666e83d3c1c4d53acccf9
>> Author: Jens Axboe <jens.axboe@oracle.com>
>> Date:   Fri Jul 3 12:57:48 2009 +0200
>>
>>     cfq-iosched: drain device queue before switching to a sync queue
>>
>>     To lessen the impact of async IO on sync IO, let the device drain of
>>     any async IO in progress when switching to a sync cfqq that has idling
>>     enabled.
>>
>>
>> If everything is in separate cgroups, then we should have seen latency
>> improvements in case of fairness=0 case also. I am little perplexed here..
>>
>> Thanks
>> Vivek
>
>

Thanks,
Corrado


-- 
__________________________________________________________________________

dott. Corrado Zoccolo                          mailto:czoccolo@gmail.com
PhD - Department of Computer Science - University of Pisa, Italy
--------------------------------------------------------------------------
The self-confidence of a warrior is not the self-confidence of the average
man. The average man seeks certainty in the eyes of the onlooker and calls
that self-confidence. The warrior seeks impeccability in his own eyes and
calls that humbleness.
                               Tales of Power - C. Castaneda
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers

^ permalink raw reply

* Re: b43 is broken in latest net-2.6 and linux-2.6
From: Oliver Hartkopp @ 2009-09-29  7:13 UTC (permalink / raw)
  To: John W. Linville; +Cc: Michael Buesch, Linux Netdev List
In-Reply-To: <20090928184211.GC4737@tuxdriver.com>

John W. Linville wrote:
> On Sat, Sep 19, 2009 at 01:23:11PM +0200, Oliver Hartkopp wrote:
>> Hello Michael,
>>
>> my b43 wireless card (Dell 830) is not working with the latest net-2.6 (and
>> also linux-2.6 2.6.31-05767-gdf58bee).
>>
>> net-2.6 2.6.31-03263-gc29854e is working
>> net-2.6 2.6.31-03301-ga97e178 is broken
>>
>> I removed the patch with the work_queue stuff which did not help - so it's
>> probably the other patch you added to b43 recently.
>>
>> Don't know ... the wlan0 link does not become ready anymore.
>>
>> If you need some more information - please let me know.
> 
> Is this working better now, with 2.6.31-rc1?

Thanks for coming back on this.

Yes it is fixed now.

   'cfg80211: fix SME connect'

broke it and

   'cfg80211: don't overwrite privacy setting'

fixed it afterwards (at least in my setup).

So it's pretty well working now.

Best regards,
Oliver

^ permalink raw reply

* [RFC][PATCH] Permission masking security module (was dpriv)
From: Andy Spencer @ 2009-09-29  7:10 UTC (permalink / raw)
  To: linux-security-module, linux-kernel
In-Reply-To: <20090923005644.GA28244@c.hsd1.tn.comcast.net>

[-- Attachment #1: Type: text/plain, Size: 36189 bytes --]

Changes since the previous patch (dpriv-p0):

- Change the name to pmask (Permission Masking)

- Use recursive and non-recursive variants for setting masks 
  $ echo self $perm $path > $stage # Set perms for $path only
  $ echo kids $perm $path > $stage # Set perms for children of $path
  $ echo both $perm $path > $stage # Set perms for $path and children

- Add a quota of 500 permission lines per policy

- Improve securityfs parsing.

- Change '-' to '.' in permissions string to avoid confusion with
  `chmod -rwx foo'

- Many syntax/naming/etc bug fixes

Signed-off-by: Andy Spencer <andy753421@gmail.com>
---
 Documentation/pmask.txt |  102 ++++++++++++++
 lib/vsprintf.c          |    2 +-
 security/Kconfig        |    1 +
 security/Makefile       |    2 +
 security/pmask/Kconfig  |    8 +
 security/pmask/Makefile |    1 +
 security/pmask/fs.c     |  299 +++++++++++++++++++++++++++++++++++++++++
 security/pmask/pmask.c  |  144 ++++++++++++++++++++
 security/pmask/policy.c |  337 +++++++++++++++++++++++++++++++++++++++++++++++
 security/pmask/policy.h |  230 ++++++++++++++++++++++++++++++++
 10 files changed, 1125 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/pmask.txt
 create mode 100644 security/pmask/Kconfig
 create mode 100644 security/pmask/Makefile
 create mode 100644 security/pmask/fs.c
 create mode 100644 security/pmask/pmask.c
 create mode 100644 security/pmask/policy.c
 create mode 100644 security/pmask/policy.h

diff --git a/Documentation/pmask.txt b/Documentation/pmask.txt
new file mode 100644
index 0000000..522cb30
--- /dev/null
+++ b/Documentation/pmask.txt
@@ -0,0 +1,102 @@
+Source code
+-----------
+  policy.[ch] - policy datatypes
+  pmask.c     - security/credentials hooks
+  fs.c        - securityfs hooks
+
+
+TODO
+----
+  - Check for race conditions
+
+
+Overview
+--------
+1. Each process keeps a list of inode -> priv mappings:
+   - i.e. the security policy
+
+2. Caching possibilities (todo?)
+   - Processes keeps a list of open fds to prevent recursing up the FS tree?
+   - Store the most recent processes access in each inode?
+
+Privs:
+  - read/write/exec/sticky/setuid/setgui
+  - All permissions are recursive
+  - Permissions for dirs and file are separate
+    - This prevents recursion problems
+    - e.g. you can set noexec for files without smashing directories
+  - Notation
+     (rwx) = specified permission (inode in policy)
+    ~(rwx) = implied permission (parent(s) in policy)
+
+Things to do when:
+  1. Setting privs
+     - Add policy line(s) for given path?
+     - Update privs on open inodes that are children of policy line?
+  2. Loading inode
+     - Cache privs from parent(s)?
+  3. Namespace modification (mv,ln,bind,etc)
+     - OR
+       - Keep policy for inode the same        (policy = old      )
+       - Merge policy for both locations       (policy = old & new)
+       - Change policy to reflect new location (policy =       new)
+     - If mv, and including old implied policy:
+       - need to write new (combined) policy line
+
+
+Security FS
+-----------
+files:
+  -rw-rw-rw- /securityfs/pmask/stage
+  -r--r--r-- /securityfs/pmask/policy
+  --w--w--w- /securityfs/pmask/control
+
+stage:
+  read:  print staged policy
+  write: set inode in staged policy to given perms OR
+         add inode to staged policy with given perms
+         > staged[inode] = perms
+
+  In the stage, order does not matter, adding a line simply writes or
+  overwrites the location with no regard to the rest of the policy.
+
+policy:
+  read: print active policy
+
+control:
+  write:
+    "commit" - merge staged policy into policy
+      > for (inode in policy, staged):
+      >     new[inode] =
+      >         implied_privs(policy, inode) &
+      >         implied_privs(staged, inode)
+      > clear(staged)
+
+    When committing, privilages can only be revoked.
+
+
+Examples
+--------
+Example 1:
+  set /src/     (rw-)
+  set /dst/     (r-x)
+
+  $ mv /src/foo /dst
+
+  get /src/     (rw-)
+  get /dst/     (r-x)
+  OR:
+    get /dst/foo  (rw-)
+    get /dst/foo ~(r-x)
+    get /dst/foo  (rw-) & ~(r-x) = (r--)
+
+Example 2:
+  $ ln /src/foo /dst
+
+  set /src/     (rw-)
+  set /dst/     (rwx)
+
+  get /src/     (rw-)
+  get /dst/     (rwx)
+  get /src/foo ~(rw-) & ~(rwx) = ~(rw-)
+  get /dst/foo ~(rw-) & ~(rwx) = ~(rw-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b91839e..33bed5e 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1771,7 +1771,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
 		 * advance both strings to next white space
 		 */
 		if (*fmt == '*') {
-			while (!isspace(*fmt) && *fmt)
+			while (!isspace(*fmt) && *fmt != '%' && *fmt)
 				fmt++;
 			while (!isspace(*str) && *str)
 				str++;
diff --git a/security/Kconfig b/security/Kconfig
index fb363cd..d4521b5 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -159,6 +159,7 @@ config LSM_MMAP_MIN_ADDR
 	  this low address space will need the permission specific to the
 	  systems running LSM.
 
+source security/pmask/Kconfig
 source security/selinux/Kconfig
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
diff --git a/security/Makefile b/security/Makefile
index 95ecc06..f8c5b26 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_KEYS)			+= keys/
+subdir-$(CONFIG_SECURITY_PERM_MASKING)  += pmask
 subdir-$(CONFIG_SECURITY_SELINUX)	+= selinux
 subdir-$(CONFIG_SECURITY_SMACK)		+= smack
 subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
@@ -14,6 +15,7 @@ obj-y		+= commoncap.o min_addr.o
 obj-$(CONFIG_SECURITY)			+= security.o capability.o
 obj-$(CONFIG_SECURITYFS)		+= inode.o
 # Must precede capability.o in order to stack properly.
+obj-$(CONFIG_SECURITY_PERM_MASKING)	+= pmask/built-in.o
 obj-$(CONFIG_SECURITY_SELINUX)		+= selinux/built-in.o
 obj-$(CONFIG_SECURITY_SMACK)		+= smack/built-in.o
 obj-$(CONFIG_AUDIT)			+= lsm_audit.o
diff --git a/security/pmask/Kconfig b/security/pmask/Kconfig
new file mode 100644
index 0000000..a8ca887
--- /dev/null
+++ b/security/pmask/Kconfig
@@ -0,0 +1,8 @@
+config SECURITY_PERM_MASKING
+	bool "Permission masking"
+	depends on SECURITY
+	select SECURITYFS
+	default n
+	help
+	  This enabled support for masking filesystem permissions.
+	  If you are unsure how to answer this question, answer N.
diff --git a/security/pmask/Makefile b/security/pmask/Makefile
new file mode 100644
index 0000000..39d5b27
--- /dev/null
+++ b/security/pmask/Makefile
@@ -0,0 +1 @@
+obj-y = pmask.o policy.o fs.o
diff --git a/security/pmask/fs.c b/security/pmask/fs.c
new file mode 100644
index 0000000..84a6515
--- /dev/null
+++ b/security/pmask/fs.c
@@ -0,0 +1,299 @@
+/**
+ * pmask/fs.c -- Security FS interface for privilege dropping
+ *
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/security.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/ctype.h>
+#include <linux/uaccess.h>
+
+#include "policy.h"
+
+/***************************
+ * Generic policy iterator *
+ ***************************/
+/* Use this for reading form any policy file */
+static void *pmask_seq_start(struct seq_file *sf, loff_t *pos)
+{
+	struct pmask_policy *policy = sf->private;
+	down_read(&policy->privs_lock);
+	return seq_list_start(&policy->privs, *pos);
+}
+
+static void *pmask_seq_next(struct seq_file *sf, void *seq, loff_t *pos)
+{
+	struct pmask_policy *policy = sf->private;
+	return seq_list_next(seq, &policy->privs, pos);
+}
+
+static void pmask_seq_stop(struct seq_file *sf, void *seq)
+{
+	struct pmask_policy *policy = sf->private;
+	up_read(&policy->privs_lock);
+}
+
+static int pmask_seq_show(struct seq_file *sf, void *seq)
+{
+	struct pmask_line *line = list_entry(seq, struct pmask_line, list);
+	char perm_str[PMASK_PERM_BITS+1] = {};
+	if (pmask_isset(line->self_perm) &&
+			line->self_perm == line->kids_perm) {
+		pmask_perm_to_str(line->self_perm, perm_str);
+		seq_printf(sf, "both %s %s\n", perm_str, line->path);
+	} else {
+		if (pmask_isset(line->self_perm)) {
+			pmask_perm_to_str(line->self_perm, perm_str);
+			seq_printf(sf, "self %s %s\n", perm_str, line->path);
+		}
+		if (pmask_isset(line->kids_perm)) {
+			pmask_perm_to_str(line->kids_perm, perm_str);
+			seq_printf(sf, "kids %s %s\n", perm_str, line->path);
+		}
+	}
+	return 0;
+}
+
+static const struct seq_operations pmask_seq_ops = {
+	.start = pmask_seq_start,
+	.next  = pmask_seq_next,
+	.stop  = pmask_seq_stop,
+	.show  = pmask_seq_show,
+};
+
+static int pmask_seq_open(struct file *file, struct pmask_policy *policy)
+{
+	/* From __seq_open_private
+	 * Not sure if this is correct way to store private data */
+	struct seq_file *sf;
+	if (seq_open(file, &pmask_seq_ops) < 0) {
+		pr_warning("Out of memory opening PMask sequence\n");
+		return -ENOMEM;
+	}
+	sf = file->private_data;
+	sf->private = policy;
+	return 0;
+};
+
+
+
+/**************
+ * Stage file *
+ **************/
+static int pmask_stage_open(struct inode *inode, struct file *file)
+{
+	return pmask_seq_open(file, pmask_cur_stage);
+};
+
+/**
+ * Parse policy lines one at a time.
+ * Format: /\s*([rwxsguRWXSGU\-]*)\s*(.*)(\s*)?/
+ *   \1: See pmask_str_to_perm() for discussion
+ *   \2: A file path, \3 trailing whitespace is optional
+ */
+static ssize_t pmask_stage_write(struct file *filp, const char *ubuffer,
+		size_t length, loff_t *off)
+{
+	struct file *file;
+	int err, rval, perm, scope;
+	char *kbuffer, *cmd_str, *perm_str, *path_str;
+	int cmd_start, cmd_end, perm_start, perm_end, path_start;
+
+	if (length > (size_t)~0LL)
+		return -EINVAL;;
+	kbuffer = kmalloc(length+1, GFP_KERNEL);
+	if (!kbuffer)
+		return -ENOMEM;
+	kbuffer[length] = '\0';
+
+	if (copy_from_user(kbuffer, ubuffer, length))
+		goto fail_fault;
+
+	/* Parse input */
+	path_start = -1;
+	sscanf(kbuffer, " %n%*s%n %n%*s%n %n", &cmd_start, &cmd_end,
+			&perm_start, &perm_end, &path_start);
+	if (path_start == -1)
+		goto fail_inval;
+	cmd_str  = kbuffer+cmd_start;  kbuffer[cmd_end]  = '\0';
+	perm_str = kbuffer+perm_start; kbuffer[perm_end] = '\0';
+	path_str = kbuffer+path_start;
+
+	/* Check and convert cmd/scope */
+	if (!strcmp(cmd_str, "self"))
+		scope = PMASK_SELF;
+	else if (!strcmp(cmd_str, "kids"))
+		scope = PMASK_KIDS;
+	else if (!strcmp(cmd_str, "both"))
+		scope = PMASK_BOTH;
+	else
+		goto fail_inval;
+
+	/* Check and convert perm */
+	if (perm_str[0] == '\0')
+		goto fail_inval;
+	perm = pmask_str_to_perm(perm_str);
+	if (perm < 0)
+		goto fail_inval;
+
+	/* Check and open path */
+	if (path_str[0] == '\0')
+		goto fail_inval;
+	file = filp_open(path_str, 0, 0);
+	if (IS_ERR(file)) {
+		/* file not found, try trimming trailing spaces */
+		strstrip(path_str);
+		if (path_str[0] == '\0')
+			goto fail_inval;
+		file = filp_open(path_str, 0, 0);
+		if (IS_ERR(file))
+			goto fail_noent;
+	}
+
+	path_str = kstrdup(path_str, GFP_KERNEL);
+	if (!path_str)
+		goto fail_nomem;
+
+	err = pmask_policy_set_perm(pmask_cur_stage,
+			file->f_dentry->d_inode, path_str, perm, scope);
+	if (err) {
+		kfree(path_str);
+		rval = err;
+		goto out;
+	}
+
+	pr_debug("pmask_task=%p pid=%d perm=%o[%s] path=%p[%s]\n",
+		pmask_cur_task, current->pid, perm, perm_str, file, path_str);
+
+	rval = length;
+	goto out; /* Success */
+
+fail_inval: rval = -EINVAL; goto out;
+fail_nomem: rval = -ENOMEM; goto out;
+fail_fault: rval = -EFAULT; goto out;
+fail_noent: rval = -ENOENT; goto out;
+out:
+	kfree(kbuffer);
+	/* if (rval < 0) abort task ? */
+	return rval;
+}
+
+static const struct file_operations pmask_stage_fops = {
+	.open    = pmask_stage_open,
+	.write   = pmask_stage_write,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+
+
+/***************
+ * Policy file *
+ ***************/
+static int pmask_policy_open(struct inode *inode, struct file *file)
+{
+	return pmask_seq_open(file, pmask_cur_policy);
+};
+
+static const struct file_operations pmask_policy_fops = {
+	.open    = pmask_policy_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+
+
+/****************
+ * Control file *
+ ****************/
+/**
+ * Read various commands from the user
+ * Format: /(\w+).* /
+ * Commands:
+ *   commit: copy stage to the policy and reset stage
+ */
+static ssize_t pmask_control_write(struct file *filp, const char *buffer,
+		size_t length, loff_t *off)
+{
+	int rval, err;
+	char *command;
+
+	command = kzalloc(length+1, GFP_KERNEL);
+	if (!command)
+		return -ENOMEM;
+
+	if (copy_from_user(command, buffer, length)) {
+		rval = -EFAULT;
+		goto out;
+	}
+
+	strstrip(command);
+
+	if (!strcmp("commit", command)) {
+		pr_debug("committing stage for pid=%d\n", current->pid);
+		err = pmask_policy_commit(pmask_cur_stage, pmask_cur_policy);
+		if (err) {
+			rval = err;
+			goto out;
+		}
+		pmask_policy_clear(pmask_cur_stage);
+	} else {
+		pr_debug("unimplemented control coomand `%s'\n", command);
+		rval = -EINVAL;
+		goto out;
+	}
+
+	rval = length; /* success */
+	goto out;
+
+out:
+	kfree(command);
+	return rval;
+}
+
+static const struct file_operations pmask_control_fops = {
+	.write = pmask_control_write,
+};
+
+
+
+/****************
+ * Registration *
+ ****************/
+static int __init pmask_fs_init(void)
+{
+	struct dentry *pmask_dir;
+	if (!pmask_loaded)
+		return 0;
+	pmask_dir = securityfs_create_dir("pmask", NULL);
+	securityfs_create_file("stage",
+			0666, pmask_dir, NULL, &pmask_stage_fops);
+	securityfs_create_file("policy",
+			0444, pmask_dir, NULL, &pmask_policy_fops);
+	securityfs_create_file("control",
+			0222, pmask_dir, NULL, &pmask_control_fops);
+	pr_info("PMask FS initialized\n");
+	return 0;
+}
+
+fs_initcall(pmask_fs_init);
diff --git a/security/pmask/pmask.c b/security/pmask/pmask.c
new file mode 100644
index 0000000..c64e4bc
--- /dev/null
+++ b/security/pmask/pmask.c
@@ -0,0 +1,144 @@
+/**
+ * pmask/pmask.c -- Linux Security Module interface for privilege dropping
+ *
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/security.h>
+#include <linux/sched.h>
+
+#include "policy.h"
+
+int pmask_loaded;
+
+/* Credentials */
+static void pmask_cred_free(struct cred *cred)
+{
+	pmask_task_free(cred->security);
+	cred->security = NULL;
+}
+
+static int pmask_cred_prepare(struct cred *new, const struct cred *old,
+		gfp_t gfp)
+{
+	new->security = pmask_task_dup(old->security, gfp);
+	if (!new->security) {
+		pr_warning("Out of memory while preparing PMask task\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int pmask_dentry_open(struct file *file, const struct cred *cred)
+{
+	u16 perm, need;
+
+	/* Set parent link */
+	if (!IS_ROOT(file->f_dentry))
+		file->f_dentry->d_inode->i_security =
+				file->f_dentry->d_parent->d_inode;
+	else
+		file->f_dentry->d_inode->i_security = NULL;
+
+
+	/* Check privs */
+	perm = pmask_policy_get_perm(pmask_cur_policy,
+			file->f_dentry->d_inode);
+	need = pmask_flags_to_mode(file->f_flags);
+	need = pmask_imode_to_perm(need, file->f_dentry->d_inode);
+	if (unlikely(pmask_denied(perm, need))) {
+		char *path = kzalloc(PATH_MAX, GFP_KERNEL);
+		if (path) {
+			path = d_path(&file->f_path, path, sizeof(path));
+			pr_debug("denied perm=%o:%o path=%s\n",
+					perm, need, path);
+			kfree(path);
+		} else {
+			pr_warning("Out of memory getting path\n");
+			pr_debug("denied perm=%o:%o path=%s\n",
+					perm, need, "-ENOMEM");
+		}
+		return -EACCES;
+	}
+	return 0;
+}
+
+/* Mostly for directory walking */
+static int pmask_inode_permission(struct inode *inode, int mask)
+{
+	u16 perm = pmask_policy_get_perm(pmask_cur_policy, inode);
+	u16 need = pmask_imode_to_perm(mask, inode);
+	if (unlikely(pmask_denied(perm, need))) {
+		pr_debug("denied perm=%o:%o:%o inode=%p\n",
+				perm, need, mask, inode);
+		return -EACCES;
+	}
+	return 0;
+}
+
+/* TODO: Use these to store the multiple pointers? */
+/*
+static int pmask_inode_alloc_security(struct inode *inode)
+{
+	return 0;
+}
+static int pmask_inode_init_security(struct inode *inode, struct inode *dir,
+		char **name, void **value, size_t *len)
+{
+	return 0;
+}
+static void pmask_inode_free_security(struct inode *inode)
+{
+}
+*/
+
+/* Registration */
+static struct security_operations pmask_security_ops = {
+	.name                 = "pmask",
+	.cred_prepare         = pmask_cred_prepare,
+	.cred_free            = pmask_cred_free,
+	.dentry_open          = pmask_dentry_open,
+	.inode_permission     = pmask_inode_permission,
+	/*
+	.inode_alloc_security = pmask_inode_alloc_security,
+	.inode_init_security  = pmask_inode_init_security,
+	.inode_free_security  = pmask_inode_free_security,
+	*/
+	/* TODO: add path operations and update the policies when the
+	 * filesystem layout changes */
+};
+
+static int __init pmask_init(void)
+{
+	struct cred *cred = (struct cred *)current_cred();
+
+	if (!security_module_enable(&pmask_security_ops))
+		return 0;
+	if (register_security(&pmask_security_ops))
+		panic("Failure registering PMask");
+	cred->security = pmask_task_new(GFP_KERNEL);
+	if (!cred->security)
+		panic("Out of memory while initializing pmask");
+	pr_info("PMask initialized\n");
+	pmask_loaded = 1;
+	return 0;
+}
+
+security_initcall(pmask_init);
diff --git a/security/pmask/policy.c b/security/pmask/policy.c
new file mode 100644
index 0000000..90d0606
--- /dev/null
+++ b/security/pmask/policy.c
@@ -0,0 +1,337 @@
+/**
+ * pmask/policy.c -- Privilege dropping core functionality
+ *
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/security.h>
+#include <linux/sched.h>
+#include <linux/ctype.h>
+#include <linux/fs.h>
+
+#include "policy.h"
+
+/*******************
+ * Permission bits *
+ *******************/
+static char pmask_perm_bit_list[] = "rwxsguRWXSGU";
+static u16  pmask_perm_bit_table['z'] = {
+	['x'] PMASK_EXEC,
+	['w'] PMASK_WRITE,
+	['r'] PMASK_READ,
+	['s'] PMASK_KEEPSWP,
+	['g'] PMASK_SETGID,
+	['u'] PMASK_SETUID,
+	['X'] PMASK_WALK,
+	['W'] PMASK_CREATE,
+	['R'] PMASK_LIST,
+	['S'] PMASK_STICKY,
+	['G'] PMASK_PASSGID,
+	['U'] PMASK_PASSUID,
+	['.'] 0,
+}; /* plus 0.25k .. */
+
+u16 pmask_flags_to_mode(unsigned int flags)
+{
+	u16 mode = 0;
+	if (flags & FMODE_READ)  mode |= PMASK_READ;
+	if (flags & FMODE_WRITE) mode |= PMASK_WRITE;
+	if (flags & FMODE_EXEC)  mode |= PMASK_EXEC;
+	if (flags & O_CREAT)     mode |= PMASK_CREATE;
+	return mode;
+}
+
+int pmask_str_to_perm(const char *str)
+{
+	int perm = 0;
+	for (; *str; str++) {
+		if ((!isalpha(*str) || !pmask_perm_bit_table[(int)*str]) &&
+				*str != '.')
+			return -1;
+		perm |= pmask_perm_bit_table[(int)*str];
+	}
+	return perm;
+}
+
+void pmask_perm_to_str(u16 perm, char *str)
+{
+	char *c = pmask_perm_bit_list;
+	for (; *c; c++, str++)
+		*str = (perm & pmask_perm_bit_table[(int)*c]) ?  *c : '.';
+	*str = '\0';
+}
+
+
+
+/**************
+ * PMask Line *
+ **************/
+/**
+ * Allocate and initalize a new pmask_line
+ * @indoe, @path, @perm: fileds to store en line
+ */
+static struct pmask_line *pmask_line_new(const struct inode *inode,
+		const char *path, gfp_t gfp)
+{
+	struct pmask_line *line;
+	line = kzalloc(sizeof(struct pmask_line), gfp);
+	if (!line)
+		return NULL;
+	line->inode = inode;
+	line->path  = path;
+	line->self_perm = PMASK_IGNORE;
+	line->kids_perm = PMASK_IGNORE;
+	return line;
+}
+
+
+
+/****************
+ * PMask Policy *
+ ****************/
+/* Return the line from @policy->privs that matches @inode */
+static struct pmask_line *pmask_policy_get_line(
+		const struct pmask_policy *policy, const struct inode *inode)
+{
+	struct pmask_line *line;
+	list_for_each_entry(line, &policy->privs, list)
+		if (line->inode == inode)
+			return line;
+	return NULL;
+}
+
+/* Create and add a line to to @policy while checking for errors and updating
+ * the quota */
+static struct pmask_line *pmask_policy_add_line(struct pmask_policy *policy,
+		const struct inode *inode, const char *path, gfp_t gfp)
+{
+	struct pmask_line *line;
+	if (atomic_read(&policy->privs_count) >= PMASK_MAX_LINES)
+		return NULL;
+	atomic_inc(&policy->privs_count);
+	line = pmask_line_new(inode, path, GFP_KERNEL);
+	if (!line)
+		return NULL;
+	list_add_tail(&line->list, &policy->privs);
+	return line;
+}
+
+/* Create and add a line to to @policy while checking for errors and updating
+ * the quota */
+static struct pmask_line *pmask_policy_ensure_line(struct pmask_policy *policy,
+		const struct inode *inode, const char *path, gfp_t gfp)
+{
+	struct pmask_line *line = pmask_policy_get_line(policy, inode);
+	if (!line)
+		line = pmask_policy_add_line(policy, inode, path, gfp);
+	return line;
+}
+
+
+/* Delete a line form @policy and update the quota */
+static void pmask_policy_del_line(struct pmask_policy *policy,
+		struct pmask_line *line)
+{
+	list_del(&line->list);
+	kfree(line);
+	atomic_dec(&policy->privs_count);
+}
+
+/* Do a semi-deep copy, that is, copy enough that the policies are distinct,
+ * but without duplicating conostant data such as paths and dentries */
+static int pmask_policy_append(struct pmask_policy *from,
+		struct pmask_policy *to, gfp_t gfp)
+{
+	struct pmask_line *old_line, *new_line;
+	list_for_each_entry(old_line, &from->privs, list) {
+		new_line = pmask_policy_add_line(to,
+				old_line->inode, old_line->path, gfp);
+		if (!new_line)
+			return -ENOMEM;
+		new_line->self_perm = old_line->self_perm;
+		new_line->kids_perm = old_line->kids_perm;
+	}
+	return 0;
+}
+
+/* Initialize a blank @policy */
+static void pmask_policy_init(struct pmask_policy *policy)
+{
+	INIT_LIST_HEAD(&policy->privs);
+	init_rwsem(&policy->privs_lock);
+	atomic_set(&policy->privs_count, 0);
+}
+
+void pmask_policy_clear(struct pmask_policy *policy)
+{
+	struct pmask_line *line, *n;
+	list_for_each_entry_safe(line, n, &policy->privs, list)
+		pmask_policy_del_line(policy, line);
+}
+
+
+static u16 pmask_policy_get_perm_rec(const struct pmask_policy *policy,
+		const struct inode *inode)
+{
+	struct pmask_line *line;
+
+	/* Allow everything if we've reach the root without finding perms */
+	/* TODO: recurse to parent filesystems */
+	if (inode == NULL)
+		return USHORT_MAX;
+
+	line = pmask_policy_get_line(policy, inode);
+
+	if (line && pmask_isset(line->kids_perm))
+		return line->kids_perm;
+
+	/* Check parents for recursive permissions */
+	/* TODO: Check for multiple parents */
+	return pmask_policy_get_perm_rec(policy, inode->i_security);
+	/*
+	 * perm = USHORT_MAX;
+	 * foreach parent:
+	 * 	perm &= pmask_policy_get_perm(policy, inode->d_parent);
+	 * return perm;
+	 */
+}
+
+u16 pmask_policy_get_perm(const struct pmask_policy *policy,
+		const struct inode *inode)
+{
+	/* Stop if a permissions is found for current node */
+	struct pmask_line *line = pmask_policy_get_line(policy, inode);
+	if (line && pmask_isset(line->self_perm))
+		return line->self_perm;
+	return pmask_policy_get_perm_rec(policy, inode->i_security);
+}
+
+/* We need the inode and path so we can create the line if it doesn't exist */
+int pmask_policy_set_perm(struct pmask_policy *policy,
+		const struct inode *inode, const char *path,
+		u16 perm, int scope)
+{
+	struct pmask_line *line = pmask_policy_ensure_line(policy,
+			inode, path, GFP_KERNEL);
+	if (!line)
+		return -ENOMEM;
+	if (scope == PMASK_BOTH || scope == PMASK_SELF)
+		line->self_perm = perm;
+	if (scope == PMASK_BOTH || scope == PMASK_KIDS)
+		line->kids_perm = perm;
+	return 0;
+}
+
+static void pmask_policy_merge_line(const struct inode *inode,
+		struct pmask_policy *pl, struct pmask_policy *pr,
+		struct pmask_line *to)
+{
+	struct pmask_line *ll = pmask_policy_get_line(pl, inode);
+	struct pmask_line *lr = pmask_policy_get_line(pr, inode);
+	if ((ll && pmask_isset(ll->self_perm)) ||
+	    (lr && pmask_isset(lr->self_perm))) {
+		to->self_perm  = pmask_policy_get_perm(pl, inode);
+		to->self_perm &= pmask_policy_get_perm(pr, inode);
+	}
+	if ((ll && pmask_isset(ll->kids_perm)) ||
+	    (lr && pmask_isset(lr->kids_perm))) {
+		to->kids_perm  = pmask_policy_get_perm_rec(pl, inode);
+		to->kids_perm &= pmask_policy_get_perm_rec(pr, inode);
+	}
+}
+
+int pmask_policy_commit(struct pmask_policy *from, struct pmask_policy *to)
+{
+	struct pmask_line *line, *merge_line, *n;
+	struct pmask_policy merge;
+	pmask_policy_init(&merge);
+
+	/* Merge paths from @to into merge */
+	list_for_each_entry(line, &to->privs, list) {
+		merge_line = pmask_policy_ensure_line(&merge,
+				line->inode, line->path, GFP_KERNEL);
+		if (!merge_line)
+			goto fail;
+		pmask_policy_merge_line(line->inode, from, to, merge_line);
+	}
+
+	/* Merge paths from @from into merge */
+	list_for_each_entry(line, &from->privs, list) {
+		merge_line = pmask_policy_ensure_line(&merge,
+				line->inode, line->path, GFP_KERNEL);
+		if (!merge_line)
+			goto fail;
+		pmask_policy_merge_line(line->inode, from, to, merge_line);
+	}
+
+	/* Free old entries, and move to ones to @to */
+	pmask_policy_clear(to);
+	list_for_each_entry_safe(line, n, &merge.privs, list)
+		list_move_tail(&line->list, &to->privs);
+
+	return 0;
+
+fail:
+	pmask_policy_clear(&merge);
+	return -ENOMEM;
+}
+
+
+
+/**************
+ * PMask Task *
+ **************/
+struct pmask_task *pmask_task_new(gfp_t gfp)
+{
+	struct pmask_task *task;
+	task = kzalloc(sizeof(struct pmask_task), gfp);
+	if (!task)
+		return NULL;
+
+	pmask_policy_init(&task->stage);
+	pmask_policy_init(&task->policy);
+
+	return task;
+}
+
+void pmask_task_free(struct pmask_task *task)
+{
+	pmask_policy_clear(&task->stage);
+	pmask_policy_clear(&task->policy);
+	kfree(task);
+}
+
+struct pmask_task *pmask_task_dup(struct pmask_task *task, gfp_t gfp)
+{
+	struct pmask_task *copy = pmask_task_new(gfp);
+	if (!copy)
+		return NULL;
+
+	/* Copy policies */
+	if (pmask_policy_append(&task->stage,  &copy->stage,  gfp))
+		goto fail;
+	if (pmask_policy_append(&task->policy, &copy->policy, gfp))
+		goto fail;
+
+	return copy;
+
+fail:
+	pmask_task_free(copy);
+	return NULL;
+}
diff --git a/security/pmask/policy.h b/security/pmask/policy.h
new file mode 100644
index 0000000..bc2d526
--- /dev/null
+++ b/security/pmask/policy.h
@@ -0,0 +1,230 @@
+/**
+ * pmask/policy.h -- Privilege dropping core functionality
+ *
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PMASK_POLICY_H__
+#define __PMASK_POLICY_H__
+
+/* Set to 1 when pmask is initialized */
+extern int pmask_loaded;
+
+/**
+ * Terminology
+ *   mode   = `Unix' mode (u16 use for filesyste mode bits)
+ *   perm   = PMask permission bits (see below)
+ *   privs  = List of files and associated perm
+ *   policy = Privs + whatever else
+ */
+
+#define pmask_cur_task   ((struct pmask_task *)current_security())
+#define pmask_cur_stage  ((struct pmask_policy *)&pmask_cur_task->stage)
+#define pmask_cur_policy ((struct pmask_policy *)&pmask_cur_task->policy)
+
+
+/*******************
+ * Permission bits *
+ *******************/
+/* File bits */
+#define PMASK_EXEC    (1u<<0)  /* x */
+#define PMASK_WRITE   (1u<<1)  /* w */
+#define PMASK_READ    (1u<<2)  /* r */
+#define PMASK_KEEPSWP (1u<<3)  /* s (ignored) */
+#define PMASK_SETGID  (1u<<4)  /* g */
+#define PMASK_SETUID  (1u<<5)  /* u */
+
+/* Directory bits */
+#define PMASK_WALK    (1u<<6)  /* X */
+#define PMASK_CREATE  (1u<<7)  /* W */
+#define PMASK_LIST    (1u<<8)  /* R */
+#define PMASK_STICKY  (1u<<9)  /* S */
+#define PMASK_PASSGID (1u<<10) /* G */
+#define PMASK_PASSUID (1u<<11) /* U (ignored) */
+
+/* Special bits */
+#define PMASK_IGNORE  (1u<<12) /* Permissions unset */
+
+/* Meta bits/masks */
+#define PMASK_PERM_BITS 12
+#define PMASK_MASK      0b111111111111
+#define PMASK_FILE_MASK 0b000000111111
+#define PMASK_DIR_MASK  0b111111000000
+
+/* Scope of permission */
+enum {
+	PMASK_SELF, /* Permissions only affect the inode */
+	PMASK_KIDS, /* Permissions only affect the inodes children */
+	PMASK_BOTH, /* Permissions affect inode and children */
+};
+
+/* Determine if a permission is set or ignored */
+static inline bool pmask_isset(u16 perm)
+{
+	return !(perm & PMASK_IGNORE);
+}
+
+/* Mode conversion functions */
+static inline bool pmask_denied(u16 perm, u16 request)
+{
+	return perm >= 0 && ~perm & request;
+}
+
+/* Convert from a unix directory mode to a perm */
+static inline u16 pmask_dmode_to_perm(u16 mode)
+{
+	return mode << 6;
+}
+
+/* Convert from a unix file mode to a perm */
+static inline u16 pmask_fmode_to_perm(u16 mode)
+{
+	return mode;
+}
+
+/* Convert from a unix perm to a mode based on inode type */
+static inline u16 pmask_imode_to_perm(u16 mode, struct inode *inode)
+{
+	return S_ISDIR(inode->i_mode) ?
+		 pmask_dmode_to_perm(mode) :
+		 pmask_fmode_to_perm(mode);
+}
+
+/**
+ * Convert struct file->f_flags to a Unix mode
+ * <x>mode_to_perm should probably be called on the resulting mode
+ */
+u16 pmask_flags_to_mode(unsigned int flags);
+
+/**
+ * Parse a permission string into a perm
+ * @str:
+ *  - Format is "rwxsguRWXSGU" (see Permission bits)
+ *  - Order does not matter
+ *  - '.' is ignored, any other character is invalid
+ *  - return -1 on invalid str
+ */
+int pmask_str_to_perm(const char *str);
+
+/**
+ * Convert a perm to a string for printing
+ */
+void pmask_perm_to_str(u16 perm, char *str);
+
+
+
+/**************
+ * PMask Line *
+ **************/
+/**
+ * An entry in the policy
+ *
+ * Example:
+ *   /var/tmp (rw-)
+ *
+ * @list:      list_head for stroing in policy
+ * @inode:     Some point in the filesystem, topically an inode
+ * @path:      Path given when the line was created, debugging only
+ * @self_perm: Permissions given to the location
+ * @kids_perm: Permissions given to the location's kids
+ */
+struct pmask_line {
+	struct list_head    list;
+	const struct inode *inode;
+	const char         *path;
+	u16                 self_perm;
+	u16                 kids_perm;
+};
+
+
+
+/****************
+ * PMask Policy *
+ ****************/
+#define PMASK_MAX_LINES 500
+
+/**
+ * Contains permisisons and operations allowed for given security policy
+ *
+ * @privs:      List of pmask_lines for filesystem privilages
+ * @privs_lock: Used for printing (maybe other?)
+ *
+ * Example:
+ *   privs:
+ *     /         (r--)
+ *     /bin/     (r-x)
+ *     /tmp/     (rw-)
+ */
+struct pmask_policy {
+	struct list_head privs;
+	struct rw_semaphore privs_lock;
+	atomic_t privs_count;
+	/* TODO: add other security things */
+};
+
+/* Clear/free data from @policy */
+void pmask_policy_clear(struct pmask_policy *policy);
+
+/* Recursivly lookup perm for @inode in @policy */
+u16 pmask_policy_get_perm(const struct pmask_policy *policy,
+		const struct inode *inode);
+
+/* Set perm for @inode in @policy to @perm, create new line if necessasiary */
+int pmask_policy_set_perm(struct pmask_policy *policy,
+		const struct inode *inode, const char *path,
+		u16 perm, int scope);
+
+/* Copy lines from @from to @to making sure that no additional oeratoins are
+ * allowed in @to after the commit is performed */
+int pmask_policy_commit(struct pmask_policy *from, struct pmask_policy *to);
+
+
+
+/**************
+ * PMask Task *
+ **************/
+/**
+ * Contains information for a given task, including the security policy, stage,
+ * and cache information.
+ *
+ * @stage:
+ *   The modifialbe policy, privilages can be allowed or denied in the stage
+ * @policy:
+ *   The effective policy, used to determines whether an action is allowed
+ *
+ * @policy can only be modified by commiting @stage to @policy. When this is
+ * done, it is insured that no additional operations will be allowed by @policy
+ * after the commit.
+ *
+ * Example:
+ *   stage:  (see pmask_policy)
+ *   policy: (see pmask_policy)
+ */
+struct pmask_task {
+	struct pmask_policy stage;
+	struct pmask_policy policy;
+};
+
+/* Allocate a blank task */
+struct pmask_task *pmask_task_new(gfp_t gfp);
+
+/* Free a task and data associated with it */
+void pmask_task_free(struct pmask_task *task);
+
+/* Create a semi-deep copy of @task, suitable for passing to a child on exec */
+struct pmask_task *pmask_task_dup(struct pmask_task *task, gfp_t gfp);
+
+#endif

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related

* Re: IO scheduler based IO controller V10
From: Corrado Zoccolo @ 2009-09-29  7:10 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: Ulrich Lukas, linux-kernel, containers, dm-devel, nauman, dpshah,
	lizf, mikew, fchecconi, paolo.valente, ryov, fernando, jmoyer,
	dhaval, balbir, righi.andrea, m-ikeda, agk, akpm, peterz,
	jmarchan, torvalds, mingo, riel, jens.axboe, Tobias Oetiker
In-Reply-To: <20090928171420.GA3643@redhat.com>

Hi Vivek,
On Mon, Sep 28, 2009 at 7:14 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> On Mon, Sep 28, 2009 at 05:35:02PM +0200, Corrado Zoccolo wrote:
>> On Mon, Sep 28, 2009 at 4:56 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
>> > On Sun, Sep 27, 2009 at 07:00:08PM +0200, Corrado Zoccolo wrote:
>> >> Hi Vivek,
>> >> On Fri, Sep 25, 2009 at 10:26 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
>> >> > On Fri, Sep 25, 2009 at 04:20:14AM +0200, Ulrich Lukas wrote:
>> >> >> Vivek Goyal wrote:
>> >> >> > Notes:
>> >> >> > - With vanilla CFQ, random writers can overwhelm a random reader.
>> >> >> >   Bring down its throughput and bump up latencies significantly.
>> >> >>
>> >> >>
>> >> >> IIRC, with vanilla CFQ, sequential writing can overwhelm random readers,
>> >> >> too.
>> >> >>
>> >> >> I'm basing this assumption on the observations I made on both OpenSuse
>> >> >> 11.1 and Ubuntu 9.10 alpha6 which I described in my posting on LKML
>> >> >> titled: "Poor desktop responsiveness with background I/O-operations" of
>> >> >> 2009-09-20.
>> >> >> (Message ID: 4AB59CBB.8090907@datenparkplatz.de)
>> >> >>
>> >> >>
>> >> >> Thus, I'm posting this to show that your work is greatly appreciated,
>> >> >> given the rather disappointig status quo of Linux's fairness when it
>> >> >> comes to disk IO time.
>> >> >>
>> >> >> I hope that your efforts lead to a change in performance of current
>> >> >> userland applications, the sooner, the better.
>> >> >>
>> >> > [Please don't remove people from original CC list. I am putting them back.]
>> >> >
>> >> > Hi Ulrich,
>> >> >
>> >> > I quicky went through that mail thread and I tried following on my
>> >> > desktop.
>> >> >
>> >> > ##########################################
>> >> > dd if=/home/vgoyal/4G-file of=/dev/null &
>> >> > sleep 5
>> >> > time firefox
>> >> > # close firefox once gui pops up.
>> >> > ##########################################
>> >> >
>> >> > It was taking close to 1 minute 30 seconds to launch firefox and dd got
>> >> > following.
>> >> >
>> >> > 4294967296 bytes (4.3 GB) copied, 100.602 s, 42.7 MB/s
>> >> >
>> >> > (Results do vary across runs, especially if system is booted fresh. Don't
>> >> >  know why...).
>> >> >
>> >> >
>> >> > Then I tried putting both the applications in separate groups and assign
>> >> > them weights 200 each.
>> >> >
>> >> > ##########################################
>> >> > dd if=/home/vgoyal/4G-file of=/dev/null &
>> >> > echo $! > /cgroup/io/test1/tasks
>> >> > sleep 5
>> >> > echo $$ > /cgroup/io/test2/tasks
>> >> > time firefox
>> >> > # close firefox once gui pops up.
>> >> > ##########################################
>> >> >
>> >> > Now I firefox pops up in 27 seconds. So it cut down the time by 2/3.
>> >> >
>> >> > 4294967296 bytes (4.3 GB) copied, 84.6138 s, 50.8 MB/s
>> >> >
>> >> > Notice that throughput of dd also improved.
>> >> >
>> >> > I ran the block trace and noticed in many a cases firefox threads
>> >> > immediately preempted the "dd". Probably because it was a file system
>> >> > request. So in this case latency will arise from seek time.
>> >> >
>> >> > In some other cases, threads had to wait for up to 100ms because dd was
>> >> > not preempted. In this case latency will arise both from waiting on queue
>> >> > as well as seek time.
>> >>
>> >> I think cfq should already be doing something similar, i.e. giving
>> >> 100ms slices to firefox, that alternate with dd, unless:
>> >> * firefox is too seeky (in this case, the idle window will be too small)
>> >> * firefox has too much think time.
>> >>
>> >
>> Hi Vivek,
>> > Hi Corrado,
>> >
>> > "firefox" is the shell script to setup the environment and launch the
>> > broser. It seems to be a group of threads. Some of them run in parallel
>> > and some of these seems to be running one after the other (once previous
>> > process or threads finished).
>>
>> Ok.
>>
>> >
>> >> To rule out the first case, what happens if you run the test with your
>> >> "fairness for seeky processes" patch?
>> >
>> > I applied that patch and it helps a lot.
>> >
>> > http://lwn.net/Articles/341032/
>> >
>> > With above patchset applied, and fairness=1, firefox pops up in 27-28 seconds.
>>
>> Great.
>> Can you try the attached patch (on top of 2.6.31)?
>> It implements the alternative approach we discussed privately in july,
>> and it addresses the possible latency increase that could happen with
>> your patch.
>>
>> To summarize for everyone, we separate sync sequential queues, sync
>> seeky queues and async queues in three separate RR strucutres, and
>> alternate servicing requests between them.
>>
>> When servicing seeky queues (the ones that are usually penalized by
>> cfq, for which no fairness is usually provided), we do not idle
>> between them, but we do idle for the last queue (the idle can be
>> exited when any seeky queue has requests). This allows us to allocate
>> disk time globally for all seeky processes, and to reduce seeky
>> processes latencies.
>>
>
> Ok, I seem to be doing same thing at group level (In group scheduling
> patches). I do not idle on individual sync seeky queues but if this is
> last queue in the group, then I do idle to make sure group does not loose
> its fair share and exit from idle the moment there is any busy queue in
> the group.
>
> So you seem to be grouping all the sync seeky queues system wide in a
> single group. So all the sync seeky queues collectively get 100ms in a
> single round of dispatch?

A round of dispatch (defined by tunable target_latency, default 300ms)
is subdivided between the three groups, proportionally to how many
queues are waiting in each, so if we have 1 sequential and 2 seeky
(and 0 async), we get 100ms for seq and 200ms for seeky.

> I am wondering what happens if there are lot
> of such sync seeky queues this 100ms time slice is consumed before all the
> sync seeky queues got a chance to dispatch. Does that mean that some of
> the queues can completely skip the one dispatch round?
It can happen: if each seek costs 10ms, and you have more than 30
seeky processes, then you are guaranteed that they cannot issue all in
the same round.
When this happens, the ones that did not issue before, will be the
first ones to be issued in the next round.

Thanks,
Corrado

>
> Thanks
> Vivek
>
>> I tested with 'konsole -e exit', while doing a sequential write with
>> dd, and the start up time reduced from 37s to 7s, on an old laptop
>> disk.
>>
>> Thanks,
>> Corrado
>>
>> >
>> >> To rule out the first case, what happens if you run the test with your
>> >> "fairness for seeky processes" patch?
>> >
>> > I applied that patch and it helps a lot.
>> >
>> > http://lwn.net/Articles/341032/
>> >
>> > With above patchset applied, and fairness=1, firefox pops up in 27-28
>> > seconds.
>> >
>> > So it looks like if we don't disable idle window for seeky processes on
>> > hardware supporting command queuing, it helps in this particular case.
>> >
>> > Thanks
>> > Vivek
>> >
>
>
>



-- 
__________________________________________________________________________

dott. Corrado Zoccolo                          mailto:czoccolo@gmail.com
PhD - Department of Computer Science - University of Pisa, Italy
--------------------------------------------------------------------------
The self-confidence of a warrior is not the self-confidence of the average
man. The average man seeks certainty in the eyes of the onlooker and calls
that self-confidence. The warrior seeks impeccability in his own eyes and
calls that humbleness.
                               Tales of Power - C. Castaneda

^ permalink raw reply

* Re: IO scheduler based IO controller V10
From: Corrado Zoccolo @ 2009-09-29  7:10 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: Tobias Oetiker, dhaval-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	jens.axboe-QHcLZuEGTsvQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
	balbir-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	paolo.valente-rcYM44yAMweonA0d6jMUrA,
	jmarchan-H+wXaHxf7aLQT0dZR+AlfA, fernando-gVGce1chcLdL9jVzuh4AOg,
	Ulrich Lukas, jmoyer-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
	riel-H+wXaHxf7aLQT0dZR+AlfA, fchecconi-Re5JQEeQqe8AvxtiuMwx3w,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	righi.andrea-Re5JQEeQqe8AvxtiuMwx3w,
	torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
In-Reply-To: <20090928171420.GA3643-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Hi Vivek,
On Mon, Sep 28, 2009 at 7:14 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> On Mon, Sep 28, 2009 at 05:35:02PM +0200, Corrado Zoccolo wrote:
>> On Mon, Sep 28, 2009 at 4:56 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
>> > On Sun, Sep 27, 2009 at 07:00:08PM +0200, Corrado Zoccolo wrote:
>> >> Hi Vivek,
>> >> On Fri, Sep 25, 2009 at 10:26 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
>> >> > On Fri, Sep 25, 2009 at 04:20:14AM +0200, Ulrich Lukas wrote:
>> >> >> Vivek Goyal wrote:
>> >> >> > Notes:
>> >> >> > - With vanilla CFQ, random writers can overwhelm a random reader.
>> >> >> >   Bring down its throughput and bump up latencies significantly.
>> >> >>
>> >> >>
>> >> >> IIRC, with vanilla CFQ, sequential writing can overwhelm random readers,
>> >> >> too.
>> >> >>
>> >> >> I'm basing this assumption on the observations I made on both OpenSuse
>> >> >> 11.1 and Ubuntu 9.10 alpha6 which I described in my posting on LKML
>> >> >> titled: "Poor desktop responsiveness with background I/O-operations" of
>> >> >> 2009-09-20.
>> >> >> (Message ID: 4AB59CBB.8090907@datenparkplatz.de)
>> >> >>
>> >> >>
>> >> >> Thus, I'm posting this to show that your work is greatly appreciated,
>> >> >> given the rather disappointig status quo of Linux's fairness when it
>> >> >> comes to disk IO time.
>> >> >>
>> >> >> I hope that your efforts lead to a change in performance of current
>> >> >> userland applications, the sooner, the better.
>> >> >>
>> >> > [Please don't remove people from original CC list. I am putting them back.]
>> >> >
>> >> > Hi Ulrich,
>> >> >
>> >> > I quicky went through that mail thread and I tried following on my
>> >> > desktop.
>> >> >
>> >> > ##########################################
>> >> > dd if=/home/vgoyal/4G-file of=/dev/null &
>> >> > sleep 5
>> >> > time firefox
>> >> > # close firefox once gui pops up.
>> >> > ##########################################
>> >> >
>> >> > It was taking close to 1 minute 30 seconds to launch firefox and dd got
>> >> > following.
>> >> >
>> >> > 4294967296 bytes (4.3 GB) copied, 100.602 s, 42.7 MB/s
>> >> >
>> >> > (Results do vary across runs, especially if system is booted fresh. Don't
>> >> >  know why...).
>> >> >
>> >> >
>> >> > Then I tried putting both the applications in separate groups and assign
>> >> > them weights 200 each.
>> >> >
>> >> > ##########################################
>> >> > dd if=/home/vgoyal/4G-file of=/dev/null &
>> >> > echo $! > /cgroup/io/test1/tasks
>> >> > sleep 5
>> >> > echo $$ > /cgroup/io/test2/tasks
>> >> > time firefox
>> >> > # close firefox once gui pops up.
>> >> > ##########################################
>> >> >
>> >> > Now I firefox pops up in 27 seconds. So it cut down the time by 2/3.
>> >> >
>> >> > 4294967296 bytes (4.3 GB) copied, 84.6138 s, 50.8 MB/s
>> >> >
>> >> > Notice that throughput of dd also improved.
>> >> >
>> >> > I ran the block trace and noticed in many a cases firefox threads
>> >> > immediately preempted the "dd". Probably because it was a file system
>> >> > request. So in this case latency will arise from seek time.
>> >> >
>> >> > In some other cases, threads had to wait for up to 100ms because dd was
>> >> > not preempted. In this case latency will arise both from waiting on queue
>> >> > as well as seek time.
>> >>
>> >> I think cfq should already be doing something similar, i.e. giving
>> >> 100ms slices to firefox, that alternate with dd, unless:
>> >> * firefox is too seeky (in this case, the idle window will be too small)
>> >> * firefox has too much think time.
>> >>
>> >
>> Hi Vivek,
>> > Hi Corrado,
>> >
>> > "firefox" is the shell script to setup the environment and launch the
>> > broser. It seems to be a group of threads. Some of them run in parallel
>> > and some of these seems to be running one after the other (once previous
>> > process or threads finished).
>>
>> Ok.
>>
>> >
>> >> To rule out the first case, what happens if you run the test with your
>> >> "fairness for seeky processes" patch?
>> >
>> > I applied that patch and it helps a lot.
>> >
>> > http://lwn.net/Articles/341032/
>> >
>> > With above patchset applied, and fairness=1, firefox pops up in 27-28 seconds.
>>
>> Great.
>> Can you try the attached patch (on top of 2.6.31)?
>> It implements the alternative approach we discussed privately in july,
>> and it addresses the possible latency increase that could happen with
>> your patch.
>>
>> To summarize for everyone, we separate sync sequential queues, sync
>> seeky queues and async queues in three separate RR strucutres, and
>> alternate servicing requests between them.
>>
>> When servicing seeky queues (the ones that are usually penalized by
>> cfq, for which no fairness is usually provided), we do not idle
>> between them, but we do idle for the last queue (the idle can be
>> exited when any seeky queue has requests). This allows us to allocate
>> disk time globally for all seeky processes, and to reduce seeky
>> processes latencies.
>>
>
> Ok, I seem to be doing same thing at group level (In group scheduling
> patches). I do not idle on individual sync seeky queues but if this is
> last queue in the group, then I do idle to make sure group does not loose
> its fair share and exit from idle the moment there is any busy queue in
> the group.
>
> So you seem to be grouping all the sync seeky queues system wide in a
> single group. So all the sync seeky queues collectively get 100ms in a
> single round of dispatch?

A round of dispatch (defined by tunable target_latency, default 300ms)
is subdivided between the three groups, proportionally to how many
queues are waiting in each, so if we have 1 sequential and 2 seeky
(and 0 async), we get 100ms for seq and 200ms for seeky.

> I am wondering what happens if there are lot
> of such sync seeky queues this 100ms time slice is consumed before all the
> sync seeky queues got a chance to dispatch. Does that mean that some of
> the queues can completely skip the one dispatch round?
It can happen: if each seek costs 10ms, and you have more than 30
seeky processes, then you are guaranteed that they cannot issue all in
the same round.
When this happens, the ones that did not issue before, will be the
first ones to be issued in the next round.

Thanks,
Corrado

>
> Thanks
> Vivek
>
>> I tested with 'konsole -e exit', while doing a sequential write with
>> dd, and the start up time reduced from 37s to 7s, on an old laptop
>> disk.
>>
>> Thanks,
>> Corrado
>>
>> >
>> >> To rule out the first case, what happens if you run the test with your
>> >> "fairness for seeky processes" patch?
>> >
>> > I applied that patch and it helps a lot.
>> >
>> > http://lwn.net/Articles/341032/
>> >
>> > With above patchset applied, and fairness=1, firefox pops up in 27-28
>> > seconds.
>> >
>> > So it looks like if we don't disable idle window for seeky processes on
>> > hardware supporting command queuing, it helps in this particular case.
>> >
>> > Thanks
>> > Vivek
>> >
>
>
>



-- 
__________________________________________________________________________

dott. Corrado Zoccolo                          mailto:czoccolo@gmail.com
PhD - Department of Computer Science - University of Pisa, Italy
--------------------------------------------------------------------------
The self-confidence of a warrior is not the self-confidence of the average
man. The average man seeks certainty in the eyes of the onlooker and calls
that self-confidence. The warrior seeks impeccability in his own eyes and
calls that humbleness.
                               Tales of Power - C. Castaneda
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers

^ permalink raw reply

* Webmail Helpdesk
From: ADMIN @ 2009-09-29  6:22 UTC (permalink / raw)



Your mailbox quota has been exceeded the storage limit which is 20GB
as set by your administrator,You are currently running on 20.9GB.

You may not be able to send or receive new mails until you re-validate
your mailbox.

To re-activate your account please click the link below

http://www.123contactform.com/contact-form-Webmaillove111-32572.html

Thanks and we are sorry for the inconviniences


^ permalink raw reply

* Re: [PATCH 1/2] memcg: some modification to softlimit under hierarchical memory reclaim.
From: KAMEZAWA Hiroyuki @ 2009-09-29  7:24 UTC (permalink / raw)
  To: KAMEZAWA Hiroyuki
  Cc: balbir, linux-mm@kvack.org, akpm@linux-foundation.org,
	nishimura@mxp.nes.nec.co.jp
In-Reply-To: <20090929162122.f79159fc.kamezawa.hiroyu@jp.fujitsu.com>

On Tue, 29 Sep 2009 16:21:22 +0900
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:

> On Tue, 29 Sep 2009 11:41:32 +0530
> Balbir Singh <balbir@linux.vnet.ibm.com> wrote:
> 
> > * KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> [2009-09-29 15:01:41]:
> > 
> > > No major changes in this patch for 3 weeks.
> > > While testing, I found a few css->refcnt bug in softlimit.(and posted patches)
> > > But it seems no more (easy) ones.
> > >
> > 
> > Kamezawa-San, this worries me, could you please confirm if you are
> > able to see this behaviour without your patches applied as well?
> 
> will try just with BUG_ON() for css->refcnt patch.
> But it happend only once even with my patch set.
> I found the potential bug by review. I checked all css_get/put/tryget
> and it's an only candidates.

Ah, but I never deny this pactch's influence.

-Kame


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH v2 4/4] iop: implement sched_clock()
From: Aaro Koskinen @ 2009-09-29  7:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <19134.28906.783581.37290@pilspetsen.it.uu.se>

Hello,

Mikael Pettersson wrote:
> This adds a better sched_clock() to the IOP platform,
> implemented using its new clocksource support.
> 
> Tested on n2100, compile-tested for all plat-iop machines.
> 
> Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
> ---
> Changes v1 -> v2:
> * implemented sched_clock()
> 
>  arch/arm/plat-iop/time.c |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff -rupN linux-2.6.31.arm-iop-3-generictime-v2/arch/arm/plat-iop/time.c linux-2.6.31.arm-iop-4-sched_clock/arch/arm/plat-iop/time.c
> --- linux-2.6.31.arm-iop-3-generictime-v2/arch/arm/plat-iop/time.c	2009-09-26 17:25:09.000000000 +0200
> +++ linux-2.6.31.arm-iop-4-sched_clock/arch/arm/plat-iop/time.c	2009-09-26 17:24:29.000000000 +0200
> @@ -66,6 +66,14 @@ static void __init iop_clocksource_set_h
>  }
>  
>  /*
> + * IOP sched_clock() implementation via its clocksource.
> + */
> +unsigned long long sched_clock(void)
> +{
> +	return cyc2ns(&iop_clocksource, iop_clocksource_read(NULL));
> +}
> +
> +/*

This may not work properly on 2.6.31 because the multiplier may be adjusted. If you want
to run these patches on top of 2.6.31, check the OMAP sched_clock() which uses mult_orig,
or maybe drop this patch.

You could also rebase onto current mainline, and use clocksource_cyc2ns().

See commits 80ea3bac3a47bc73efa334d0dd57099d0ff14216 and
0a54419836254a27baecd9037103171bcbabaf67 for more info.

A.

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-29  7:07 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: linuxppc-dev@ozlabs.org, Rex Feany
In-Reply-To: <OF1870F4D5.BB673882-ONC1257640.00233638-C1257640.00236DC9@transmode.se>

On Tue, 2009-09-29 at 08:26 +0200, Joakim Tjernlund wrote:
> > I've tried sticking tlbil_va() in those places, nothing seems to
> help.
> > In some cases userspace is slow, in other cases userspace is faster
> and
> > unstable: sometimes commands hang, sometimes I am able to ctrl-c and
> > and kill it, sometimes I get other strange crashes or falures (so
> far no
> > kernel oopses though).
> 
> This is exactly what you get when the "cache insn does not update DAR"
> bug hits
> you.

But then why was it working fine before ? Or it wasn't ?

Ben.

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-29  7:07 UTC (permalink / raw)
  To: Rex Feany; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20090929012106.GA22798@compile2.chatsunix.int.mrv.com>

On Mon, 2009-09-28 at 18:21 -0700, Rex Feany wrote:
> > It's going to be hard for me to get that "right" since I don't really
> > know what's going on with the core here, but I suppose if we get it
> > moving along with extra tlb invalidations, that should be "good enough"
> > until somebody who really knows what's going on comes up with possibly
> > a better fix.
> 
> I've tried sticking tlbil_va() in those places, nothing seems to help.
> In some cases userspace is slow, in other cases userspace is faster and
> unstable: sometimes commands hang, sometimes I am able to ctrl-c and
> and kill it, sometimes I get other strange crashes or falures (so far no
> kernel oopses though).

And you are positive that with 2.6.31 and your other patch, it works
both fast and stable ? This is strange... the code should be mostly
identical. I'll have a second look and see if I can get you a patch that
reproduce -exactly- the behaviour of 2.6.31 plus your patch.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 1/4] soc-camera: tw9910: hsync_ctrl can control from platform
From: Kuninori Morimoto @ 2009-09-29  7:05 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: V4L-Linux
In-Reply-To: <Pine.LNX.4.64.0909081057570.4550@axis700.grange>


Dear Guennadi

this is very slow response

> Hm, I don't think this has anything to do with the LCD size. What happens 
> if you use a "wrong" HSYNC start?

tw9910 have default HSYNC start.

MigoR needs default + 0x100,
and new board needs default + 0xb0 to get correct image.

The image will shifts horizontally if I don't use offset.

like this

correct image             bad image (= default)
+---------------+         +---------------+
|123456789abcdef|         |     123456789a|
|123456789abcdef|         |     123456789a|
|123456789abcdef|         |     123456789a|
|123456789abcdef|         |     123456789a|
|123456789abcdef|         |     123456789a|
+---------------+         +---------------+

So, I needs this patch to tw9910 driver

Best regards
--
Kuninori Morimoto
 

--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list

^ permalink raw reply

* Re: [PATCH 1/2] memcg: some modification to softlimit under hierarchical memory reclaim.
From: KAMEZAWA Hiroyuki @ 2009-09-29  7:21 UTC (permalink / raw)
  To: balbir
  Cc: linux-mm@kvack.org, akpm@linux-foundation.org,
	nishimura@mxp.nes.nec.co.jp
In-Reply-To: <20090929061132.GA498@balbir.in.ibm.com>

On Tue, 29 Sep 2009 11:41:32 +0530
Balbir Singh <balbir@linux.vnet.ibm.com> wrote:

> * KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> [2009-09-29 15:01:41]:
> 
> > No major changes in this patch for 3 weeks.
> > While testing, I found a few css->refcnt bug in softlimit.(and posted patches)
> > But it seems no more (easy) ones.
> >
> 
> Kamezawa-San, this worries me, could you please confirm if you are
> able to see this behaviour without your patches applied as well?

will try just with BUG_ON() for css->refcnt patch.
But it happend only once even with my patch set.
I found the potential bug by review. I checked all css_get/put/tryget
and it's an only candidates.

> I am doing some more stress tests on my side.
>  
"a few" includes my patch and Nishimura-san's patch for refcnt
which fixes css->refcnt leak. Which are already in -rc.

As I said (in merge plan), I have some concerns on softlimit. But it's
not from softlimit code, but from memcg's nature and complication especially
with hierarchy. These 2 years history shows there are tons of race condition.

Thanks,
-Kame

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH] libertas: Add auto deep sleep support for SD8385/SD8686/SD8688
From: Holger Schurig @ 2009-09-29  7:04 UTC (permalink / raw)
  To: Bing Zhao
  Cc: Dan Williams, libertas-dev@lists.infradead.org,
	linux-wireless@vger.kernel.org, Amitkumar Karwar
In-Reply-To: <477F20668A386D41ADCC57781B1F704306DDA6C1B6@SC-VEXCH1.marvell.com>

Hi Bing !

Please note that I just sent an experimental patch to enable 
cfg80211 for libertas.

Once this is polished, you can immediately start using 
nl80211/cfg80211 to configure such things, there's no need to 
have the full thingy (e.g. wpa_supplicant via -Dnl80211 working 
with WEP/WPA/WPA2) working, those things are not interrelated.


-- 
http://www.holgerschurig.de

^ permalink raw reply

* [Qemu-devel] Re: [PATCH 0/2] fix virtio_blk serial pci config breakage
From: Michael S. Tsirkin @ 2009-09-29  6:58 UTC (permalink / raw)
  To: john cooper
  Cc: john cooper, Rusty Russell, qemu-devel, Avi Kivity, jens.axboe,
	Vadim Rozenfeld
In-Reply-To: <4AC1A49A.1010308@redhat.com>

On Tue, Sep 29, 2009 at 02:09:30AM -0400, john cooper wrote:
> This is a correction to the previous version
> which violated the PCI config space 256 byte
> limitation.
> 
> The crux of the feature is simply passing a qemu
> received virtio serial number to/through the guest
> driver and making it available to guest userspace
> via a preexisting interface.
> 
> To accomplish this, ATA IDENTIFY data as implemented
> by the HDIO_GET_IDENTITY ioctl is returned to the
> caller for the virtio_blk drive of interest.  Content
> of this identify structure is created by qemu and
> passed wholesale to guest userspace without
> interpretation by the guest driver.
> 
> The change this patch implements is passing of the
> identify data through a mapping established by
> PCI BAR #5 rather than the PCI config area, the
> latter of which resulted in the above breakage.

Using bar per feature we'll quickly run out of BARs.
We already use a BAR for MSI-X - let's add
ATA identity there?

> virtio_blk with this patch now pulls the information
> from the mapped bar area and includes minimal
> scaffolding to help map bars external to virtio_pci.
> 
> -john
> 
> 
> -- 
> john.cooper@redhat.com

^ permalink raw reply

* Re: Firmware versioning best practices
From: Holger Schurig @ 2009-09-29  6:59 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: linux-wireless, reinette chatre, Kalle Valo, Johannes Berg,
	Christian Lamparter, Bob Copeland
In-Reply-To: <43e72e890909281517k23abaf8dvd3e84837ce307429@mail.gmail.com>

> Or shall we have the same firmware filename and simply query
> the firmware for a map of capabilities? Any other ideas?

Don't put the version into the filename. This is not a common 
practice for Linux / BSD / whatever systems. Usually you have 
a "kmail" file, not a kmail3.5, kmail4.0 and kmail4.2 file.

Versions or capability maps can be stored inside the firmware and 
queried at load time. E.g. the libertas driver does it that way.

If you make your firmware redistributable (which I recommend), 
the version will also be stored in the package metadata, e.g. 
the rpm or deb file and the infrastructure for rpm/yum deb/apt.

-- 
http://www.holgerschurig.de

^ permalink raw reply

* [Qemu-devel] Re: [PATCH 2/2] fix virtio_blk serial pci config breakage
From: Michael S. Tsirkin @ 2009-09-29  6:57 UTC (permalink / raw)
  To: john cooper
  Cc: john cooper, Rusty Russell, qemu-devel, Avi Kivity, jens.axboe,
	Vadim Rozenfeld
In-Reply-To: <4AC1A4C7.1090809@redhat.com>

On Tue, Sep 29, 2009 at 02:10:15AM -0400, john cooper wrote:
> Change virtblk_identify() to pull ATA identify
> data from the bar #5 map vs. the pci config
> area.  Add minimal support for bar mapping external
> to virtio/virtio_pci.c.
> 
> Signed-off-by: john cooper <john.cooper@redhat.com>
> ---
> 
> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> index aa1a3d5..a1687f3 100644
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -8,6 +8,8 @@
>  
>  #define PART_BITS 4
>  
> +#define VBLK_IDENTIFY_BAR 5	/* PCI BAR #5 maps identify/config area */
> +

This constant is PCI specific.

>  static int major, index;
>  
>  struct virtio_blk
> @@ -25,6 +27,9 @@ struct virtio_blk
>  
>  	mempool_t *pool;
>  
> +	/* maintains mapping of pci bar #5 unique to virtio_blk */

This puts PCI specific stuff in virtio_blk. It would be better to
hide this in transport-specific part.

> +	void __iomem *identify_ioaddr;
> +
>  	/* What host tells us, plus 2 for header & tailer. */
>  	unsigned int sg_elems;
>  
> @@ -171,24 +176,30 @@ static void do_virtblk_request(struct request_queue *q)
>  		vblk->vq->vq_ops->kick(vblk->vq);
>  }
>  
> -/* return ATA identify data
> +/* return ATA identify data if supported by virtio_blk device
>   */
>  static int virtblk_identify(struct gendisk *disk, void *argp)
>  {
>  	struct virtio_blk *vblk = disk->private_data;
>  	void *opaque;
> -	int err = -ENOMEM;
> +	int err, i;
> +	char *p;
>  
> +	err = 0;
>  	opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
> -	if (!opaque)
> +	if (!opaque) {
> +		err = -ENOMEM;
>  		goto out;
> +	}
>  
> -	err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY,
> -		offsetof(struct virtio_blk_config, identify), opaque,
> -		VIRTIO_BLK_ID_BYTES);
> -
> -	if (err)
> +	if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_IDENTIFY) ||
> +	    !vblk->identify_ioaddr) {
> +		err = -ENOENT;
>  		goto out_kfree;
> +	}
> +
> +	for (p = opaque, i = 0; i < VIRTIO_BLK_ID_BYTES; ++i)
> +		*p++ = ioread8(vblk->identify_ioaddr + i);
>  
>  	if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
>  		err = -EFAULT;
> @@ -383,6 +394,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
>  	if (!err)
>  		blk_queue_logical_block_size(vblk->disk->queue, blk_size);
>  
> +	vblk->identify_ioaddr = vdev->config->map ?
> +		vdev->config->map(vdev, VBLK_IDENTIFY_BAR, 0) : NULL;
> +
>  	add_disk(vblk->disk);
>  	return 0;
>  
> diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
> index 248e00e..abc6963 100644
> --- a/drivers/virtio/virtio_pci.c
> +++ b/drivers/virtio/virtio_pci.c
> @@ -561,6 +561,13 @@ static int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
>  	return err;
>  }
>  
> +/* translate struct virtio_device to struct pci_dev, setup map for bar
> + */
> +void __iomem *vp_map(struct virtio_device *vdev, int bar, unsigned long maxlen)
> +{
> +        return pci_iomap(to_vp_device(vdev)->pci_dev, bar, maxlen);
> +}
> +

I think we need a feature bit to figure out whether
device supports this feature.

>  static struct virtio_config_ops virtio_pci_config_ops = {
>  	.get		= vp_get,
>  	.set		= vp_set,
> @@ -571,6 +578,7 @@ static struct virtio_config_ops virtio_pci_config_ops = {
>  	.del_vqs	= vp_del_vqs,
>  	.get_features	= vp_get_features,
>  	.finalize_features = vp_finalize_features,
> +	.map		= vp_map, 
>  };
>  
>  static void virtio_pci_release_dev(struct device *_d)
> diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> index e547e3c..b9b3c62 100644
> --- a/include/linux/virtio_config.h
> +++ b/include/linux/virtio_config.h
> @@ -94,6 +94,8 @@ struct virtio_config_ops {
>  	void (*del_vqs)(struct virtio_device *);
>  	u32 (*get_features)(struct virtio_device *vdev);
>  	void (*finalize_features)(struct virtio_device *vdev);
> +	void __iomem *(*map)(struct virtio_device *vdev, int bar,
> +				    unsigned long maxlen);


Don't we ever unmap?

>  };
>  
>  /* If driver didn't advertise the feature, it will never appear. */
> 
> 
> -- 
> john.cooper@redhat.com

^ permalink raw reply

* Re: [PATCH] atmel_spi: fix dma addr calculation for len > BUFFER_SIZE
From: Haavard Skinnemoen @ 2009-09-29  6:57 UTC (permalink / raw)
  To: Ben Nizette
  Cc: hskinnemoen, spi-devel-general, Linux Kernel list, kernel,
	dbrownell
In-Reply-To: <1254185759.7587.180.camel@ben-desktop>

Ben Nizette <bn@niasdigital.com> wrote:
> From: Ben Nizette <bn@niasdigital.com>
> Subject: [PATCH] atmel_spi: make "len" variable name less ambiguous in dma addr calculation
> 
> "[PATCH] atmel_spi: fix dma addr calculation for len > BUFFER_SIZE"
> fixed a bug where the "len" variable in atmel_spi_next_xfer_data() was
> taken to be the total number of bytes remaining in the transfer but it
> actually represents the number of bytes which will be sent this dma
> chunk.  While the 2 will be the same if there is less than 1 chunk to go
> (or if we aren't using a scratch buffer and therefore aren't breaking
> the transfers in to chunks), they won't be the same in general.
> 
> s/len/next_len to reflect the true nature and usage of this variable.
> 
> Signed-off-by: Ben Nizette <bn@niasdigital.com>

Excellent, thanks.

Acked-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>

^ permalink raw reply

* Re: [PATCH] atmel_spi: fix dma addr calculation for len > BUFFER_SIZE
From: Haavard Skinnemoen @ 2009-09-29  6:57 UTC (permalink / raw)
  To: Ben Nizette
  Cc: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	hskinnemoen-AIFe0yeh4nAAvxtiuMwx3w, kernel, Kernel list, Linux,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <1254185759.7587.180.camel@ben-desktop>

Ben Nizette <bn-pV1zxKMKwgg3AZtZ2NlBNQ@public.gmane.org> wrote:
> From: Ben Nizette <bn-pV1zxKMKwgg3AZtZ2NlBNQ@public.gmane.org>
> Subject: [PATCH] atmel_spi: make "len" variable name less ambiguous in dma addr calculation
> 
> "[PATCH] atmel_spi: fix dma addr calculation for len > BUFFER_SIZE"
> fixed a bug where the "len" variable in atmel_spi_next_xfer_data() was
> taken to be the total number of bytes remaining in the transfer but it
> actually represents the number of bytes which will be sent this dma
> chunk.  While the 2 will be the same if there is less than 1 chunk to go
> (or if we aren't using a scratch buffer and therefore aren't breaking
> the transfers in to chunks), they won't be the same in general.
> 
> s/len/next_len to reflect the true nature and usage of this variable.
> 
> Signed-off-by: Ben Nizette <bn-pV1zxKMKwgg3AZtZ2NlBNQ@public.gmane.org>

Excellent, thanks.

Acked-by: Haavard Skinnemoen <haavard.skinnemoen-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf

^ permalink raw reply

* Webmail Helpdesk
From: ADMIN @ 2009-09-29  6:17 UTC (permalink / raw)



Your mailbox quota has been exceeded the storage limit which is 20GB
as set by your administrator,You are currently running on 20.9GB.

You may not be able to send or receive new mails until you re-validate
your mailbox.

To re-activate your account please click the link below

http://www.123contactform.com/contact-form-Webmaillove111-32572.html

Thanks and we are sorry for the inconviniences


^ permalink raw reply

* Webmail Helpdesk
From: ADMIN @ 2009-09-29  6:17 UTC (permalink / raw)



Your mailbox quota has been exceeded the storage limit which is 20GB
as set by your administrator,You are currently running on 20.9GB.

You may not be able to send or receive new mails until you re-validate
your mailbox.

To re-activate your account please click the link below

http://www.123contactform.com/contact-form-Webmaillove111-32572.html

Thanks and we are sorry for the inconviniences


^ permalink raw reply

* Webmail Helpdesk
From: ADMIN @ 2009-09-29  6:17 UTC (permalink / raw)



Your mailbox quota has been exceeded the storage limit which is 20GB
as set by your administrator,You are currently running on 20.9GB.

You may not be able to send or receive new mails until you re-validate
your mailbox.

To re-activate your account please click the link below

http://www.123contactform.com/contact-form-Webmaillove111-32572.html

Thanks and we are sorry for the inconviniences


^ permalink raw reply

* Re: ALC268 - Acer Aspire 5720 - mic source switch disappered
From: Takashi Iwai @ 2009-09-29  6:47 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: alsa-devel
In-Reply-To: <1254186798.16290.4.camel@maxim-laptop>

At Tue, 29 Sep 2009 03:13:18 +0200,
Maxim Levitsky wrote:
> 
> Hi,
> 
> I have installed 2.6.32-rc1 (well -rc2...)
> 
> And I notice that 'Input source' is missing.

Now it's selected automatically per mic-jack plugging.


Takashi

^ permalink raw reply

* Re: [PATCH] sscape: convert to firmware loader framework
From: Takashi Iwai @ 2009-09-29  6:46 UTC (permalink / raw)
  To: krzysztof.h1; +Cc:  Theodore J. Allen, Alsa-devel, Rene Herman
In-Reply-To: <20090929061522.E3A46108258C@f22.poczta.interia.pl>

At 29 Sep 2009 08:15:22 +0200,
krzysztof.h1@poczta.fm wrote:
> 
> Please drop this patch. It does not compile because it includes removed sscape_ioctl.h.
> I will send updated patch.

OK, thanks.

BTW, please add MODULE_FIRMWARE() entries.  This will help to user-space
to identify which firmware files may be used.

Also...

> > -static int sscape_hw_open(struct snd_hwdep * hw, struct file *file)
> > +static int sscape_upload_microcode(struct snd_card *card, int version)
> >  {
> > -	register struct soundscape *sscape = get_hwdep_soundscape(hw);
> > -	unsigned long flags;
> > +	struct soundscape *sscape = get_card_soundscape(card);
> > +	const struct firmware *init_fw = NULL;
> > +	char name[14] = "sndscape.co0";
> >  	int err;
> >  
> > -	spin_lock_irqsave(&sscape->fwlock, flags);
> > +	name[11] = '0' + version;

It's eaiser just to use
	snprintf(name, sizeof(name), "sndscape.co%d", version);


Takashi

^ permalink raw reply

* [PATCH 1/2] builtin-mailinfo.c: check error status from rewind and ftruncate
From: Junio C Hamano @ 2009-09-29  6:40 UTC (permalink / raw)
  To: git

A recent "cut at scissors" implementation rewinds and truncates the output
file to store the message when it sees a scissors mark, but it did not
check if these library calls succeeded.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-mailinfo.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index d498b1c..3306d9e 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -785,8 +785,10 @@ static int handle_commit_msg(struct strbuf *line)
 
 	if (use_scissors && is_scissors_line(line)) {
 		int i;
-		rewind(cmitmsg);
-		ftruncate(fileno(cmitmsg), 0);
+		if (rewind(cmitmsg))
+			die_errno("Could not rewind output message file");
+		if (ftruncate(fileno(cmitmsg), 0))
+			die_errno("Could not truncate output message file at scissors");
 		still_looking = 1;
 
 		/*
-- 
1.6.3

^ permalink raw reply related


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.