linux: zfs: ctldir: set [amc]time to snapshot's creation property
If looking up a snapdir inode failed, hold pool config – hold the snapshot – get its creation property – release it – release it, then use that as the [amc]time in the allocated inode. If that fails then fall back to current time. No performance impact since this is only done when allocating a new snapdir inode. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Closes #15110 Closes #15117
This commit is contained in:
parent
6751634d77
commit
a21ca18d4d
|
@ -478,17 +478,19 @@ zfsctl_is_snapdir(struct inode *ip)
|
|||
*/
|
||||
static struct inode *
|
||||
zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
|
||||
const struct file_operations *fops, const struct inode_operations *ops)
|
||||
const struct file_operations *fops, const struct inode_operations *ops,
|
||||
uint64_t creation)
|
||||
{
|
||||
inode_timespec_t now;
|
||||
struct inode *ip;
|
||||
znode_t *zp;
|
||||
inode_timespec_t now = {.tv_sec = creation};
|
||||
|
||||
ip = new_inode(zfsvfs->z_sb);
|
||||
if (ip == NULL)
|
||||
return (NULL);
|
||||
|
||||
now = current_time(ip);
|
||||
if (!creation)
|
||||
now = current_time(ip);
|
||||
zp = ITOZ(ip);
|
||||
ASSERT3P(zp->z_dirlocks, ==, NULL);
|
||||
ASSERT3P(zp->z_acl_cached, ==, NULL);
|
||||
|
@ -552,14 +554,28 @@ zfsctl_inode_lookup(zfsvfs_t *zfsvfs, uint64_t id,
|
|||
const struct file_operations *fops, const struct inode_operations *ops)
|
||||
{
|
||||
struct inode *ip = NULL;
|
||||
uint64_t creation = 0;
|
||||
dsl_dataset_t *snap_ds;
|
||||
dsl_pool_t *pool;
|
||||
|
||||
while (ip == NULL) {
|
||||
ip = ilookup(zfsvfs->z_sb, (unsigned long)id);
|
||||
if (ip)
|
||||
break;
|
||||
|
||||
if (id <= ZFSCTL_INO_SNAPDIRS && !creation) {
|
||||
pool = dmu_objset_pool(zfsvfs->z_os);
|
||||
dsl_pool_config_enter(pool, FTAG);
|
||||
if (!dsl_dataset_hold_obj(pool,
|
||||
ZFSCTL_INO_SNAPDIRS - id, FTAG, &snap_ds)) {
|
||||
creation = dsl_get_creation(snap_ds);
|
||||
dsl_dataset_rele(snap_ds, FTAG);
|
||||
}
|
||||
dsl_pool_config_exit(pool, FTAG);
|
||||
}
|
||||
|
||||
/* May fail due to concurrent zfsctl_inode_alloc() */
|
||||
ip = zfsctl_inode_alloc(zfsvfs, id, fops, ops);
|
||||
ip = zfsctl_inode_alloc(zfsvfs, id, fops, ops, creation);
|
||||
}
|
||||
|
||||
return (ip);
|
||||
|
@ -581,7 +597,7 @@ zfsctl_create(zfsvfs_t *zfsvfs)
|
|||
ASSERT(zfsvfs->z_ctldir == NULL);
|
||||
|
||||
zfsvfs->z_ctldir = zfsctl_inode_alloc(zfsvfs, ZFSCTL_INO_ROOT,
|
||||
&zpl_fops_root, &zpl_ops_root);
|
||||
&zpl_fops_root, &zpl_ops_root, 0);
|
||||
if (zfsvfs->z_ctldir == NULL)
|
||||
return (SET_ERROR(ENOENT));
|
||||
|
||||
|
|
Loading…
Reference in New Issue