Welcome! Log In Create A New Profile

Advanced

[PATCH 00/21] vfs: atomic open v6 (part 2)

Posted by Miklos Szeredi 
Miklos Szeredi
[PATCH 00/21] vfs: atomic open v6 (part 2)
June 05, 2012 03:30PM
This is part 2 of the atomic open series. It introduces i_op->atomic_open() and
converts filesystems that abuse ->lookup() and ->create() to use this new
interface instead.

This version has one bugfix and several cleanups, reported by David Howells.
Also updated documentation in Documentation/filesytems/{vfs.txt,Locking}.

Al, please apply.

git tree is here:

git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git atomic-open.v6

Thanks,
Miklos
---

Miklos Szeredi (21):
vfs: do_last(): inline lookup_slow()
vfs: do_last(): separate O_CREAT specific code
vfs: do_last(): common slow lookup
vfs: add lookup_open()
vfs: lookup_open(): expand lookup_hash()
vfs: add i_op->atomic_open()
nfs: implement i_op->atomic_open()
nfs: clean up ->create in nfs_rpc_ops
nfs: don't use nd->intent.open.flags
nfs: don't use intents for checking atomic open
fuse: implement i_op->atomic_open()
cifs: implement i_op->atomic_open()
ceph: remove unused arg from ceph_lookup_open()
ceph: implement i_op->atomic_open()
9p: implement i_op->atomic_open()
vfs: remove open intents from nameidata
vfs: do_last(): clean up error handling
vfs: do_last(): clean up labels
vfs: do_last(): clean up bool
vfs: do_last(): clean up retry
vfs: move O_DIRECT check to common code

---
Documentation/filesystems/Locking | 4 +
Documentation/filesystems/vfs.txt | 11 +
fs/9p/vfs_inode.c | 169 ++++++++-----
fs/9p/vfs_inode_dotl.c | 52 +++--
fs/ceph/dir.c | 68 ++++--
fs/ceph/file.c | 22 +-
fs/ceph/super.h | 6 +-
fs/cifs/cifsfs.c | 1 +
fs/cifs/cifsfs.h | 3 +
fs/cifs/dir.c | 437 ++++++++++++++++++---------------
fs/fuse/dir.c | 94 +++++--
fs/internal.h | 8 +-
fs/namei.c | 492 ++++++++++++++++++++++++++-----------
fs/nfs/dir.c | 242 ++++++++-----------
fs/nfs/nfs3proc.c | 2 +-
fs/nfs/nfs4proc.c | 37 +--
fs/nfs/proc.c | 2 +-
fs/open.c | 91 ++-----
include/linux/fs.h | 7 +
include/linux/namei.h | 11 -
include/linux/nfs_xdr.h | 2 +-
21 files changed, 1023 insertions(+), 738 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Miklos Szeredi
[PATCH 08/21] nfs: clean up ->create in nfs_rpc_ops
June 05, 2012 03:30PM
From: Miklos Szeredi <[email protected]>

Don't pass nfs_open_context() to ->create(). Only the NFS4 implementation
needed that and only because it wanted to return an open file using open
intents. That task has been replaced by ->atomic_open so it is not necessary
anymore to pass the context to the create rpc operation.

Despite nfs4_proc_create apparently being okay with a NULL context it Oopses
somewhere down the call chain. So allocate a context here.

Signed-off-by: Miklos Szeredi <[email protected]>
CC: Trond Myklebust <[email protected]>
---
fs/nfs/dir.c | 42 ++----------------------------------------
fs/nfs/nfs3proc.c | 2 +-
fs/nfs/nfs4proc.c | 37 ++++++++++---------------------------
fs/nfs/proc.c | 2 +-
include/linux/nfs_xdr.h | 2 +-
5 files changed, 15 insertions(+), 70 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 0d8c712..45015d3 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -114,10 +114,8 @@ const struct inode_operations nfs3_dir_inode_operations = {
static struct file *nfs_atomic_open(struct inode *, struct dentry *,
struct opendata *, unsigned, umode_t,
bool *);
-static int nfs4_create(struct inode *dir, struct dentry *dentry,
- umode_t mode, struct nameidata *nd);
const struct inode_operations nfs4_dir_inode_operations = {
- .create = nfs4_create,
+ .create = nfs_create,
.lookup = nfs_lookup,
.atomic_open = nfs_atomic_open,
.link = nfs_link,
@@ -1582,42 +1580,6 @@ no_open:
return nfs_lookup_revalidate(dentry, nd);
}

-static int nfs4_create(struct inode *dir, struct dentry *dentry,
- umode_t mode, struct nameidata *nd)
-{
- struct nfs_open_context *ctx = NULL;
- struct iattr attr;
- int error;
- int open_flags = O_CREAT|O_EXCL;
-
- dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
- dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
-
- attr.ia_mode = mode;
- attr.ia_valid = ATTR_MODE;
-
- if (nd)
- open_flags = nd->intent.open.flags;
-
- ctx = create_nfs_open_context(dentry, open_flags);
- error = PTR_ERR(ctx);
- if (IS_ERR(ctx))
- goto out_err_drop;
-
- error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx);
- if (error != 0)
- goto out_put_ctx;
-
- put_nfs_open_context(ctx);
-
- return 0;
-out_put_ctx:
- put_nfs_open_context(ctx);
-out_err_drop:
- d_drop(dentry);
- return error;
-}
-
#endif /* CONFIG_NFSV4 */

