Skip to content

Commit

Permalink
Handle NULL in nfsd .fsync() hook
Browse files Browse the repository at this point in the history
How nfsd handles .fsync() has been changed a couple of times in the
recent kernels.  But basically there are three cases we need to
consider.

Linux 2.6.12 - 2.6.33
* The .fsync() hook takes 3 arguments
* The nfsd will call .fsync() with a NULL file struct pointer.

Linux 2.6.34
* The .fsync() hook takes 3 arguments
* The nfsd no longer calls .fsync() but instead used sync_inode()

Linux 2.6.35 - 2.6.x
* The .fsync() hook takes 2 arguments
* The nfsd no longer calls .fsync() but instead used sync_inode()

For once it looks like we've gotten lucky.  The first two cases can
actually be collased in to one if we stop using the file struct
pointer entirely.  Since the dentry is still passed in both cases
this is possible.  The last case can then be safely handled by
unconditionally using the dentry in the file struct pointer now
that we know the nfsd caller has been removed.

Closes openzfs#230
  • Loading branch information
behlendorf committed May 6, 2011
1 parent 6ee44e3 commit 3117dd0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
13 changes: 0 additions & 13 deletions include/linux/vfs_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@
#ifndef _ZFS_VFS_H
#define _ZFS_VFS_H

/*
* 2.6.35 API change,
* The dentry argument to the .fsync() vfs hook was deemed unused by
* all filesystem consumers and dropped. Add a compatibility prototype
* to ensure correct usage when defining this callback.
*/
#ifdef HAVE_2ARGS_FSYNC
#define ZPL_FSYNC_PROTO(fn, x, y, z) static int fn(struct file *x, int z)
#else
#define ZPL_FSYNC_PROTO(fn, x, y, z) static int fn(struct file *x, \
struct dentry *y, int z)
#endif /* HAVE_2ARGS_FSYNC */

/*
* 2.6.28 API change,
* Added insert_inode_locked() helper function, prior to this most callers
Expand Down
23 changes: 21 additions & 2 deletions module/zfs/zpl_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,32 @@ zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
return (error);
}

ZPL_FSYNC_PROTO(zpl_fsync, filp, unused_dentry, datasync)
/*
* 2.6.35 API change,
* As of 2.6.35 the dentry argument to the .fsync() vfs hook was deemed
* redundant. The dentry is still accessible via filp->f_path.dentry,
* and we are guaranteed that filp will never be NULL.
*
* 2.6.34 API change,
* Prior to 2.6.34 the nfsd kernel server would pass a NULL file struct *
* to the .fsync() hook. For this reason, we must be careful not to use
* filp unconditionally in the 3 argument case.
*/
#ifdef HAVE_2ARGS_FSYNC
static int
zpl_fsync(struct file *filp, int datasync)
{
struct dentry *dentry = filp->f_path.dentry;
#else
static int
zpl_fsync(struct file *filp, struct dentry *dentry, int datasync)
{
#endif /* HAVE_2ARGS_FSYNC */
cred_t *cr = CRED();
int error;

crhold(cr);
error = -zfs_fsync(filp->f_path.dentry->d_inode, datasync, cr);
error = -zfs_fsync(dentry->d_inode, datasync, cr);
crfree(cr);
ASSERT3S(error, <=, 0);

Expand Down

0 comments on commit 3117dd0

Please sign in to comment.