So next round. This has Mark's fix for sendfile() which was pushed to 1.4. The other two enable NFS support. Sunil
From: Mark Fasheh <mfasheh at suse.com> ocfs2_sendfile() was duplicating locking which happens later on in ocfs2_readpage(). The double locking would sometimes cause a lockup in nfsd, which uses ->sendfile() for fast read support. An easy way to see this is to mount an exported ocfs2 fs on a client and initiate two parallel read/write dd commands to the same file when there is low memory on the server. Fix ocfs2_sendfile() so that it only takes and immediately drops the cluster lock. This is consistent with the locking in ocfs2_file_splice_read(). Signed-off-by: Mark Fasheh <mfasheh at suse.com> Acked-by: Sunil Mushran <sunil.mushran at oracle.com> --- fs/ocfs2/file.c | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index daba3a6..3a2ba66 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2284,15 +2284,14 @@ static ssize_t ocfs2_file_sendfile(struct file *in_file, mlog_errno(ret); goto bail; } + ocfs2_inode_unlock(inode, 0); - down_read(&OCFS2_I(inode)->ip_alloc_sem); - + /* + * This uses ->readpage, so we don't want to hold any cluster + * locks before the call. + */ ret = generic_file_sendfile(in_file, ppos, count, actor, target); - up_read(&OCFS2_I(inode)->ip_alloc_sem); - - ocfs2_inode_unlock(inode, 0); - bail: mlog_exit(ret); return ret; -- 1.6.3.3
Sunil Mushran
2009-Dec-05 01:54 UTC
[Ocfs2-devel] [PATCH 2/3] ocfs2: Reverse patch that disabled NFS
This patch reverses commit 73359af38a74b691d30e889c707266bf436476cb.
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
Config.make.in | 1 -
configure.in | 2 --
fs/ocfs2/Makefile | 4 ----
fs/ocfs2/export.c | 4 ----
fs/ocfs2/export.h | 3 ---
fs/ocfs2/super.c | 2 --
6 files changed, 0 insertions(+), 16 deletions(-)
diff --git a/Config.make.in b/Config.make.in
index acbe8fd..8675982 100644
--- a/Config.make.in
+++ b/Config.make.in
@@ -83,7 +83,6 @@ SKIP_BUFFER_TRIGGERS = @SKIP_BUFFER_TRIGGERS@
NO_NAME_IN_BACKING_DEV_INFO=@NO_NAME_IN_BACKING_DEV_INFO@
NO_KOBJ_ATTRIBUTE = @NO_KOBJ_ATTRIBUTE@
SKIP_QUOTAS= @SKIP_QUOTAS@
-SKIP_EXPORTS= @SKIP_EXPORTS@
OCFS_DEBUG = @OCFS_DEBUG@
diff --git a/configure.in b/configure.in
index 405e1a5..6b83f8c 100644
--- a/configure.in
+++ b/configure.in
@@ -452,8 +452,6 @@ OCFS2_CHECK_KERNEL([new quota format in dqblk_qtree.h],
dqblk_qtree.h,
AC_SUBST(SKIP_QUOTAS)
KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $SKIP_QUOTAS"
-SKIP_EXPORTS=yes
-
cancel_work_sync_header OCFS2_CHECK_KERNEL([cancel_work_sync() in workqueue.h],
workqueue.h,
, cancel_work_sync_header=cancel_work_sync.h, [extern int
cancel_work_sync(struct work_struct])
diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile
index 848c121..7a03c94 100644
--- a/fs/ocfs2/Makefile
+++ b/fs/ocfs2/Makefile
@@ -132,10 +132,6 @@ ifdef SKIP_QUOTAS
EXTRA_CFLAGS += -DSKIP_QUOTAS
endif
-ifdef SKIP_EXPORTS
-EXTRA_CFLAGS += -DSKIP_EXPORTS
-endif
-
#
# Since SUBDIRS means something to kbuild, define them safely. Do not
# include trailing slashes.
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index e2a584f..fce7d23 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -23,8 +23,6 @@
* Boston, MA 021110-1307, USA.
*/
-#ifndef SKIP_EXPORTS
-
#include <linux/fs.h>
#include <linux/types.h>
@@ -287,5 +285,3 @@ const struct export_operations ocfs2_export_ops = {
.fh_to_parent = ocfs2_fh_to_parent,
.get_parent = ocfs2_get_parent,
};
-
-#endif /* SKIP_EXPORTS */
diff --git a/fs/ocfs2/export.h b/fs/ocfs2/export.h
index 1f93127..0707bf3 100644
--- a/fs/ocfs2/export.h
+++ b/fs/ocfs2/export.h
@@ -26,8 +26,6 @@
#ifndef OCFS2_EXPORT_H
#define OCFS2_EXPORT_H
-#ifndef SKIP_EXPORTS
-
#include <linux/exportfs.h>
#ifdef EXPORTOP_IS_NOT_CONST
@@ -36,5 +34,4 @@ extern struct export_operations ocfs2_export_ops;
extern const struct export_operations ocfs2_export_ops;
#endif
-#endif
#endif /* OCFS2_EXPORT_H */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index cf50330..a104314 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -2020,9 +2020,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
sb->s_fs_info = osb;
sb->s_op = &ocfs2_sops;
-#ifndef SKIP_EXPORTS
sb->s_export_op = &ocfs2_export_ops;
-#endif
#ifndef SKIP_QUOTAS
sb->s_qcop = &ocfs2_quotactl_ops;
sb->dq_op = &ocfs2_quota_operations;
--
1.6.3.3
Mainline commits 6e91ea2bb0b6a3ddf6d4faeb54a9c20d4e20bc42 and
2596110a3994593f6aa3e2bb76345ad4791b1a14 changed the exportfs api.
This patch adds support for the old exportfs api by enabling
export_ops.decode_fh()
and export_ops.get_dentry().
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
Config.make.in | 1 +
configure.in | 5 ++++
fs/ocfs2/Makefile | 4 +++
fs/ocfs2/export.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/ocfs2/export.h | 2 +
5 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/Config.make.in b/Config.make.in
index 8675982..304fd76 100644
--- a/Config.make.in
+++ b/Config.make.in
@@ -83,6 +83,7 @@ SKIP_BUFFER_TRIGGERS = @SKIP_BUFFER_TRIGGERS@
NO_NAME_IN_BACKING_DEV_INFO=@NO_NAME_IN_BACKING_DEV_INFO@
NO_KOBJ_ATTRIBUTE = @NO_KOBJ_ATTRIBUTE@
SKIP_QUOTAS= @SKIP_QUOTAS@
+NFS_OLD_API=@NFS_OLD_API@
OCFS_DEBUG = @OCFS_DEBUG@
diff --git a/configure.in b/configure.in
index 6b83f8c..ebb0a34 100644
--- a/configure.in
+++ b/configure.in
@@ -457,6 +457,11 @@ OCFS2_CHECK_KERNEL([cancel_work_sync() in workqueue.h],
workqueue.h,
, cancel_work_sync_header=cancel_work_sync.h, [extern int
cancel_work_sync(struct work_struct])
KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $cancel_work_sync_header"
+NFS_OLD_API+OCFS2_CHECK_KERNEL([existence of exportfs.h], exportfs.h,
+ , NFS_OLD_API=yes, [enum fid_type {])
+AC_SUBST(NFS_OLD_API)
+
# End kapi_compat checks
# using -include has two advantages:
diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile
index 7a03c94..9f8115d 100644
--- a/fs/ocfs2/Makefile
+++ b/fs/ocfs2/Makefile
@@ -132,6 +132,10 @@ ifdef SKIP_QUOTAS
EXTRA_CFLAGS += -DSKIP_QUOTAS
endif
+ifdef NFS_OLD_API
+EXTRA_CFLAGS += -DNFS_OLD_API
+endif
+
#
# Since SUBDIRS means something to kbuild, define them safely. Do not
# include trailing slashes.
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index fce7d23..00dcb59 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -47,10 +47,17 @@ struct ocfs2_inode_handle
u32 ih_generation;
};
+#ifdef NFS_OLD_API
+static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
+#else
static struct dentry *ocfs2_get_dentry(struct super_block *sb,
struct ocfs2_inode_handle *handle)
+#endif
{
struct inode *inode;
+#ifdef NFS_OLD_API
+ struct ocfs2_inode_handle *handle = vobjp;
+#endif
struct ocfs2_super *osb = OCFS2_SB(sb);
u64 blkno = handle->ih_blkno;
int status, set;
@@ -247,6 +254,53 @@ bail:
return type;
}
+#ifdef NFS_OLD_API
+static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in,
+ int fh_len, int fileid_type,
+ int (*acceptable)(void *context,
+ struct dentry *de),
+ void *context)
+{
+ struct ocfs2_inode_handle handle, parent;
+ struct dentry *ret = NULL;
+ __le32 *fh = (__force __le32 *) fh_in;
+
+ mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
+ sb, fh, fh_len, fileid_type, acceptable, context);
+
+ if (fh_len < 3 || fileid_type > 2)
+ goto bail;
+
+ if (fileid_type == 2) {
+ if (fh_len < 6)
+ goto bail;
+
+ parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
+ parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
+ parent.ih_generation = le32_to_cpu(fh[5]);
+
+ mlog(0, "Decoding parent: blkno: %llu, generation: %u\n",
+ (unsigned long long)parent.ih_blkno,
+ parent.ih_generation);
+ }
+
+ handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32;
+ handle.ih_blkno |= (u64)le32_to_cpu(fh[1]);
+ handle.ih_generation = le32_to_cpu(fh[2]);
+
+ mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
+ (unsigned long long)handle.ih_blkno, handle.ih_generation);
+
+ ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent,
+ acceptable, context);
+
+bail:
+ mlog_exit_ptr(ret);
+ return ret;
+}
+
+#else /* ! NFS_OLD_API */
+
static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
struct fid *fid, int fh_len, int fh_type)
{
@@ -274,6 +328,7 @@ static struct dentry *ocfs2_fh_to_parent(struct super_block
*sb,
parent.ih_generation = le32_to_cpu(fid->raw[5]);
return ocfs2_get_dentry(sb, &parent);
}
+#endif /* NFS_OLD_API */
#ifdef EXPORTOP_IS_NOT_CONST
struct export_operations ocfs2_export_ops = {
@@ -281,7 +336,12 @@ struct export_operations ocfs2_export_ops = {
const struct export_operations ocfs2_export_ops = {
#endif
.encode_fh = ocfs2_encode_fh,
+#ifdef NFS_OLD_API
+ .get_dentry = ocfs2_get_dentry,
+ .decode_fh = ocfs2_decode_fh,
+#else
.fh_to_dentry = ocfs2_fh_to_dentry,
.fh_to_parent = ocfs2_fh_to_parent,
+#endif
.get_parent = ocfs2_get_parent,
};
diff --git a/fs/ocfs2/export.h b/fs/ocfs2/export.h
index 0707bf3..2cac2a6 100644
--- a/fs/ocfs2/export.h
+++ b/fs/ocfs2/export.h
@@ -26,7 +26,9 @@
#ifndef OCFS2_EXPORT_H
#define OCFS2_EXPORT_H
+#ifndef NFS_OLD_API
#include <linux/exportfs.h>
+#endif
#ifdef EXPORTOP_IS_NOT_CONST
extern struct export_operations ocfs2_export_ops;
--
1.6.3.3
On Fri, Dec 04, 2009 at 05:54:03PM -0800, Sunil Mushran wrote:> So next round. This has Mark's fix for sendfile() which was pushed to 1.4. > The other two enable NFS support.ack -- "When I am working on a problem I never think about beauty. I only think about how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." - Buckminster Fuller Joel Becker Principal Software Developer Oracle E-mail: joel.becker at oracle.com Phone: (650) 506-8127