/*
@@ -1684,7 +1646,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry,
if (nd)
open_flags = nd->intent.open.flags;

- error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL);
+ error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
if (error != 0)
goto out_err;
return 0;
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 2292a0f..3187e24 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -314,7 +314,7 @@ static void nfs3_free_createdata(struct nfs3_createdata *data)
*/
static int
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags, struct nfs_open_context *ctx)
+ int flags)
{
struct nfs3_createdata *data;
umode_t mode = sattr->ia_mode;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d48dbef..267be3c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2779,37 +2779,22 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
}

/*
- * Got race?
- * We will need to arrange for the VFS layer to provide an atomic open.
- * Until then, this create/open method is prone to inefficiency and race
- * conditions due to the lookup, create, and open VFS calls from sys_open()
- * placed on the wire.
- *
- * Given the above sorry state of affairs, I'm simply sending an OPEN.
- * The file will be opened again in the subsequent VFS open call
- * (nfs4_proc_file_open).
- *
- * The open for read will just hang around to be used by any process that
- * opens the file O_RDONLY. This will all be resolved with the VFS changes.
+ * This is just for mknod. open(O_CREAT) will always do ->open_context().
*/
-
static int
nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags, struct nfs_open_context *ctx)
+ int flags)
{
- struct dentry *de = dentry;
+ struct nfs_open_context *ctx;
struct nfs4_state *state;
- struct rpc_cred *cred = NULL;
- fmode_t fmode = 0;
int status = 0;

- if (ctx != NULL) {
- cred = ctx->cred;
- de = ctx->dentry;
- fmode = ctx->mode;
- }
+ ctx = alloc_nfs_open_context(dentry, FMODE_READ);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
sattr->ia_mode &= ~current_umask();
- state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL);
+ state = nfs4_do_open(dir, dentry, ctx->mode, flags, sattr, ctx->cred, NULL);
d_drop(dentry);
if (IS_ERR(state)) {
status = PTR_ERR(state);
@@ -2817,11 +2802,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
}
d_add(dentry, igrab(state->inode));
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
- if (ctx != NULL)
- ctx->state = state;
- else
- nfs4_close_sync(state, fmode);
+ ctx->state = state;
out:
+ put_nfs_open_context(ctx);
return status;
}

diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index a706b6b..81a0a42 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -259,7 +259,7 @@ static void nfs_free_createdata(const struct nfs_createdata *data)

static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags, struct nfs_open_context *ctx)
+ int flags)
{
struct nfs_createdata *data;
struct rpc_message msg = {
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index d1a7bf5..660c0f5 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1371,7 +1371,7 @@ struct nfs_rpc_ops {
int (*readlink)(struct inode *, struct page *, unsigned int,
unsigned int);
int (*create) (struct inode *, struct dentry *,
- struct iattr *, int, struct nfs_open_context *);
+ struct iattr *, int);
int (*remove) (struct inode *, struct qstr *);
void (*unlink_setup) (struct rpc_message *, struct inode *dir);
void (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *);
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Miklos Szeredi <[email protected]>

Check O_CREAT on the slow lookup paths where necessary. This allows the rest to
be shared with plain open.

Signed-off-by: Miklos Szeredi <[email protected]>
---
fs/namei.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index d6e8c55..73e824c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2265,22 +2265,23 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
inode = path->dentry->d_inode;
}
goto finish_lookup;
- }
-
- /* create side of things */
- /*
- * This will *only* deal with leaving RCU mode - LOOKUP_JUMPED has been
- * cleared when we got to the last component we are about to look up
- */
- error = complete_walk(nd);
- if (error)
- return ERR_PTR(error);
+ } else {
+ /* create side of things */
+ /*
+ * This will *only* deal with leaving RCU mode - LOOKUP_JUMPED
+ * has been cleared when we got to the last component we are
+ * about to look up
+ */
+ error = complete_walk(nd);
+ if (error)
+ return ERR_PTR(error);

- audit_inode(pathname, dir);
- error = -EISDIR;
- /* trailing slashes? */
- if (nd->last.name[nd->last.len])
- goto exit;
+ audit_inode(pathname, dir);
+ error = -EISDIR;
+ /* trailing slashes? */
+ if (nd->last.name[nd->last.len])
+ goto exit;
+ }

retry_lookup:
mutex_lock(&dir->d_inode->i_mutex);
@@ -2296,7 +2297,7 @@ retry_lookup:
path->mnt = nd->path.mnt;

