Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-22 Thread Daniel Axtens
>> From: Miklos Szeredi 
>> 
>> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
>> f_path always point to the overlay and f_inode to the underlay").
>> 
>> Regular files opened on overlayfs will result in the file being opened on
>> the underlying filesystem, while f_path points to the overlayfs
>> mount/dentry.
>> 
>> This confuses filesystems which get the dentry from struct file and assume
>> it's theirs.
>> 
>> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
>> from the file.  This simply compares file_inode(file->f_path.dentry) to
>> file_inode(file) and if they are equal returns file->f_path.dentry (this is
>> the common, non-overlayfs case).
>> 
>> In the uncommon case (regular file on overlayfs) it will call into
>> overlayfs's ->d_native_dentry() to get the underlying dentry matching
>> file_inode(file).
>> 
>> [*] If possible, it's better simply to use file_inode() instead.

Hopefully this is not so late as to be useless!
For this entire series:
Tested-by: Daniel Axtens 

Regards,
Daniel

>> 
>> Signed-off-by: Miklos Szeredi 
>> Tested-by: Goldwyn Rodrigues 
>> Reviewed-by: Trond Myklebust 
>> Cc:  # v4.2
>> Cc: David Howells 
>> Cc: Al Viro 
>> Cc: Theodore Ts'o 
>> Cc: Daniel Axtens 
>> ---
>>  fs/open.c  | 11 +++
>>  fs/overlayfs/super.c   | 16 
>>  include/linux/dcache.h |  1 +
>>  include/linux/fs.h |  2 ++
>>  4 files changed, 30 insertions(+)
>
> I have this patch in the ext4.git tree, but I'd like to get an
> Acked-by from Al before I send a pull request to Linus.
>
> Al?  Any objections to my sending in this change via the ext4 tree?
>
>   - Ted
>
>> 
>> diff --git a/fs/open.c b/fs/open.c
>> index 55bdc75e2172..6326c11eda78 100644
>> --- a/fs/open.c
>> +++ b/fs/open.c
>> @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char *buf, int 
>> buflen)
>>  }
>>  EXPORT_SYMBOL(file_path);
>>  
>> +struct dentry *file_dentry(const struct file *file)
>> +{
>> +struct dentry *dentry = file->f_path.dentry;
>> +
>> +if (likely(d_inode(dentry) == file_inode(file)))
>> +return dentry;
>> +else
>> +return dentry->d_op->d_native_dentry(dentry, file_inode(file));
>> +}
>> +EXPORT_SYMBOL(file_dentry);
>> +
>>  /**
>>   * vfs_open - open the file at the given path
>>   * @path: path to open
>> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
>> index 619ad4b016d2..5142aa2034c4 100644
>> --- a/fs/overlayfs/super.c
>> +++ b/fs/overlayfs/super.c
>> @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(struct dentry 
>> *dentry, unsigned int flags)
>>  return ret;
>>  }
>>  
>> +static struct dentry *ovl_d_native_dentry(struct dentry *dentry,
>> + struct inode *inode)
>> +{
>> +struct ovl_entry *oe = dentry->d_fsdata;
>> +struct dentry *realentry = ovl_upperdentry_dereference(oe);
>> +
>> +if (realentry && inode == d_inode(realentry))
>> +return realentry;
>> +realentry = __ovl_dentry_lower(oe);
>> +if (realentry && inode == d_inode(realentry))
>> +return realentry;
>> +BUG();
>> +}
>> +
>>  static const struct dentry_operations ovl_dentry_operations = {
>>  .d_release = ovl_dentry_release,
>>  .d_select_inode = ovl_d_select_inode,
>> +.d_native_dentry = ovl_d_native_dentry,
>>  };
>>  
>>  static const struct dentry_operations ovl_reval_dentry_operations = {
>>  .d_release = ovl_dentry_release,
>>  .d_select_inode = ovl_d_select_inode,
>> +.d_native_dentry = ovl_d_native_dentry,
>>  .d_revalidate = ovl_dentry_revalidate,
>>  .d_weak_revalidate = ovl_dentry_weak_revalidate,
>>  };
>> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
>> index c4b5f4b3f8f8..99ecb6de636c 100644
>> --- a/include/linux/dcache.h
>> +++ b/include/linux/dcache.h
>> @@ -161,6 +161,7 @@ struct dentry_operations {
>>  struct vfsmount *(*d_automount)(struct path *);
>>  int (*d_manage)(struct dentry *, bool);
>>  struct inode *(*d_select_inode)(struct dentry *, unsigned);
>> +struct dentry *(*d_native_dentry)(struct dentry *, struct inode *);
>>  } cacheline_aligned;
>>  
>>  /*
>> diff --git a/include/linux/fs.h b/include/linux/fs.h
>> index ae681002100a..1091d9f43271 100644
>> --- a/include/linux/fs.h
>> +++ b/include/linux/fs.h
>> @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(const struct 
>> file *f)
>>  return f->f_inode;
>>  }
>>  
>> +extern struct dentry *file_dentry(const struct file *file);
>> +
>>  static inline int locks_lock_file_wait(struct file *filp, struct file_lock 
>> *fl)
>>  {
>>  return locks_lock_inode_wait(file_inode(filp), fl);
>> -- 
>> 2.1.4

Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-22 Thread Daniel Axtens
>> From: Miklos Szeredi 
>> 
>> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
>> f_path always point to the overlay and f_inode to the underlay").
>> 
>> Regular files opened on overlayfs will result in the file being opened on
>> the underlying filesystem, while f_path points to the overlayfs
>> mount/dentry.
>> 
>> This confuses filesystems which get the dentry from struct file and assume
>> it's theirs.
>> 
>> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
>> from the file.  This simply compares file_inode(file->f_path.dentry) to
>> file_inode(file) and if they are equal returns file->f_path.dentry (this is
>> the common, non-overlayfs case).
>> 
>> In the uncommon case (regular file on overlayfs) it will call into
>> overlayfs's ->d_native_dentry() to get the underlying dentry matching
>> file_inode(file).
>> 
>> [*] If possible, it's better simply to use file_inode() instead.

Hopefully this is not so late as to be useless!
For this entire series:
Tested-by: Daniel Axtens 

Regards,
Daniel

>> 
>> Signed-off-by: Miklos Szeredi 
>> Tested-by: Goldwyn Rodrigues 
>> Reviewed-by: Trond Myklebust 
>> Cc:  # v4.2
>> Cc: David Howells 
>> Cc: Al Viro 
>> Cc: Theodore Ts'o 
>> Cc: Daniel Axtens 
>> ---
>>  fs/open.c  | 11 +++
>>  fs/overlayfs/super.c   | 16 
>>  include/linux/dcache.h |  1 +
>>  include/linux/fs.h |  2 ++
>>  4 files changed, 30 insertions(+)
>
> I have this patch in the ext4.git tree, but I'd like to get an
> Acked-by from Al before I send a pull request to Linus.
>
> Al?  Any objections to my sending in this change via the ext4 tree?
>
>   - Ted
>
>> 
>> diff --git a/fs/open.c b/fs/open.c
>> index 55bdc75e2172..6326c11eda78 100644
>> --- a/fs/open.c
>> +++ b/fs/open.c
>> @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char *buf, int 
>> buflen)
>>  }
>>  EXPORT_SYMBOL(file_path);
>>  
>> +struct dentry *file_dentry(const struct file *file)
>> +{
>> +struct dentry *dentry = file->f_path.dentry;
>> +
>> +if (likely(d_inode(dentry) == file_inode(file)))
>> +return dentry;
>> +else
>> +return dentry->d_op->d_native_dentry(dentry, file_inode(file));
>> +}
>> +EXPORT_SYMBOL(file_dentry);
>> +
>>  /**
>>   * vfs_open - open the file at the given path
>>   * @path: path to open
>> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
>> index 619ad4b016d2..5142aa2034c4 100644
>> --- a/fs/overlayfs/super.c
>> +++ b/fs/overlayfs/super.c
>> @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(struct dentry 
>> *dentry, unsigned int flags)
>>  return ret;
>>  }
>>  
>> +static struct dentry *ovl_d_native_dentry(struct dentry *dentry,
>> + struct inode *inode)
>> +{
>> +struct ovl_entry *oe = dentry->d_fsdata;
>> +struct dentry *realentry = ovl_upperdentry_dereference(oe);
>> +
>> +if (realentry && inode == d_inode(realentry))
>> +return realentry;
>> +realentry = __ovl_dentry_lower(oe);
>> +if (realentry && inode == d_inode(realentry))
>> +return realentry;
>> +BUG();
>> +}
>> +
>>  static const struct dentry_operations ovl_dentry_operations = {
>>  .d_release = ovl_dentry_release,
>>  .d_select_inode = ovl_d_select_inode,
>> +.d_native_dentry = ovl_d_native_dentry,
>>  };
>>  
>>  static const struct dentry_operations ovl_reval_dentry_operations = {
>>  .d_release = ovl_dentry_release,
>>  .d_select_inode = ovl_d_select_inode,
>> +.d_native_dentry = ovl_d_native_dentry,
>>  .d_revalidate = ovl_dentry_revalidate,
>>  .d_weak_revalidate = ovl_dentry_weak_revalidate,
>>  };
>> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
>> index c4b5f4b3f8f8..99ecb6de636c 100644
>> --- a/include/linux/dcache.h
>> +++ b/include/linux/dcache.h
>> @@ -161,6 +161,7 @@ struct dentry_operations {
>>  struct vfsmount *(*d_automount)(struct path *);
>>  int (*d_manage)(struct dentry *, bool);
>>  struct inode *(*d_select_inode)(struct dentry *, unsigned);
>> +struct dentry *(*d_native_dentry)(struct dentry *, struct inode *);
>>  } cacheline_aligned;
>>  
>>  /*
>> diff --git a/include/linux/fs.h b/include/linux/fs.h
>> index ae681002100a..1091d9f43271 100644
>> --- a/include/linux/fs.h
>> +++ b/include/linux/fs.h
>> @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(const struct 
>> file *f)
>>  return f->f_inode;
>>  }
>>  
>> +extern struct dentry *file_dentry(const struct file *file);
>> +
>>  static inline int locks_lock_file_wait(struct file *filp, struct file_lock 
>> *fl)
>>  {
>>  return locks_lock_inode_wait(file_inode(filp), fl);
>> -- 
>> 2.1.4
>> 


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-21 Thread Miklos Szeredi
On Mon, Mar 21, 2016 at 6:28 AM, Al Viro  wrote:
> On Thu, Mar 17, 2016 at 10:02:00AM +0100, Miklos Szeredi wrote:
>> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
>> from the file.  This simply compares file_inode(file->f_path.dentry) to
>> file_inode(file) and if they are equal returns file->f_path.dentry (this is
>> the common, non-overlayfs case).
>>
>> In the uncommon case (regular file on overlayfs) it will call into
>> overlayfs's ->d_native_dentry() to get the underlying dentry matching
>> file_inode(file).
>
> What's wrong with making ovl_dentry_real() an instance of optional
> ->d_real() method and having a flag (DCACHE_OP_REAL) controlling its
> calls?  With d_real(dentry) returning either that or dentry itself,
> and file_dentry(file) being simply d_real(file->f_path.dentry)...
>
> Why do we need to look at the inode at all?  d_set_d_op() dereferences
> ->d_op anyway, as well as setting ->d_flags, so there's no extra cost
> there, and "test bit in ->d_flags + branch not taken" is all it would
> cost in normal case...

Checking DCACHE_OP_REAL insted of inode would be fine.

But d_real() needs inode as well.  Consider the case where

 1) file opened on lower layer
 2) copied up
 3) file_dentry() called

d_real(file->f_path.dentry) would return the upper dentry but that's
not what we want.

Thanks,
Miklos


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-21 Thread Miklos Szeredi
On Mon, Mar 21, 2016 at 6:28 AM, Al Viro  wrote:
> On Thu, Mar 17, 2016 at 10:02:00AM +0100, Miklos Szeredi wrote:
>> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
>> from the file.  This simply compares file_inode(file->f_path.dentry) to
>> file_inode(file) and if they are equal returns file->f_path.dentry (this is
>> the common, non-overlayfs case).
>>
>> In the uncommon case (regular file on overlayfs) it will call into
>> overlayfs's ->d_native_dentry() to get the underlying dentry matching
>> file_inode(file).
>
> What's wrong with making ovl_dentry_real() an instance of optional
> ->d_real() method and having a flag (DCACHE_OP_REAL) controlling its
> calls?  With d_real(dentry) returning either that or dentry itself,
> and file_dentry(file) being simply d_real(file->f_path.dentry)...
>
> Why do we need to look at the inode at all?  d_set_d_op() dereferences
> ->d_op anyway, as well as setting ->d_flags, so there's no extra cost
> there, and "test bit in ->d_flags + branch not taken" is all it would
> cost in normal case...

Checking DCACHE_OP_REAL insted of inode would be fine.

But d_real() needs inode as well.  Consider the case where

 1) file opened on lower layer
 2) copied up
 3) file_dentry() called

d_real(file->f_path.dentry) would return the upper dentry but that's
not what we want.

Thanks,
Miklos


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-20 Thread Al Viro
On Thu, Mar 17, 2016 at 10:02:00AM +0100, Miklos Szeredi wrote:
> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
> from the file.  This simply compares file_inode(file->f_path.dentry) to
> file_inode(file) and if they are equal returns file->f_path.dentry (this is
> the common, non-overlayfs case).
> 
> In the uncommon case (regular file on overlayfs) it will call into
> overlayfs's ->d_native_dentry() to get the underlying dentry matching
> file_inode(file).

What's wrong with making ovl_dentry_real() an instance of optional
->d_real() method and having a flag (DCACHE_OP_REAL) controlling its
calls?  With d_real(dentry) returning either that or dentry itself,
and file_dentry(file) being simply d_real(file->f_path.dentry)...

Why do we need to look at the inode at all?  d_set_d_op() dereferences
->d_op anyway, as well as setting ->d_flags, so there's no extra cost
there, and "test bit in ->d_flags + branch not taken" is all it would
cost in normal case...


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-20 Thread Al Viro
On Thu, Mar 17, 2016 at 10:02:00AM +0100, Miklos Szeredi wrote:
> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
> from the file.  This simply compares file_inode(file->f_path.dentry) to
> file_inode(file) and if they are equal returns file->f_path.dentry (this is
> the common, non-overlayfs case).
> 
> In the uncommon case (regular file on overlayfs) it will call into
> overlayfs's ->d_native_dentry() to get the underlying dentry matching
> file_inode(file).

What's wrong with making ovl_dentry_real() an instance of optional
->d_real() method and having a flag (DCACHE_OP_REAL) controlling its
calls?  With d_real(dentry) returning either that or dentry itself,
and file_dentry(file) being simply d_real(file->f_path.dentry)...

Why do we need to look at the inode at all?  d_set_d_op() dereferences
->d_op anyway, as well as setting ->d_flags, so there's no extra cost
there, and "test bit in ->d_flags + branch not taken" is all it would
cost in normal case...


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-20 Thread Al Viro
On Mon, Mar 21, 2016 at 01:02:15AM -0400, Theodore Ts'o wrote:

> I have this patch in the ext4.git tree, but I'd like to get an
> Acked-by from Al before I send a pull request to Linus.
> 
> Al?  Any objections to my sending in this change via the ext4 tree?
>   - Ted

FWIW, I would rather add DCACHE_OP_REAL (set at d_set_d_op()
time) and turned that into

static inline struct dentry *d_real(const struct dentry *dentry)
{
if (unlikely(dentry->d_flags & DCACHE_OP_NATIVE_DENTRY))
returd dentry->d_op->d_real(dentry);
else
return dentry;
}
static inline struct dentry *file_dentry(const struct file *file)
{
return d_real(file->f_path.dentry);
}

and used ovl_dentry_real as ->d_real for overlayfs.  Miklos, do you
see any problems with that variant?


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-20 Thread Al Viro
On Mon, Mar 21, 2016 at 01:02:15AM -0400, Theodore Ts'o wrote:

> I have this patch in the ext4.git tree, but I'd like to get an
> Acked-by from Al before I send a pull request to Linus.
> 
> Al?  Any objections to my sending in this change via the ext4 tree?
>   - Ted

FWIW, I would rather add DCACHE_OP_REAL (set at d_set_d_op()
time) and turned that into

static inline struct dentry *d_real(const struct dentry *dentry)
{
if (unlikely(dentry->d_flags & DCACHE_OP_NATIVE_DENTRY))
returd dentry->d_op->d_real(dentry);
else
return dentry;
}
static inline struct dentry *file_dentry(const struct file *file)
{
return d_real(file->f_path.dentry);
}

and used ovl_dentry_real as ->d_real for overlayfs.  Miklos, do you
see any problems with that variant?


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-20 Thread Theodore Ts'o
On Thu, Mar 17, 2016 at 10:02:00AM +0100, Miklos Szeredi wrote:
> From: Miklos Szeredi 
> 
> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
> f_path always point to the overlay and f_inode to the underlay").
> 
> Regular files opened on overlayfs will result in the file being opened on
> the underlying filesystem, while f_path points to the overlayfs
> mount/dentry.
> 
> This confuses filesystems which get the dentry from struct file and assume
> it's theirs.
> 
> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
> from the file.  This simply compares file_inode(file->f_path.dentry) to
> file_inode(file) and if they are equal returns file->f_path.dentry (this is
> the common, non-overlayfs case).
> 
> In the uncommon case (regular file on overlayfs) it will call into
> overlayfs's ->d_native_dentry() to get the underlying dentry matching
> file_inode(file).
> 
> [*] If possible, it's better simply to use file_inode() instead.
> 
> Signed-off-by: Miklos Szeredi 
> Tested-by: Goldwyn Rodrigues 
> Reviewed-by: Trond Myklebust 
> Cc:  # v4.2
> Cc: David Howells 
> Cc: Al Viro 
> Cc: Theodore Ts'o 
> Cc: Daniel Axtens 
> ---
>  fs/open.c  | 11 +++
>  fs/overlayfs/super.c   | 16 
>  include/linux/dcache.h |  1 +
>  include/linux/fs.h |  2 ++
>  4 files changed, 30 insertions(+)

I have this patch in the ext4.git tree, but I'd like to get an
Acked-by from Al before I send a pull request to Linus.

Al?  Any objections to my sending in this change via the ext4 tree?

- Ted

> 
> diff --git a/fs/open.c b/fs/open.c
> index 55bdc75e2172..6326c11eda78 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char *buf, int buflen)
>  }
>  EXPORT_SYMBOL(file_path);
>  
> +struct dentry *file_dentry(const struct file *file)
> +{
> + struct dentry *dentry = file->f_path.dentry;
> +
> + if (likely(d_inode(dentry) == file_inode(file)))
> + return dentry;
> + else
> + return dentry->d_op->d_native_dentry(dentry, file_inode(file));
> +}
> +EXPORT_SYMBOL(file_dentry);
> +
>  /**
>   * vfs_open - open the file at the given path
>   * @path: path to open
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 619ad4b016d2..5142aa2034c4 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(struct dentry 
> *dentry, unsigned int flags)
>   return ret;
>  }
>  
> +static struct dentry *ovl_d_native_dentry(struct dentry *dentry,
> +  struct inode *inode)
> +{
> + struct ovl_entry *oe = dentry->d_fsdata;
> + struct dentry *realentry = ovl_upperdentry_dereference(oe);
> +
> + if (realentry && inode == d_inode(realentry))
> + return realentry;
> + realentry = __ovl_dentry_lower(oe);
> + if (realentry && inode == d_inode(realentry))
> + return realentry;
> + BUG();
> +}
> +
>  static const struct dentry_operations ovl_dentry_operations = {
>   .d_release = ovl_dentry_release,
>   .d_select_inode = ovl_d_select_inode,
> + .d_native_dentry = ovl_d_native_dentry,
>  };
>  
>  static const struct dentry_operations ovl_reval_dentry_operations = {
>   .d_release = ovl_dentry_release,
>   .d_select_inode = ovl_d_select_inode,
> + .d_native_dentry = ovl_d_native_dentry,
>   .d_revalidate = ovl_dentry_revalidate,
>   .d_weak_revalidate = ovl_dentry_weak_revalidate,
>  };
> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
> index c4b5f4b3f8f8..99ecb6de636c 100644
> --- a/include/linux/dcache.h
> +++ b/include/linux/dcache.h
> @@ -161,6 +161,7 @@ struct dentry_operations {
>   struct vfsmount *(*d_automount)(struct path *);
>   int (*d_manage)(struct dentry *, bool);
>   struct inode *(*d_select_inode)(struct dentry *, unsigned);
> + struct dentry *(*d_native_dentry)(struct dentry *, struct inode *);
>  } cacheline_aligned;
>  
>  /*
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index ae681002100a..1091d9f43271 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(const struct 
> file *f)
>   return f->f_inode;
>  }
>  
> +extern struct dentry *file_dentry(const struct file *file);
> +
>  static inline int locks_lock_file_wait(struct file *filp, struct file_lock 
> *fl)
>  {
>   return locks_lock_inode_wait(file_inode(filp), fl);
> -- 
> 2.1.4
> 


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-20 Thread Theodore Ts'o
On Thu, Mar 17, 2016 at 10:02:00AM +0100, Miklos Szeredi wrote:
> From: Miklos Szeredi 
> 
> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
> f_path always point to the overlay and f_inode to the underlay").
> 
> Regular files opened on overlayfs will result in the file being opened on
> the underlying filesystem, while f_path points to the overlayfs
> mount/dentry.
> 
> This confuses filesystems which get the dentry from struct file and assume
> it's theirs.
> 
> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
> from the file.  This simply compares file_inode(file->f_path.dentry) to
> file_inode(file) and if they are equal returns file->f_path.dentry (this is
> the common, non-overlayfs case).
> 
> In the uncommon case (regular file on overlayfs) it will call into
> overlayfs's ->d_native_dentry() to get the underlying dentry matching
> file_inode(file).
> 
> [*] If possible, it's better simply to use file_inode() instead.
> 
> Signed-off-by: Miklos Szeredi 
> Tested-by: Goldwyn Rodrigues 
> Reviewed-by: Trond Myklebust 
> Cc:  # v4.2
> Cc: David Howells 
> Cc: Al Viro 
> Cc: Theodore Ts'o 
> Cc: Daniel Axtens 
> ---
>  fs/open.c  | 11 +++
>  fs/overlayfs/super.c   | 16 
>  include/linux/dcache.h |  1 +
>  include/linux/fs.h |  2 ++
>  4 files changed, 30 insertions(+)

I have this patch in the ext4.git tree, but I'd like to get an
Acked-by from Al before I send a pull request to Linus.

Al?  Any objections to my sending in this change via the ext4 tree?

- Ted

> 
> diff --git a/fs/open.c b/fs/open.c
> index 55bdc75e2172..6326c11eda78 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char *buf, int buflen)
>  }
>  EXPORT_SYMBOL(file_path);
>  
> +struct dentry *file_dentry(const struct file *file)
> +{
> + struct dentry *dentry = file->f_path.dentry;
> +
> + if (likely(d_inode(dentry) == file_inode(file)))
> + return dentry;
> + else
> + return dentry->d_op->d_native_dentry(dentry, file_inode(file));
> +}
> +EXPORT_SYMBOL(file_dentry);
> +
>  /**
>   * vfs_open - open the file at the given path
>   * @path: path to open
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 619ad4b016d2..5142aa2034c4 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(struct dentry 
> *dentry, unsigned int flags)
>   return ret;
>  }
>  
> +static struct dentry *ovl_d_native_dentry(struct dentry *dentry,
> +  struct inode *inode)
> +{
> + struct ovl_entry *oe = dentry->d_fsdata;
> + struct dentry *realentry = ovl_upperdentry_dereference(oe);
> +
> + if (realentry && inode == d_inode(realentry))
> + return realentry;
> + realentry = __ovl_dentry_lower(oe);
> + if (realentry && inode == d_inode(realentry))
> + return realentry;
> + BUG();
> +}
> +
>  static const struct dentry_operations ovl_dentry_operations = {
>   .d_release = ovl_dentry_release,
>   .d_select_inode = ovl_d_select_inode,
> + .d_native_dentry = ovl_d_native_dentry,
>  };
>  
>  static const struct dentry_operations ovl_reval_dentry_operations = {
>   .d_release = ovl_dentry_release,
>   .d_select_inode = ovl_d_select_inode,
> + .d_native_dentry = ovl_d_native_dentry,
>   .d_revalidate = ovl_dentry_revalidate,
>   .d_weak_revalidate = ovl_dentry_weak_revalidate,
>  };
> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
> index c4b5f4b3f8f8..99ecb6de636c 100644
> --- a/include/linux/dcache.h
> +++ b/include/linux/dcache.h
> @@ -161,6 +161,7 @@ struct dentry_operations {
>   struct vfsmount *(*d_automount)(struct path *);
>   int (*d_manage)(struct dentry *, bool);
>   struct inode *(*d_select_inode)(struct dentry *, unsigned);
> + struct dentry *(*d_native_dentry)(struct dentry *, struct inode *);
>  } cacheline_aligned;
>  
>  /*
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index ae681002100a..1091d9f43271 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(const struct 
> file *f)
>   return f->f_inode;
>  }
>  
> +extern struct dentry *file_dentry(const struct file *file);
> +
>  static inline int locks_lock_file_wait(struct file *filp, struct file_lock 
> *fl)
>  {
>   return locks_lock_inode_wait(file_inode(filp), fl);
> -- 
> 2.1.4
> 


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Theodore Ts'o
On Thu, Mar 17, 2016 at 11:15:26AM +0100, Sedat Dilek wrote:
> 
> Is that correct the ext4-related patches 3/4 and 4/4 are Linux-v4.5 material?
> Not applicable fpr v4.4.y-stable?

4.5 has already been released, but I think these patches are suitable
for the v4.[345].y-stable branch (which I think is the question you
are really asking).

Al, are you willing to push all of these to Linus before the merge
window closes, with a cc to sta...@vger.kernel.org?  Or I can push
them to linus via the ext4.git tree if I get signoffs/acked-by's from
the VFS and NFS maintainers.

I'll want to do a full a regression test cycle since we're pushing
patches created after the merge window opened, but I consider these
bug fixes and will certainly support pushing them to Linus as far as
ext4 is concerned.

Cheers,

- Ted


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Theodore Ts'o
On Thu, Mar 17, 2016 at 11:15:26AM +0100, Sedat Dilek wrote:
> 
> Is that correct the ext4-related patches 3/4 and 4/4 are Linux-v4.5 material?
> Not applicable fpr v4.4.y-stable?

4.5 has already been released, but I think these patches are suitable
for the v4.[345].y-stable branch (which I think is the question you
are really asking).

Al, are you willing to push all of these to Linus before the merge
window closes, with a cc to sta...@vger.kernel.org?  Or I can push
them to linus via the ext4.git tree if I get signoffs/acked-by's from
the VFS and NFS maintainers.

I'll want to do a full a regression test cycle since we're pushing
patches created after the merge window opened, but I consider these
bug fixes and will certainly support pushing them to Linus as far as
ext4 is concerned.

Cheers,

- Ted


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Sedat Dilek
On Thu, Mar 17, 2016 at 10:33 AM, Miklos Szeredi  wrote:
> On Thu, Mar 17, 2016 at 10:09 AM, Sedat Dilek  wrote:
>> On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
>>> From: Miklos Szeredi 
>>>
>>> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
>>> f_path always point to the overlay and f_inode to the underlay").
>>>
>>
>> Can you put that series in your vfs.git tree?
>> Easier for getting and testing.
>
> Ok, pushed to:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git file_dentry
>

Is that correct the ext4-related patches 3/4 and 4/4 are Linux-v4.5 material?
Not applicable fpr v4.4.y-stable?

- Sedat -


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Sedat Dilek
On Thu, Mar 17, 2016 at 10:33 AM, Miklos Szeredi  wrote:
> On Thu, Mar 17, 2016 at 10:09 AM, Sedat Dilek  wrote:
>> On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
>>> From: Miklos Szeredi 
>>>
>>> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
>>> f_path always point to the overlay and f_inode to the underlay").
>>>
>>
>> Can you put that series in your vfs.git tree?
>> Easier for getting and testing.
>
> Ok, pushed to:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git file_dentry
>

Is that correct the ext4-related patches 3/4 and 4/4 are Linux-v4.5 material?
Not applicable fpr v4.4.y-stable?

- Sedat -


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Miklos Szeredi
On Thu, Mar 17, 2016 at 10:09 AM, Sedat Dilek  wrote:
> On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
>> From: Miklos Szeredi 
>>
>> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
>> f_path always point to the overlay and f_inode to the underlay").
>>
>
> Can you put that series in your vfs.git tree?
> Easier for getting and testing.

Ok, pushed to:

  git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git file_dentry

Thanks,
Miklos


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Miklos Szeredi
On Thu, Mar 17, 2016 at 10:09 AM, Sedat Dilek  wrote:
> On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
>> From: Miklos Szeredi 
>>
>> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
>> f_path always point to the overlay and f_inode to the underlay").
>>
>
> Can you put that series in your vfs.git tree?
> Easier for getting and testing.

Ok, pushed to:

  git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git file_dentry

Thanks,
Miklos


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Sedat Dilek
On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
> From: Miklos Szeredi 
>
> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
> f_path always point to the overlay and f_inode to the underlay").
>

Can you put that series in your vfs.git tree?
Easier for getting and testing.

Thanks.

- Sedat -

> Regular files opened on overlayfs will result in the file being opened on
> the underlying filesystem, while f_path points to the overlayfs
> mount/dentry.
>
> This confuses filesystems which get the dentry from struct file and assume
> it's theirs.
>
> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
> from the file.  This simply compares file_inode(file->f_path.dentry) to
> file_inode(file) and if they are equal returns file->f_path.dentry (this is
> the common, non-overlayfs case).
>
> In the uncommon case (regular file on overlayfs) it will call into
> overlayfs's ->d_native_dentry() to get the underlying dentry matching
> file_inode(file).
>
> [*] If possible, it's better simply to use file_inode() instead.
>
> Signed-off-by: Miklos Szeredi 
> Tested-by: Goldwyn Rodrigues 
> Reviewed-by: Trond Myklebust 
> Cc:  # v4.2
> Cc: David Howells 
> Cc: Al Viro 
> Cc: Theodore Ts'o 
> Cc: Daniel Axtens 
> ---
>  fs/open.c  | 11 +++
>  fs/overlayfs/super.c   | 16 
>  include/linux/dcache.h |  1 +
>  include/linux/fs.h |  2 ++
>  4 files changed, 30 insertions(+)
>
> diff --git a/fs/open.c b/fs/open.c
> index 55bdc75e2172..6326c11eda78 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char *buf, int buflen)
>  }
>  EXPORT_SYMBOL(file_path);
>
> +struct dentry *file_dentry(const struct file *file)
> +{
> +   struct dentry *dentry = file->f_path.dentry;
> +
> +   if (likely(d_inode(dentry) == file_inode(file)))
> +   return dentry;
> +   else
> +   return dentry->d_op->d_native_dentry(dentry, 
> file_inode(file));
> +}
> +EXPORT_SYMBOL(file_dentry);
> +
>  /**
>   * vfs_open - open the file at the given path
>   * @path: path to open
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 619ad4b016d2..5142aa2034c4 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(struct dentry 
> *dentry, unsigned int flags)
> return ret;
>  }
>
> +static struct dentry *ovl_d_native_dentry(struct dentry *dentry,
> +struct inode *inode)
> +{
> +   struct ovl_entry *oe = dentry->d_fsdata;
> +   struct dentry *realentry = ovl_upperdentry_dereference(oe);
> +
> +   if (realentry && inode == d_inode(realentry))
> +   return realentry;
> +   realentry = __ovl_dentry_lower(oe);
> +   if (realentry && inode == d_inode(realentry))
> +   return realentry;
> +   BUG();
> +}
> +
>  static const struct dentry_operations ovl_dentry_operations = {
> .d_release = ovl_dentry_release,
> .d_select_inode = ovl_d_select_inode,
> +   .d_native_dentry = ovl_d_native_dentry,
>  };
>
>  static const struct dentry_operations ovl_reval_dentry_operations = {
> .d_release = ovl_dentry_release,
> .d_select_inode = ovl_d_select_inode,
> +   .d_native_dentry = ovl_d_native_dentry,
> .d_revalidate = ovl_dentry_revalidate,
> .d_weak_revalidate = ovl_dentry_weak_revalidate,
>  };
> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
> index c4b5f4b3f8f8..99ecb6de636c 100644
> --- a/include/linux/dcache.h
> +++ b/include/linux/dcache.h
> @@ -161,6 +161,7 @@ struct dentry_operations {
> struct vfsmount *(*d_automount)(struct path *);
> int (*d_manage)(struct dentry *, bool);
> struct inode *(*d_select_inode)(struct dentry *, unsigned);
> +   struct dentry *(*d_native_dentry)(struct dentry *, struct inode *);
>  } cacheline_aligned;
>
>  /*
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index ae681002100a..1091d9f43271 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(const struct 
> file *f)
> return f->f_inode;
>  }
>
> +extern struct dentry *file_dentry(const struct file *file);
> +
>  static inline int locks_lock_file_wait(struct file *filp, struct file_lock 
> *fl)
>  {
> return locks_lock_inode_wait(file_inode(filp), fl);
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-19 Thread Sedat Dilek
On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
> From: Miklos Szeredi 
>
> This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: Make
> f_path always point to the overlay and f_inode to the underlay").
>

Can you put that series in your vfs.git tree?
Easier for getting and testing.

Thanks.

- Sedat -

> Regular files opened on overlayfs will result in the file being opened on
> the underlying filesystem, while f_path points to the overlayfs
> mount/dentry.
>
> This confuses filesystems which get the dentry from struct file and assume
> it's theirs.
>
> Add a new helper, file_dentry() [*], to get the filesystem's own dentry
> from the file.  This simply compares file_inode(file->f_path.dentry) to
> file_inode(file) and if they are equal returns file->f_path.dentry (this is
> the common, non-overlayfs case).
>
> In the uncommon case (regular file on overlayfs) it will call into
> overlayfs's ->d_native_dentry() to get the underlying dentry matching
> file_inode(file).
>
> [*] If possible, it's better simply to use file_inode() instead.
>
> Signed-off-by: Miklos Szeredi 
> Tested-by: Goldwyn Rodrigues 
> Reviewed-by: Trond Myklebust 
> Cc:  # v4.2
> Cc: David Howells 
> Cc: Al Viro 
> Cc: Theodore Ts'o 
> Cc: Daniel Axtens 
> ---
>  fs/open.c  | 11 +++
>  fs/overlayfs/super.c   | 16 
>  include/linux/dcache.h |  1 +
>  include/linux/fs.h |  2 ++
>  4 files changed, 30 insertions(+)
>
> diff --git a/fs/open.c b/fs/open.c
> index 55bdc75e2172..6326c11eda78 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char *buf, int buflen)
>  }
>  EXPORT_SYMBOL(file_path);
>
> +struct dentry *file_dentry(const struct file *file)
> +{
> +   struct dentry *dentry = file->f_path.dentry;
> +
> +   if (likely(d_inode(dentry) == file_inode(file)))
> +   return dentry;
> +   else
> +   return dentry->d_op->d_native_dentry(dentry, 
> file_inode(file));
> +}
> +EXPORT_SYMBOL(file_dentry);
> +
>  /**
>   * vfs_open - open the file at the given path
>   * @path: path to open
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 619ad4b016d2..5142aa2034c4 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(struct dentry 
> *dentry, unsigned int flags)
> return ret;
>  }
>
> +static struct dentry *ovl_d_native_dentry(struct dentry *dentry,
> +struct inode *inode)
> +{
> +   struct ovl_entry *oe = dentry->d_fsdata;
> +   struct dentry *realentry = ovl_upperdentry_dereference(oe);
> +
> +   if (realentry && inode == d_inode(realentry))
> +   return realentry;
> +   realentry = __ovl_dentry_lower(oe);
> +   if (realentry && inode == d_inode(realentry))
> +   return realentry;
> +   BUG();
> +}
> +
>  static const struct dentry_operations ovl_dentry_operations = {
> .d_release = ovl_dentry_release,
> .d_select_inode = ovl_d_select_inode,
> +   .d_native_dentry = ovl_d_native_dentry,
>  };
>
>  static const struct dentry_operations ovl_reval_dentry_operations = {
> .d_release = ovl_dentry_release,
> .d_select_inode = ovl_d_select_inode,
> +   .d_native_dentry = ovl_d_native_dentry,
> .d_revalidate = ovl_dentry_revalidate,
> .d_weak_revalidate = ovl_dentry_weak_revalidate,
>  };
> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
> index c4b5f4b3f8f8..99ecb6de636c 100644
> --- a/include/linux/dcache.h
> +++ b/include/linux/dcache.h
> @@ -161,6 +161,7 @@ struct dentry_operations {
> struct vfsmount *(*d_automount)(struct path *);
> int (*d_manage)(struct dentry *, bool);
> struct inode *(*d_select_inode)(struct dentry *, unsigned);
> +   struct dentry *(*d_native_dentry)(struct dentry *, struct inode *);
>  } cacheline_aligned;
>
>  /*
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index ae681002100a..1091d9f43271 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(const struct 
> file *f)
> return f->f_inode;
>  }
>
> +extern struct dentry *file_dentry(const struct file *file);
> +
>  static inline int locks_lock_file_wait(struct file *filp, struct file_lock 
> *fl)
>  {
> return locks_lock_inode_wait(file_inode(filp), fl);
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-18 Thread Sedat Dilek
On Thu, Mar 17, 2016 at 11:15 AM, Sedat Dilek  wrote:
> On Thu, Mar 17, 2016 at 10:33 AM, Miklos Szeredi  wrote:
>> On Thu, Mar 17, 2016 at 10:09 AM, Sedat Dilek  wrote:
>>> On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
 From: Miklos Szeredi 

 This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: 
 Make
 f_path always point to the overlay and f_inode to the underlay").

>>>
>>> Can you put that series in your vfs.git tree?
>>> Easier for getting and testing.
>>
>> Ok, pushed to:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git file_dentry
>>
>
> Is that correct the ext4-related patches 3/4 and 4/4 are Linux-v4.5 material?
> Not applicable fpr v4.4.y-stable?
>

Sorry, for disturbing again - parallelly building some other software
which needs my attention.

Why didn't you split 1/4 into a vfs (generic) part and overlayfs (related) part?
Thinking of bisecting or backporting ovl fixes.

Just my €0,02.

- Sedat -


Re: [PATCH 1/4] vfs: add file_dentry()

2016-03-18 Thread Sedat Dilek
On Thu, Mar 17, 2016 at 11:15 AM, Sedat Dilek  wrote:
> On Thu, Mar 17, 2016 at 10:33 AM, Miklos Szeredi  wrote:
>> On Thu, Mar 17, 2016 at 10:09 AM, Sedat Dilek  wrote:
>>> On Thu, Mar 17, 2016 at 10:02 AM, Miklos Szeredi  wrote:
 From: Miklos Szeredi 

 This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: 
 Make
 f_path always point to the overlay and f_inode to the underlay").

>>>
>>> Can you put that series in your vfs.git tree?
>>> Easier for getting and testing.
>>
>> Ok, pushed to:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git file_dentry
>>
>
> Is that correct the ext4-related patches 3/4 and 4/4 are Linux-v4.5 material?
> Not applicable fpr v4.4.y-stable?
>

Sorry, for disturbing again - parallelly building some other software
which needs my attention.

Why didn't you split 1/4 into a vfs (generic) part and overlayfs (related) part?
Thinking of bisecting or backporting ovl fixes.

Just my €0,02.

- Sedat -