From: Alex Zhuravlev Date: Mon, 16 Oct 2023 13:59:08 +0000 (+0300) Subject: LU-16966 osd: take trunc_lock for fallocate X-Git-Tag: 2.15.4-RC1~14 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=refs%2Fchanges%2F10%2F52710%2F2;p=fs%2Flustre-release.git LU-16966 osd: take trunc_lock for fallocate as fallocate may need few transactions (or transaction restarted) we have to avoid any concurrent writes/truncates on this object until fallocate supports 'restart-from-beginning' - first stop the transaction, then release the lock, then repeat again (like the write path does). Lustre-change: https://review.whamcloud.com/52264 Lustre-commit: 51529fb57f85210e292a15c882cf25a4689ea77d Signed-off-by: Alex Zhuravlev Change-Id: I0bf38b1886fbf24656b45fe0f87fcbad2227672a Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52710 Reviewed-by: Andreas Dilger Reviewed-by: Arshad Hussain Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 5a21f0f..f74862c 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -2262,33 +2262,39 @@ static int osd_declare_fallocate(const struct lu_env *env, LASSERT(th); LASSERT(inode); - if (mode & FALLOC_FL_PUNCH_HOLE) { - rc = osd_declare_inode_qid(env, i_uid_read(inode), - i_gid_read(inode), - i_projid_read(inode), 0, oh, - osd_dt_obj(dt), NULL, OSD_QID_BLK); - if (rc == 0) - rc = osd_trunc_lock(osd_dt_obj(dt), oh, false); - RETURN(rc); - } - - /* quota space for metadata blocks - * approximate metadata estimate should be good enough. - */ - quota_space += PAGE_SIZE; - quota_space += depth * LDISKFS_BLOCK_SIZE(osd_sb(osd)); + if ((mode & FALLOC_FL_PUNCH_HOLE) == 0) { + /* quota space for metadata blocks + * approximate metadata estimate should be good enough. + */ + quota_space += PAGE_SIZE; + quota_space += depth * LDISKFS_BLOCK_SIZE(osd_sb(osd)); - /* quota space should be reported in 1K blocks */ - quota_space = toqb(quota_space) + toqb(end - start) + - LDISKFS_META_TRANS_BLOCKS(inode->i_sb); + /* quota space should be reported in 1K blocks */ + quota_space = toqb(quota_space) + toqb(end - start) + + LDISKFS_META_TRANS_BLOCKS(inode->i_sb); - /* We don't need to reserve credits for whole fallocate here. - * We reserve space only for metadata. Fallocate credits are - * extended as required - */ + /* + * We don't need to reserve credits for whole fallocate here. + * We reserve space only for metadata. Fallocate credits are + * extended as required + */ + } rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), i_projid_read(inode), quota_space, oh, osd_dt_obj(dt), NULL, OSD_QID_BLK); + if (rc) + RETURN(rc); + + /* + * The both hole punch and allocation may need few transactions + * to complete, so we have to avoid concurrent writes/truncates + * as we can't release object lock from within ldiskfs. + * Notice locking order: transaction start, then lock object + * (don't confuse object lock dt_{read|write}_lock() with the + * trunc lock. + */ + rc = osd_trunc_lock(osd_dt_obj(dt), oh, false); + RETURN(rc); }