/* Negative dentry, just create the file */
- if (!dentry->d_inode) {
+ if (!dentry->d_inode && (open_flag & O_CREAT)) {
umode_t mode = op->mode;
if (!IS_POSIXACL(dir->d_inode))
mode &= ~current_umask();
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Miklos Szeredi
[PATCH 09/21] nfs: don't use nd->intent.open.flags
June 05, 2012 03:30PM
From: Miklos Szeredi <[email protected]>

Instead check LOOKUP_EXCL in nd->flags, which is basically what the open intent
flags were used for.

Signed-off-by: Miklos Szeredi <[email protected]>
CC: Trond Myklebust <[email protected]>
---
fs/nfs/dir.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 45015d3..0432f47 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1538,7 +1538,7 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
struct dentry *parent = NULL;
struct inode *inode;
struct inode *dir;
- int openflags, ret = 0;
+ int ret = 0;

if (nd->flags & LOOKUP_RCU)
return -ECHILD;
@@ -1562,9 +1562,8 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
/* NFS only supports OPEN on regular files */
if (!S_ISREG(inode->i_mode))
goto no_open_dput;
- openflags = nd->intent.open.flags;
/* We cannot do exclusive creation on a positive dentry */
- if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
+ if (nd && nd->flags & LOOKUP_EXCL)
goto no_open_dput;

/* Let f_op->open() actually open (and revalidate) the file */
@@ -1643,8 +1642,8 @@ static int nfs_create(struct inode *dir, struct dentry *dentry,
attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE;

- if (nd)
- open_flags = nd->intent.open.flags;
+ if (nd && !(nd->flags & LOOKUP_EXCL))
+ open_flags = O_CREAT;

error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
if (error != 0)
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Linus Torvalds
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 05, 2012 05:50PM
On Tue, Jun 5, 2012 at 6:10 AM, Miklos Szeredi <[email protected]> wrote:
>
> This version has one bugfix and several cleanups, reported by David Howells.
> Also updated documentation in Documentation/filesytems/{vfs.txt,Locking}.

I assume the "one bugfix" is against an earlier version of this
series, not against the currently merged stuff? Because this is too
late for 3.5, so if the bugfix is for current code, please send that
separately..

Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Miklos Szeredi
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 05, 2012 06:00PM
Linus Torvalds <[email protected]> writes:

> On Tue, Jun 5, 2012 at 6:10 AM, Miklos Szeredi <[email protected]> wrote:
>>
>> This version has one bugfix and several cleanups, reported by David Howells.
>> Also updated documentation in Documentation/filesytems/{vfs.txt,Locking}.
>
> I assume the "one bugfix" is against an earlier version of this
> series, not against the currently merged stuff?

Right, the fix is against the second part of the series, so code
committed into 3.5 shouldn't be affected.

Thanks,
Miklos
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 10, 2012 06:00AM
On Tue, Jun 05, 2012 at 03:10:11PM +0200, Miklos Szeredi wrote:
> This is part 2 of the atomic open series. It introduces i_op->atomic_open() and
> converts filesystems that abuse ->lookup() and ->create() to use this new
> interface instead.
>
> This version has one bugfix and several cleanups, reported by David Howells.
> Also updated documentation in Documentation/filesytems/{vfs.txt,Locking}.
>
> Al, please apply.
>
> git tree is here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git atomic-open.v6

I'm more or less OK with that; one major exception is your struct opendata.
I think it needs to go. Really. You are using it to store three references -
file, vfsmount and dentry. You allocate struct file at the very beginning
and store it there; no arguments with that, if you are opening a file, by
damn you do need one. But that's where it starts to get really, really
odd. At some point you find vfsmount to be used. Again, you'd better -
we will need it. It ends up in file->f_path.mnt. And that's struct file
opendata ->filp points to. So why the hell do you not store it right there?
The same goes for dentry. You will need something to put into
file->f_path.dentry; that field is not going away, no matter what - we do
need to know which filesystem object read() and write() should deal with,
after all. So why bother with storing it in opendata ->dentry in the
meanwhile, when you have the instance of struct file whose ->f_path.dentry
is to be determined by all that activity?

And if you do that, your struct opendata suddenly shrinks to single struct
file *. Which you assign in the very beginning, pass by reference to all
that code and do not reassign. OK, you do reassign it. In one place:
res = do_dentry_open(dentry, od->mnt, od->filp, open, current_cred());
if (!IS_ERR(res))
od->filp = NULL;
return res;
Here do_dentry_open() returns one of two things - the value of its third
argument (i.e. od->filp) or ERR_PTR(-E...). In the latter case struct
file refered to by the third argument has been freed.

So the only remaining reason for having that thing is this: what if we
call ->atomic_open(), but it doesn't call finish_open()? Then we need
to free that unused struct file. If finish_open() failed, we wouldn't.
Same if it succeeded and something *after* it in ->atomic_open() failed
(then we need to fput() that file - your code in ceph leaks it, BTW).
Fair enough. So we need to add one more helper that would discard that
half-set-up struct file as we want it to be discarded. That's all.

IOW, you get three helpers:
finish_open()
finish_no_open() (really confusing name, BTW)
fail_open()

All of them taking struct file *. Any call of ->atomic_open() must
call one of those. Rules:
* if we called finish_no_open(), we need to return NULL.
That's the "won't open, here's your dentry, open it yourself".
BTW, I would've made it return void * - always NULL. So that
callers would be of form return finish_no_open(file, dentry);
* if we called finish_open() and it returned us an error,
we need to return that to our caller. End of story, we'd failed.
* if we called finish_open() and it succeeded, the file
has been opened. Either return it, or fput() it and return ERR_PTR()
if you have something fail past that point.
* otherwise we need to call failed_open(file). And return
appropriate ERR_PTR(). Might make sense to turn that into
return failed_open(file, ERR_PTR(-E...)); to make dumb errors easy
to spot.

And this is it - no more struct opendata, considerably simpler cleanup
in fs/namei.c and much more natural prototypes. Either ->atomic_open()
returns an opened struct file, or it gives us ERR_PTR(...) (in which case
struct file has been freed/vfsmount dropped/etc.) or it gives us NULL.
In the last case struct file is still there and file->f_path contains
the vfsmount/dentry pair we are supposed to deal with (e.g. on hitting
a symlink).

I can massage it to that form, or I can leave conversion at the end;
up to you - it's going to be a single pull request anyway, so prototype
changes midway through the series are not something tragic. OTOH, folding
said changes back into the original patches might make for less confusing
reading later. Credit for dealing with that really, really scary pile
of shit is clearly yours anyway. And I'm absolutely serious - that has
been a work that needed doing and nobody had stomach for it. You have
my sincere gratitude.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 10, 2012 08:00AM
BTW, I realize that right now you are relying on -EOPENSTALE
never coming out of ->atomic_open(), but that needs to be documented.
For now I'm adding BUG_ON() there as a crude way of documenting it;
AFAICS, there's no point whatsoever doing retries in that case.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 10, 2012 01:20PM
On Sun, Jun 10, 2012 at 04:49:21AM +0100, Al Viro wrote:

> So the only remaining reason for having that thing is this: what if we
> call ->atomic_open(), but it doesn't call finish_open()? Then we need
> to free that unused struct file. If finish_open() failed, we wouldn't.
> Same if it succeeded and something *after* it in ->atomic_open() failed
> (then we need to fput() that file - your code in ceph leaks it, BTW).
> Fair enough. So we need to add one more helper that would discard that
> half-set-up struct file as we want it to be discarded. That's all.

Actually, I take that back - that code in ceph is unreachable when
finish_open() succeeds.

Anyway, see vfs.git#atomic_open; it's a port of your queue + COMPLETELY
UNTESTED followups massaging it along the following lines:
* ->atomic_open() takes struct file * instead of struct opendata *
* it return int instead of struct file * - 0 for succeess, -E...
for error, 1 for "here's your sodding dentry, do it yourself". Said
dentry is returned via file->f_path.dentry.
* the same had been done to atomic_open()/lookup_open()/do_last()
* finish_open() takes struct file and returns an int
* it *also* takes int * - used to keep track of whether we'd done
successful do_dentry_open(), instead of "has opendata->filp been cleared?"
as in your variant. Said int * is what your bool *created of ->atomic_open()
and friends has been turned into. So the check in path_openat() is
if (!(opened & FILE_OPENED)) {
BUG_ON(!error);
put_filp(file);
}
which is as explicit as it gets, IMO.

The forest of failure exits in do_last() got cleaned up a bit, BTW. Probably
can be cleaned up some more...

WARNING: I haven't even tried to boot it. It builds, but this is all I can
promise at the moment. I'm about to fall down (it's 7am here already ;-/),
will give it some beating when I get up. It almost certainly has bugs, so
consider that as call for review and not much more.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 10, 2012 08:00PM
On Sun, Jun 10, 2012 at 12:10:56PM +0100, Al Viro wrote:

> WARNING: I haven't even tried to boot it. It builds, but this is all I can
> promise at the moment. I'm about to fall down (it's 7am here already ;-/),
> will give it some beating when I get up. It almost certainly has bugs, so
> consider that as call for review and not much more.

OK, it boots, mounts NFS and even manages to build a kernel on it. Which
probably would meet Linus' "it's perfect, ship it" criteria, so go ahead
and beat it up, folks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 11, 2012 12:30AM
On Sun, Jun 10, 2012 at 06:56:05PM +0100, Al Viro wrote:
> On Sun, Jun 10, 2012 at 12:10:56PM +0100, Al Viro wrote:
>
> > WARNING: I haven't even tried to boot it. It builds, but this is all I can
> > promise at the moment. I'm about to fall down (it's 7am here already ;-/),
> > will give it some beating when I get up. It almost certainly has bugs, so
> > consider that as call for review and not much more.
>
> OK, it boots, mounts NFS and even manages to build a kernel on it. Which
> probably would meet Linus' "it's perfect, ship it" criteria, so go ahead
> and beat it up, folks.

