From fb9152406da6fe439b75244e769db7dacb20a8d1 Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Sat, 29 Jul 2017 21:54:30 +0800 Subject: [PATCH] LU-9597 ofd: fix race for project setattr sanity-quota 33 exposed an intresting project quota bug, problem is we could hit following condition: step 1: create an empty file step 2: buffer write data to file, at this time project id 0 is packed. step 3: chattr file's project id If write RPC is generated on client but not reaching OST yet, and step 3 chattr is issued in this time window and chattr on OST is done before write PRC being processed on OST: That means we have changed file's project ID, but ofd_attr_handle_id() did not clear S_ISUID and S_ISGID for this case. Write RPC arrived on OST, first write RPC will call ofd_attr_handle_id() to set attribute. Unfortunately it will think this is first write as S_ISUID and S_ISGID is set, project id will be reset with packed id 0, thus we got wrong project accounting. We should use another file mode to indicate whether project id has been initialized, this patch tries to fix this problem. Change-Id: Ie2f9ce5b662c3011aa1cd2f59e1fb20526a3e3d7 Signed-off-by: Wang Shilong Reviewed-on: https://review.whamcloud.com/28274 Tested-by: Jenkins Reviewed-by: Niu Yawei Reviewed-by: Li Xi Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/ofd/ofd_objects.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lustre/ofd/ofd_objects.c b/lustre/ofd/ofd_objects.c index 7f328ee..eb959e4 100644 --- a/lustre/ofd/ofd_objects.c +++ b/lustre/ofd/ofd_objects.c @@ -225,7 +225,7 @@ int ofd_precreate_objects(const struct lu_env *env, struct ofd_device *ofd, RETURN(-ENOMEM); info->fti_attr.la_valid = LA_TYPE | LA_MODE; - info->fti_attr.la_mode = S_IFREG | S_ISUID | S_ISGID | 0666; + info->fti_attr.la_mode = S_IFREG | S_ISUID | S_ISGID | S_ISVTX | 0666; info->fti_dof.dof_type = dt_mode_to_dft(S_IFREG); info->fti_attr.la_valid |= LA_ATIME | LA_MTIME | LA_CTIME; @@ -449,9 +449,11 @@ int ofd_attr_handle_id(const struct lu_env *env, struct ofd_object *fo, */ if (!is_setattr) { if (!(ln->la_mode & S_ISUID)) - la->la_valid &= ~(LA_UID | LA_PROJID); + la->la_valid &= ~LA_UID; if (!(ln->la_mode & S_ISGID)) - la->la_valid &= ~(LA_GID | LA_PROJID); + la->la_valid &= ~LA_GID; + if (!(ln->la_mode & S_ISVTX)) + la->la_valid &= ~LA_PROJID; } /* Initialize ownership of this object, clear SUID+SGID bits*/ @@ -459,6 +461,8 @@ int ofd_attr_handle_id(const struct lu_env *env, struct ofd_object *fo, mask |= S_ISUID; if ((la->la_valid & LA_GID) && (ln->la_mode & S_ISGID)) mask |= S_ISGID; + if ((la->la_valid & LA_PROJID) && (ln->la_mode & S_ISVTX)) + mask |= S_ISVTX; if (mask != 0) { if (!(la->la_valid & LA_MODE) || !is_setattr) { la->la_mode = ln->la_mode; -- 1.8.3.1