Kernel commit
7a9ca53ae (~v4.13) added the requirement for xattr_sem locking
when calling *dquot_transfer. As of now, in rare cases, it is possible that
we can modify inode xattrs and perform their consistency checks in parallel,
which can fail.
Change-Id: I041694e30ce6c8398864c0ad57671df0bffd2f52
Signed-off-by: Andrew Perepechko <andrew.perepechko@hpe.com>
HPE-bug-id: LUS-10549
Reviewed-on: https://review.whamcloud.com/45424
Reviewed-by: Alexander Zarochentsev <alexander.zarochentsev@hpe.com>
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
])
]) # LC_HAVE_PROJECT_QUOTA
+AC_DEFUN([LC_HAVE_GET_INODE_USAGE], [
+LB_CHECK_COMPILE([if get_inode_usage exists],
+get_inode_usage, [
+ struct inode;
+ #include <linux/quota.h>
+],[
+ struct dquot_operations ops = { };
+
+ ops.get_inode_usage(NULL, NULL);
+],[
+ AC_DEFINE(HAVE_GET_INODE_USAGE, 1,
+ [get_inode_usage function exists])
+])
+]) # LC_HAVE_GET_INODE_USAGE
+
#
# LC_INVALIDATE_RANGE
#
# 4.13
LC_BIO_INTEGRITY_ENABLED
+ LC_HAVE_GET_INODE_USAGE
# 4.14
LC_PAGEVEC_INIT_ONE_PARAM
dquot_initialize(inode);
transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
if (transfer_to[PRJQUOTA]) {
+ lock_dquot_transfer(inode);
err = __dquot_transfer(inode, transfer_to);
+ unlock_dquot_transfer(inode);
dqput(transfer_to[PRJQUOTA]);
if (err)
return err;
iattr.ia_uid = make_kuid(&init_user_ns, attr->la_uid);
iattr.ia_gid = make_kgid(&init_user_ns, attr->la_gid);
+ lock_dquot_transfer(inode);
rc = dquot_transfer(inode, &iattr);
+ unlock_dquot_transfer(inode);
if (rc) {
CERROR("%s: quota transfer failed. Is quota enforcement enabled on the ldiskfs filesystem? rc = %d\n",
osd_ino2name(inode), rc);
#define osd_bio_nr_segs(bio) bio_segments((bio))
#endif /* HAVE_BIO_BI_PHYS_SEGMENTS */
+#ifdef HAVE_GET_INODE_USAGE
+#define lock_dquot_transfer(inode) down_read(&LDISKFS_I(inode)->xattr_sem)
+#define unlock_dquot_transfer(inode) up_read(&LDISKFS_I(inode)->xattr_sem)
+#else
+#define lock_dquot_transfer(inode) do {} while (0)
+#define unlock_dquot_transfer(inode) do {} while (0)
+#endif
+
#endif /* _OSD_INTERNAL_H */