And in vfs.git#master there's a followup to that. ->d_revalidate(),
->lookup() and ->create() are nameidata-free now. IOW, open intents
crap is well and truly dead. Good riddance.

Miklos, if I see you at Kernel Summit (or anywhere else, for that matter),
I owe you a bottle of booze of your choice.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Boaz Harrosh
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 11, 2012 01:00PM
On 06/10/2012 08:56 PM, Al Viro wrote:

> On Sun, Jun 10, 2012 at 12:10:56PM +0100, Al Viro wrote:
>
>> WARNING: I haven't even tried to boot it. It builds, but this is all I can
>> promise at the moment. I'm about to fall down (it's 7am here already ;-/),
>> will give it some beating when I get up. It almost certainly has bugs, so
>> consider that as call for review and not much more.
>
> OK, it boots, mounts NFS and even manages to build a kernel on it. Which
> probably would meet Linus' "it's perfect, ship it" criteria, so go ahead
> and beat it up, folks.


If the "manages to build a kernel on it" part involves a "git clone" first
then I agree. From past bug I found that even if xfstest cthon and bunch of
other testes pass, I still got data-corruption/bugs under
"git clone linux, umount, mount, git status". It's my best test so far.
(It needs to be a very big git tree with lots of history as well, like linux or gcc)

