From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BFD72EBDD0 for ; Mon, 9 Mar 2026 21:04:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773090262; cv=none; b=OAYoWwyggYZx2KUNAa5xU+BflmZYC4nKvAHFNyuC/ESvHa2huGFQumILcrZ+fbbuHdP2/okSXKAqJT5zHUuarZRJbIqYdBLVwReAW+toYwUflgnaWmTqmkY9Elis/xP6EVKz1vdTuSTVe21ZypsFFC66nqqcrsgYl+Ol2y4geSQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773090262; c=relaxed/simple; bh=8u7NXO4gL8IgjhKbd5rzr3CtH3lhM8sD3BmRx73qmmA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XTjPWbic6iufdMpuiuPa+sr4AwZyibLj8ViTuE5oXfkkhFYVoAboqQ5n2XpYvJnNOtL8pK5pMYHNtWm5e7kBDZw7Yl5j3IGV7iDZXhgJ1nU/AFl0Vk42tZgH89IVUE7k6YHonOGHCcM8iSt12a2fMl9JOO8iZkF7RFpMhoIl7/c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=permerror header.from=versity.com; spf=pass smtp.mailfrom=versity.com; dkim=pass (2048-bit key) header.d=versity.com header.i=@versity.com header.b=GLxbarTw; arc=none smtp.client-ip=209.85.221.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=permerror header.from=versity.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=versity.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=versity.com header.i=@versity.com header.b="GLxbarTw" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-439b6d9c981so5856596f8f.1 for ; Mon, 09 Mar 2026 14:04:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=versity.com; s=google; t=1773090259; x=1773695059; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=O0VcDiRShyiJ2rACqKLI2iMIre6rQq9B/sEpcPLFfNY=; b=GLxbarTwBeMYC1nZDOa+3riPe9/fQnxcjEPSiUbcCD9bjdgMFzSn5eLpyLBjZEWEg1 Cc4iC1/qpLav9UDkp8l/L4q6BgkjEjRJNJJcVaXhdLiyD11+OdyF1QlPwAieCXvJjCXD LldjlYN9hw3ru+0N8gEN+S6XVjvAgq91a5WYbfMLzA3+c3T6BMkO4KMqKJz91FiybC9n Qx9/B4peVvuMQs1iVgxLnBLnWe0eprij7lcxzPRqekErUE0myrwJCGtdEQmxeO61cx6S pJfMQheG3iQyZ4Asg/WDRTSOxaPCjoSrFFRk/Z5j12eDwf3fyZRqSMiziWD5AJsvYJZf Lakg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773090259; x=1773695059; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=O0VcDiRShyiJ2rACqKLI2iMIre6rQq9B/sEpcPLFfNY=; b=GakaNjTxedenC2b9xJZVMDGlfz/+b9QavoYhP1dl28dBzXJkYeec0vitJ8bnwO15b4 367Ozi4xTh8pb9FY4iaWIOmryd5sCPasn2Mcnitum6sUex6kQocWnD3U0mAlIkayXNiY UucGGbKvEh8GucWFcBfhQRZLzDykGpP0YRWVVZSk/qeZ3Ok6bkQppfCmrLFLV1kSSKWJ QDkh/dxmo6ix1m0HAFjHP7roX0ugObJR9Szlfw9mb1y1WnVHIDSJUKapkAlQTUPeGXMg 0qmT9VjL4jNFO6rIDVhnkKIPaVeFcsqr4aDPiuzNQtCdZS/ciogTxXPFAHTI3PipkV9G bRgQ== X-Gm-Message-State: AOJu0YxavvYrUH/jgLL6vw7hyiFQoTI1fD2QQVacwzuTu3GSYqEVhj/9 h6XmUNLTvDq98fOUvIKFzceW74xpDRoL6onuy/bPEaplGJsZCOY3l9c29ZBGfNako+eg62OoJw2 408Pd X-Gm-Gg: ATEYQzy/aaG74F4+Ep/3zTjfur33qAxdB9N5ezmFPn/CMs98baARo06MbNj6FN9pFsG 5F0sSiar6w65yjHMKhcnOk4wueNJIb8eGktAXBXhnQBaPceZ+XWTHo2CeLAWpZ51Cy7/Me8MbD/ J/mMoo8UgSyn8SJBSiE0peBx4T3U7oebutGL09yyuJAw4sV8SHv63eygkeuRFswV8UVR2TKUPB1 E7yfqJ/Rybt1Cw9e+4n+3GKk8qcdHRA6tHgU9s6C1Y9dTMKBsuik5Ly0IxcbMkxQ6MnqQdj8yD/ J/rj5ZIShwC2J8MwPIVWtu6dr3VSd8IbKnTPfzoFtNpwIA7XBLuf9mNaAM101ylPo1eJSCdAb7Z CeKtkcJSWiZstMica+ZQ80+qoDDLzjx1jTyeCIIqrEoASuj06ijetZFdUjAaMd2tbeUxsTmeOIj ZuVunmOShULGPlTQRJm1FG4CSgZsNlm2WV0p5abjJ2aGVfOR8Aj7H4UMrOX4kE7qREeUc= X-Received: by 2002:a05:6000:18a6:b0:439:9812:35ea with SMTP id ffacd0b85a97d-439eff12c90mr2089386f8f.3.1773090258983; Mon, 09 Mar 2026 14:04:18 -0700 (PDT) Received: from localhost.localdomain (46-117-212-87.ftth.glasoperator.nl. [87.212.117.46]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dada9116sm26906639f8f.14.2026.03.09.14.04.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 14:04:18 -0700 (PDT) From: Valerie Aurora To: rpdfs-devel@lists.linux.dev Cc: Valerie Aurora Subject: [PATCH 2/3] rpdfs: Add directory i_size accounting and helper functions Date: Mon, 9 Mar 2026 22:04:02 +0100 Message-ID: <20260309210403.105006-3-val@versity.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260309210403.105006-1-val@versity.com> References: <20260309210403.105006-1-val@versity.com> Precedence: bulk X-Mailing-List: rpdfs-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Implement directory i_size as the total length of all directory entry names including a null termination. Signed-off-by: Valerie Aurora --- fs/rpdfs/dir.c | 48 ++++++++++++++++++++++++++++++++++------- fs/rpdfs/format-block.h | 8 +++++++ fs/rpdfs/mkfs.c | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/rpdfs/dir.c b/fs/rpdfs/dir.c index 7ae8faf74161..0de00704a603 100644 --- a/fs/rpdfs/dir.c +++ b/fs/rpdfs/dir.c @@ -363,6 +363,26 @@ static struct key_dent *alloc_key_dent(struct dentry *dentry, struct inode *inod return kd; } +static void init_dir_size(struct inode *inode) +{ + i_size_write(inode, RPDFS_EMPTY_DIR_LEN); +} + +static int is_dir_empty(struct inode *inode) +{ + return (i_size_read(inode) == RPDFS_EMPTY_DIR_LEN); +} + +/* + * Helper function for readability. All consistency/corruption checks + * should happen in the prepare phase, so there are no checks when + * making changes. + */ +static void update_dir_size(struct inode *inode, s32 len) +{ + i_size_write(inode, i_size_read(inode) + len); +} + /* * Allocate an inode in a block transaction and return an allocated vfs * inode at its ino/gen position. Like _iget, this inserts an I_NEW @@ -429,17 +449,21 @@ static struct inode *create_new_inode(struct mnt_idmap *idmap, struct inode *dir /* update vfs inodes */ inode_init_owner(idmap, inode, dir, mode); - if (S_ISDIR(mode)) + if (S_ISDIR(mode)) { set_nlink(inode, 2); - else + init_dir_size(inode); + } else { set_nlink(inode, 1); + } + rpdfs_inode_init_ops(inode); + /* update parent vfs inode and apply changes to referenced blocks */ if (S_ISDIR(mode)) inc_nlink(dir); - /* apply changes to referenced blocks */ if (kd) { + update_dir_size(dir, kd->dent.name_len + 1); kd->dent.ig = ig; apply_add_entry(rfi, &txn, dir, kd); } @@ -532,7 +556,7 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d goto out; } - /* prepare all the blocks for in the txn */ + /* prepare all the blocks for the txn */ do { ret = rpdfs_inode_txn_prepare(rfi, &txn, old_dir, RBAF_WRITE) ?: rpdfs_inode_txn_prepare(rfi, &txn, old_inode, RBAF_WRITE) ?: @@ -551,6 +575,11 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d if (ret < 0) goto out; + /* + * TODO: walk ancestors, and if there is a directory to be + * deleted, check if it is empty. + */ + /* apply changes to block structures */ apply_remove_entry(rfi, &txn, old_dir, old_kd); if (new_inode) @@ -558,11 +587,12 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d else apply_add_entry(rfi, &txn, new_dir, new_kd); - /* update vfs inodes: first dir sizes .. */ - i_size_write(old_dir, i_size_read(old_dir) - old_dentry->d_name.len); + /* update dir sizes */ + update_dir_size(old_dir, -(old_dentry->d_name.len + 1)); if (!new_inode) - i_size_write(new_dir, i_size_read(new_dir) + new_dentry->d_name.len); - /* .. then link counts .. */ + update_dir_size(new_dir, new_dentry->d_name.len + 1); + + /* and link counts */ if (new_inode) { drop_nlink(new_inode); if (S_ISDIR(new_inode->i_mode)) { @@ -570,10 +600,12 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d drop_nlink(new_inode); } } + if (S_ISDIR(old_inode->i_mode) && (old_dir != new_dir)) { drop_nlink(old_dir); inc_nlink(new_dir); } + /* .. and finally times */ now = inode_set_ctime_current(old_dir); inode_set_mtime_to_ts(old_dir, now); diff --git a/fs/rpdfs/format-block.h b/fs/rpdfs/format-block.h index 1ff315668d2f..d4a0fb78d670 100644 --- a/fs/rpdfs/format-block.h +++ b/fs/rpdfs/format-block.h @@ -210,6 +210,14 @@ struct rpdfs_dirent { #define RPDFS_DIRENT_DOT_DOT_HASH 1ULL #define RPDFS_DIRENT_MIN_HASH 2ULL +/* + * An empty dir contains pseudo entries for "." and "..". The reported + * size of directory is the length of the null-terminated names of all + * the directory entries. (The actual size is the number of blocks + * necessary to store the dirents btree.) + */ +#define RPDFS_EMPTY_DIR_LEN 5 + /* * xattrs are currently implemented as btree items, whose keys are the * hash of the name combined with the xattr_create_counter value in the diff --git a/fs/rpdfs/mkfs.c b/fs/rpdfs/mkfs.c index f4cbf5538b3b..94798799c960 100644 --- a/fs/rpdfs/mkfs.c +++ b/fs/rpdfs/mkfs.c @@ -45,7 +45,7 @@ int rpdfs_mkfs(struct rpdfs_fs_info *rfi) rinode->ig.ino = cpu_to_le64(RPDFS_ROOT_INO); rinode->ig.gen = cpu_to_le64(RPDFS_ROOT_GEN); - rinode->size = cpu_to_le64(5); /* name lens of . and .. with null term */ + rinode->size = cpu_to_le64(RPDFS_EMPTY_DIR_LEN); rinode->version = cpu_to_le64(1); rinode->nlink = cpu_to_le32(2); rinode->mode = cpu_to_le32(S_IFDIR | 0755); -- 2.49.0