From 2d5f8359176f155baac4dd4a6792473a381044b8 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sat, 28 Jun 2014 21:47:15 +0000 Subject: [PATCH] There might be a potential race condition for the NFSv4 client when a newly created file has another open done on it that update the open mode. This patch moves the code that updates the open mode up into the block where the mutex is held to ensure this cannot happen. No bug caused by this potential race has been observed, but this fix is a safety belt to ensure it cannot happen. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clstate.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 5fa302f102b..6f0692cb6f2 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -280,6 +280,23 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg, nfscl_newopen(clp, dp, &owp, &nowp, &op, &nop, own, nfhp, fhlen, newonep); + /* + * Now, check the mode on the open and return the appropriate + * value. + */ + if (retp != NULL) { + if (nfhp != NULL && dp != NULL && nop == NULL) + /* new local open on delegation */ + *retp = NFSCLOPEN_SETCRED; + else + *retp = NFSCLOPEN_OK; + } + if (op != NULL && (amode & ~(op->nfso_mode))) { + op->nfso_mode |= amode; + if (retp != NULL && dp == NULL) + *retp = NFSCLOPEN_DOOPEN; + } + /* * Serialize modifications to the open owner for multiple threads * within the same process using a read/write sleep lock. @@ -295,23 +312,6 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg, *owpp = owp; if (opp != NULL) *opp = op; - if (retp != NULL) { - if (nfhp != NULL && dp != NULL && nop == NULL) - /* new local open on delegation */ - *retp = NFSCLOPEN_SETCRED; - else - *retp = NFSCLOPEN_OK; - } - - /* - * Now, check the mode on the open and return the appropriate - * value. - */ - if (op != NULL && (amode & ~(op->nfso_mode))) { - op->nfso_mode |= amode; - if (retp != NULL && dp == NULL) - *retp = NFSCLOPEN_DOOPEN; - } return (0); }