Cheers
Boaz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Miklos Szeredi
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 11, 2012 05:20PM
Al Viro <[email protected]> writes:

>
> I'm more or less OK with that; one major exception is your struct opendata.
> I think it needs to go. Really. You are using it to store three references -
> file, vfsmount and dentry.

That's not the real purpose. We can store those in struct file, I can
see that.

The real reason I went with a separate and opaque type there is that
that thing is simply not an open file. If it was a struct file and the
filesystem would do an fput() on it by accident it would lead to really
ugly problems, and the complier would have no chance at detecting it.

If it's a separate type (and it can have just that struct file embedded
into it) then such mistakes are instantly detected by the compiler

So I really don't see the downsides of having a new type for that.

Thanks,
Miklos
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Miklos Szeredi
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 11, 2012 06:40PM
I don't like this:

make ->atomic_open() return int

Change of calling conventions:
old new
NULL 1
file 0
ERR_PTR(-ve) -ve

Caller *knows* that struct file *; no need to return it.

Yes, ordinary filesystems the caller knows the 'struct file *' but for
overlayfs (and stacking in general) wants to be able to return a file
obtained by opening the file on another filesystem.

Thanks,
Miklos

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Christoph Hellwig
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 13, 2012 01:30PM
On Sun, Jun 10, 2012 at 11:27:45PM +0100, Al Viro wrote:
> And in vfs.git#master there's a followup to that. ->d_revalidate(),
> ->lookup() and ->create() are nameidata-free now. IOW, open intents
> crap is well and truly dead. Good riddance.
>
> Miklos, if I see you at Kernel Summit (or anywhere else, for that matter),
> I owe you a bottle of booze of your choice.

It also shows that were are really close to getting nameidata out of the
filesystem. The remaning issues are kern_path_parent usages in devtmpfs
and audit_watch, as well as direct access to nd->path in
proc_pid_follow_link. A hacky patch to demonstrate this is below (not
intended for submission).


diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 765c3a2..b5e907b 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -25,6 +25,8 @@
#include <linux/slab.h>
#include <linux/kthread.h>

+#include "../internal.h"
+
static struct task_struct *thread;

#if defined CONFIG_DEVTMPFS_MOUNT
diff --git a/fs/internal.h b/fs/internal.h
index 8a9f5fa..3826dcc 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -115,3 +115,23 @@ extern int invalidate_inodes(struct super_block *, bool);
* dcache.c
*/
extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
+
+
+enum { MAX_NESTED_LINKS = 8 };
+
+struct nameidata {
+ struct path path;
+ struct qstr last;
+ struct path root;
+ struct inode *inode; /* path.dentry.d_inode */
+ unsigned int flags;
+ unsigned seq;
+ int last_type;
+ unsigned depth;
+ char *saved_names[MAX_NESTED_LINKS + 1];
+};
+
+/*
+ * Type of the last component on LOOKUP_PARENT
+ */
+enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
diff --git a/fs/namei.c b/fs/namei.c
index 1fc02ff..2ea6608 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3629,6 +3629,18 @@ out:
return len;
}

+void nd_set_link(struct nameidata *nd, char *path)
+{
+ nd->saved_names[nd->depth] = path;
+}
+EXPORT_SYMBOL(nd_set_link);
+
+char *nd_get_link(struct nameidata *nd)
+{
+ return nd->saved_names[nd->depth];
+}
+EXPORT_SYMBOL(nd_get_link);
+
/*
* A helper for ->readlink(). This should be used *ONLY* for symlinks that
* have ->follow_link() touching nd only in nd_set_link(). Using (or not
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8eaa5ea..5453fdd 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -90,6 +90,7 @@
#endif
#include <trace/events/oom.h>
#include "internal.h"
+#include "../internal.h"

/* NOTE:
* Implementing inode permission operations in /proc is almost
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 54dadda..5d92c0a 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -5,26 +5,7 @@
#include <linux/linkage.h>
#include <linux/path.h>

-struct vfsmount;
-
-enum { MAX_NESTED_LINKS = 8 };
-
-struct nameidata {
- struct path path;
- struct qstr last;
- struct path root;
- struct inode *inode; /* path.dentry.d_inode */
- unsigned int flags;
- unsigned seq;
- int last_type;
- unsigned depth;
- char *saved_names[MAX_NESTED_LINKS + 1];
-};
-
-/*
- * Type of the last component on LOOKUP_PARENT
- */
-enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+struct nameidata;

/*
* The bitmask for a lookup event:
@@ -71,9 +52,6 @@ extern int kern_path_parent(const char *, struct nameidata *);
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
const char *, unsigned int, struct path *);

-extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
- int (*open)(struct inode *, struct file *));
-
extern struct dentry *lookup_one_len(const char *, struct dentry *, int);

extern int follow_down_one(struct path *);
@@ -83,15 +61,8 @@ extern int follow_up(struct path *);
extern struct dentry *lock_rename(struct dentry *, struct dentry *);
extern void unlock_rename(struct dentry *, struct dentry *);

-static inline void nd_set_link(struct nameidata *nd, char *path)
-{
- nd->saved_names[nd->depth] = path;
-}
-
-static inline char *nd_get_link(struct nameidata *nd)
-{
- return nd->saved_names[nd->depth];
-}
+extern void nd_set_link(struct nameidata *nd, char *path);
+extern char *nd_get_link(struct nameidata *nd);

static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
{
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index e683869..0943897 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -32,6 +32,8 @@
#include <linux/security.h>
#include "audit.h"

+#include "../fs/internal.h"
+
/*
* Reference counting:
*
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 14, 2012 10:10AM
On Wed, Jun 13, 2012 at 07:21:12AM -0400, Christoph Hellwig wrote:

> It also shows that were are really close to getting nameidata out of the
> filesystem. The remaning issues are kern_path_parent usages in devtmpfs
> and audit_watch, as well as direct access to nd->path in
> proc_pid_follow_link. A hacky patch to demonstrate this is below (not
> intended for submission).

Those are easily handled - kern_path_parent() ones are begging for
something like
int path_lookup_locked(char *name, struct path *path)
resulting in dentry/vfsmount pair stored in path, dentry possibly
negative and its parent known to have locked inode (i.e. path->dentry->d_parent
is stable until we unlock path->dentry->d_parent->d_inode->i_mutex).

And proc_pid_follow_link() is easier yet - explicit nd_jump_link(nd, path),
to be called by magical symlinks' ->follow_link().

Can do.. As for Miklos' objection re overlayfs - I'm tempted to make
path_openat() take struct file * as explicit argument, convert the
existing callers into path_openat(get_empty_filp(), ...) and let the
stacking ones use that.

My objection against opendata is that it's both an offense against Occam's
Razor (i.e. opaque object where none is needed) *and* not really opaque at
that - restrictions on the sequence of operations are non-trivial and
that has at least as high potential for bugs as bogus fput() done by broken fs.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Christoph Hellwig
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 17, 2012 10:40PM
vfs.git#master fails xfstests 005 (Test symlinks & ELOOP) for me. I'll
try to get it bisected tomorrow, unless anyone gets to it earlier.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Christoph Hellwig
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 18, 2012 02:00PM
On Sun, Jun 17, 2012 at 04:37:55PM -0400, Christoph Hellwig wrote:
> vfs.git#master fails xfstests 005 (Test symlinks & ELOOP) for me. I'll
> try to get it bisected tomorrow, unless anyone gets to it earlier.

this failure was caused by

"namei.c: let follow_link() do put_link() on failure"

and the reason was that we didn't do a proper path_put when failing
inside follow_link(). Fix that should be squashed in below. With this
xfstests 049 is still failing, I'll look into that next.


Index: linux-2.6/fs/namei.c
===================================================================
--- linux-2.6.orig/fs/namei.c 2012-06-18 12:17:08.084097978 +0200
+++ linux-2.6/fs/namei.c 2012-06-18 13:39:29.764224510 +0200
@@ -597,18 +591,19 @@ static inline void put_link(struct namei
static __always_inline int
follow_link(struct path *link, struct nameidata *nd, void **p)
{
- int error;
struct dentry *dentry = link->dentry;
+ int error;
+ char *s;

BUG_ON(nd->flags & LOOKUP_RCU);

if (link->mnt == nd->path.mnt)
mntget(link->mnt);

- if (unlikely(current->total_link_count >= 40)) {
- path_put(&nd->path);
- return -ELOOP;
- }
+ error = -ELOOP;
+ if (unlikely(current->total_link_count >= 40))
+ goto out_put_nd_path;
+
cond_resched();
current->total_link_count++;

@@ -616,31 +611,36 @@ follow_link(struct path *link, struct na
nd_set_link(nd, NULL);

error = security_inode_follow_link(link->dentry, nd);
- if (error) {
- path_put(&nd->path);
- return error;
- }
+ if (error)
+ goto out_put_nd_path;

nd->last_type = LAST_BIND;
*p = dentry->d_inode->i_op->follow_link(dentry, nd);
error = PTR_ERR(*p);
- if (!IS_ERR(*p)) {
- char *s = nd_get_link(nd);
- error = 0;
- if (s)
- error = __vfs_follow_link(nd, s);
- else if (nd->last_type == LAST_BIND) {
- nd->flags |= LOOKUP_JUMPED;
- nd->inode = nd->path.dentry->d_inode;
- if (nd->inode->i_op->follow_link) {
- /* stepped on a _really_ weird one */
- path_put(&nd->path);
- error = -ELOOP;
- }
+ if (IS_ERR(*p))
+ goto out_put_link;
+
+ error = 0;
+ s = nd_get_link(nd);
+ if (s) {
+ error = __vfs_follow_link(nd, s);
+ } else if (nd->last_type == LAST_BIND) {
+ nd->flags |= LOOKUP_JUMPED;
+ nd->inode = nd->path.dentry->d_inode;
+ if (nd->inode->i_op->follow_link) {
+ /* stepped on a _really_ weird one */
+ path_put(&nd->path);
+ error = -ELOOP;
}
- if (unlikely(error))
- put_link(nd, link, p);
}
+ if (unlikely(error))
+ put_link(nd, link, p);
+ return error;
+
+out_put_nd_path:
+ path_put(&nd->path);
+out_put_link:
+ path_put(link);
return error;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Christoph Hellwig
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 18, 2012 03:20PM
And here is fix number two, to be folded into the same commit:


Index: linux-2.6/fs/namei.c
===================================================================
--- linux-2.6.orig/fs/namei.c 2012-06-18 15:01:47.540350941 +0200
+++ linux-2.6/fs/namei.c 2012-06-18 15:01:48.160350957 +0200
@@ -640,7 +640,8 @@ follow_link(struct path *link, struct na
}
}
if (unlikely(error))
- put_link(nd, link, p);
+ put_link(nd, link, *p);
+
return error;

out_put_nd_path:
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Miklos Szeredi
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 18, 2012 04:30PM
Here's fix against e8c30bb7 "->atomic_open() prototype change - pass int
* instead of bool *"

Rename FILE_CREATE to FILE_CREATED because it conflicts with a define in
fs/cifs/cifspdu.h

Signed-off-by: Miklos Szeredi <[email protected]>
---
fs/9p/vfs_inode.c | 2 +-
fs/9p/vfs_inode_dotl.c | 2 +-
fs/ceph/dir.c | 2 +-
fs/cifs/dir.c | 4 ++--
fs/fuse/dir.c | 2 +-
fs/namei.c | 14 +++++++-------
include/linux/fs.h | 2 +-
7 files changed, 14 insertions(+), 14 deletions(-)

Index: linux-2.6/fs/9p/vfs_inode.c
===================================================================
--- linux-2.6.orig/fs/9p/vfs_inode.c 2012-06-18 13:50:17.000000000 +0200
+++ linux-2.6/fs/9p/vfs_inode.c 2012-06-18 15:52:59.000000000 +0200
@@ -925,7 +925,7 @@ v9fs_vfs_atomic_open(struct inode *dir,
v9fs_cache_inode_set_cookie(dentry->d_inode, file);
#endif

- *opened |= FILE_CREATE;
+ *opened |= FILE_CREATED;
out:
dput(res);
return err;
Index: linux-2.6/fs/9p/vfs_inode_dotl.c
===================================================================
--- linux-2.6.orig/fs/9p/vfs_inode_dotl.c 2012-06-18 13:50:17.000000000 +0200
+++ linux-2.6/fs/9p/vfs_inode_dotl.c 2012-06-18 15:57:11.000000000 +0200
@@ -362,7 +362,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *
if (v9ses->cache)
v9fs_cache_inode_set_cookie(inode, file);
#endif
- *opened |= FILE_CREATE;
+ *opened |= FILE_CREATED;
out:
dput(res);
return err;
Index: linux-2.6/fs/ceph/dir.c
===================================================================
--- linux-2.6.orig/fs/ceph/dir.c 2012-06-18 13:50:17.000000000 +0200
+++ linux-2.6/fs/ceph/dir.c 2012-06-18 16:01:31.000000000 +0200
@@ -665,7 +665,7 @@ int ceph_atomic_open(struct inode *dir,
if (dentry->d_inode)
return finish_no_open(file, res);

- *opened |= FILE_CREATE;
+ *opened |= FILE_CREATED;
err = ceph_lookup_open(dir, dentry, file, flags, mode, opened);
dput(res);

Index: linux-2.6/fs/cifs/dir.c
===================================================================
--- linux-2.6.orig/fs/cifs/dir.c 2012-06-18 13:50:17.000000000 +0200
+++ linux-2.6/fs/cifs/dir.c 2012-06-18 16:03:39.000000000 +0200
@@ -311,7 +311,7 @@ static int cifs_do_create(struct inode *
.device = 0,
};

- *created |= FILE_CREATE;
+ *created |= FILE_CREATED;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
args.uid = (__u64) current_fsuid();
if (inode->i_mode & S_ISGID)
@@ -466,7 +466,7 @@ int cifs_create(struct inode *inode, str
struct tcon_link *tlink;
__u16 fileHandle;
__u32 oplock;
- int created = FILE_CREATE;
+ int created = FILE_CREATED;

cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p",
inode, direntry->d_name.name, direntry);
Index: linux-2.6/fs/fuse/dir.c
===================================================================
--- linux-2.6.orig/fs/fuse/dir.c 2012-06-18 13:50:17.000000000 +0200
+++ linux-2.6/fs/fuse/dir.c 2012-06-18 16:04:46.000000000 +0200
@@ -490,7 +490,7 @@ static int fuse_atomic_open(struct inode
goto no_open;

/* Only creates */
- *opened |= FILE_CREATE;
+ *opened |= FILE_CREATED;

if (fc->no_create)
goto mknod;
Index: linux-2.6/fs/namei.c
===================================================================
--- linux-2.6.orig/fs/namei.c 2012-06-18 15:43:07.000000000 +0200
+++ linux-2.6/fs/namei.c 2012-06-18 16:05:27.000000000 +0200
@@ -2244,7 +2244,7 @@ static int atomic_open(struct nameidata

if (open_flag & O_EXCL) {
open_flag &= ~O_TRUNC;
- *opened |= FILE_CREATE;
+ *opened |= FILE_CREATED;
}

/*
@@ -2302,7 +2302,7 @@ static int atomic_open(struct nameidata
}

acc_mode = op->acc_mode;
- if (*opened & FILE_CREATE) {
+ if (*opened & FILE_CREATED) {
fsnotify_create(dir, dentry);
acc_mode = MAY_OPEN;
}
@@ -2374,7 +2374,7 @@ static int atomic_open(struct nameidata
*
* An error code is returned otherwise.
*
- * FILE_CREATE will be set in @*opened if the dentry was created and will be
+ * FILE_CREATED will be set in @*opened if the dentry was created and will be
* cleared otherwise prior to returning.
*/
static int lookup_open(struct nameidata *nd, struct path *path,
@@ -2388,7 +2388,7 @@ static int lookup_open(struct nameidata
int error;
bool need_lookup;

- *opened &= ~FILE_CREATE;
+ *opened &= ~FILE_CREATED;
dentry = lookup_dcache(&nd->last, dir, nd->flags, &need_lookup);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
@@ -2426,7 +2426,7 @@ static int lookup_open(struct nameidata
if (error)
goto out_dput;
*want_write = true;
- *opened |= FILE_CREATE;
+ *opened |= FILE_CREATED;
error = security_path_mknod(&nd->path, dentry, mode, 0);
if (error)
goto out_dput;
@@ -2532,7 +2532,7 @@ static int do_last(struct nameidata *nd,
if (error)
goto out;

- if ((*opened & FILE_CREATE) ||
+ if ((*opened & FILE_CREATED) ||
!S_ISREG(file->f_path.dentry->d_inode->i_mode))
will_truncate = false;

@@ -2540,7 +2540,7 @@ static int do_last(struct nameidata *nd,
goto opened;
}

- if (*opened & FILE_CREATE) {
+ if (*opened & FILE_CREATED) {
/* Don't check for write permission, don't truncate */
open_flag &= ~O_TRUNC;
will_truncate = false;
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h 2012-06-18 13:50:17.000000000 +0200
+++ linux-2.6/include/linux/fs.h 2012-06-18 16:05:37.000000000 +0200
@@ -2065,7 +2065,7 @@ extern struct file * dentry_open(struct
extern int filp_close(struct file *, fl_owner_t id);
extern char * getname(const char __user *);
enum {
- FILE_CREATE = 1,
+ FILE_CREATED = 1,
FILE_OPENED = 2
};
extern int finish_open(struct file *file, struct dentry *dentry,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 22, 2012 11:00AM
On Mon, Jun 18, 2012 at 04:27:41PM +0200, Miklos Szeredi wrote:
> Here's fix against e8c30bb7 "->atomic_open() prototype change - pass int
> * instead of bool *"
>
> Rename FILE_CREATE to FILE_CREATED because it conflicts with a define in
> fs/cifs/cifspdu.h

.... and that leads to actual breakage in e.g. cifs_do_create(), since the macro
from cifspdu.h wins and we end up setting the wrong bit there. Folded.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Al Viro
Re: [PATCH 00/21] vfs: atomic open v6 (part 2)
June 22, 2012 12:10PM
On Mon, Jun 18, 2012 at 09:12:52AM -0400, Christoph Hellwig wrote:
> And here is fix number two, to be folded into the same commit:

Both folded. FWIW, I'm not sure I'm happy about the reorg of failure
exits in follow_link() - gcc can't figure out that follow_link(..., &cookie)
can't return 0 without having passed through the assignment to cookie.
Hell knows; I still don't like the calling conventions in that one...
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Sorry, only registered users may post in this forum.

Click here to login