mirror of
https://github.com/versity/scoutfs.git
synced 2026-08-15 11:46:35 +00:00
Add project ID support
Add support for project IDs. They're managed through the _attr_x interfaces and are inherited from the parent directory during creation. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -33,6 +33,10 @@ static int validate_attr_x_input(struct super_block *sb, struct scoutfs_ioctl_in
|
||||
(ret = scoutfs_fmt_vers_unsupported(sb, SCOUTFS_FORMAT_VERSION_FEAT_RETENTION)))
|
||||
return ret;
|
||||
|
||||
if ((iax->x_mask & SCOUTFS_IOC_IAX_PROJECT_ID) &&
|
||||
(ret = scoutfs_fmt_vers_unsupported(sb, SCOUTFS_FORMAT_VERSION_FEAT_PROJECT_ID)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,6 +115,8 @@ int scoutfs_get_attr_x(struct inode *inode, struct scoutfs_ioctl_inode_attr_x *i
|
||||
bits |= SCOUTFS_IOC_IAX_B_RETENTION;
|
||||
size = fill_attr(size, iax, SCOUTFS_IOC_IAX__BITS, bits, bits);
|
||||
}
|
||||
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_PROJECT_ID,
|
||||
project_id, scoutfs_inode_get_proj(inode));
|
||||
|
||||
ret = size;
|
||||
unlock:
|
||||
@@ -230,6 +236,8 @@ int scoutfs_set_attr_x(struct inode *inode, struct scoutfs_ioctl_inode_attr_x *i
|
||||
(iax->bits & SCOUTFS_IOC_IAX_B_RETENTION) ?
|
||||
SCOUTFS_INO_FLAG_RETENTION : 0);
|
||||
}
|
||||
if (iax->x_mask & SCOUTFS_IOC_IAX_PROJECT_ID)
|
||||
scoutfs_inode_set_proj(inode, iax->project_id);
|
||||
|
||||
scoutfs_update_inode_item(inode, lock, &ind_locks);
|
||||
ret = 0;
|
||||
|
||||
@@ -672,6 +672,8 @@ retry:
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
scoutfs_inode_set_proj(inode, scoutfs_inode_get_proj(dir));
|
||||
|
||||
ret = scoutfs_dirty_inode_item(dir, *dir_lock);
|
||||
out:
|
||||
if (ret)
|
||||
|
||||
+10
-2
@@ -12,6 +12,7 @@
|
||||
#define SCOUTFS_FORMAT_VERSION_MAX_STR __stringify(SCOUTFS_FORMAT_VERSION_MAX)
|
||||
|
||||
#define SCOUTFS_FORMAT_VERSION_FEAT_RETENTION 2
|
||||
#define SCOUTFS_FORMAT_VERSION_FEAT_PROJECT_ID 2
|
||||
|
||||
/* statfs(2) f_type */
|
||||
#define SCOUTFS_SUPER_MAGIC 0x554f4353 /* "SCOU" */
|
||||
@@ -861,8 +862,11 @@ struct scoutfs_inode {
|
||||
struct scoutfs_timespec ctime;
|
||||
struct scoutfs_timespec mtime;
|
||||
struct scoutfs_timespec crtime;
|
||||
__le64 proj;
|
||||
};
|
||||
|
||||
#define SCOUTFS_INODE_FMT_V1_BYTES offsetof(struct scoutfs_inode, proj)
|
||||
|
||||
/*
|
||||
* There are so few versions that we don't mind doing this work inline
|
||||
* so that both utils and kernel can share these. Mounting has already
|
||||
@@ -872,7 +876,10 @@ struct scoutfs_inode {
|
||||
/* Returns the native written inode size for the given format version, 0 for bad version */
|
||||
static inline int scoutfs_inode_vers_bytes(__u64 fmt_vers)
|
||||
{
|
||||
return sizeof(struct scoutfs_inode);
|
||||
if (fmt_vers == 1)
|
||||
return SCOUTFS_INODE_FMT_V1_BYTES;
|
||||
else
|
||||
return sizeof(struct scoutfs_inode);
|
||||
}
|
||||
/*
|
||||
* Returns true if bytes is a valid inode size to read from the given
|
||||
@@ -881,7 +888,8 @@ static inline int scoutfs_inode_vers_bytes(__u64 fmt_vers)
|
||||
*/
|
||||
static inline int scoutfs_inode_valid_vers_bytes(__u64 fmt_vers, int bytes)
|
||||
{
|
||||
return bytes == sizeof(struct scoutfs_inode);
|
||||
return (bytes == sizeof(struct scoutfs_inode) && fmt_vers == SCOUTFS_FORMAT_VERSION_MAX) ||
|
||||
(bytes == SCOUTFS_INODE_FMT_V1_BYTES);
|
||||
}
|
||||
|
||||
#define SCOUTFS_INO_FLAG_TRUNCATE 0x1
|
||||
|
||||
@@ -278,6 +278,7 @@ static void load_inode(struct inode *inode, struct scoutfs_inode *cinode, int in
|
||||
si->flags = le32_to_cpu(cinode->flags);
|
||||
si->crtime.tv_sec = le64_to_cpu(cinode->crtime.sec);
|
||||
si->crtime.tv_nsec = le32_to_cpu(cinode->crtime.nsec);
|
||||
si->proj = le64_to_cpu(cinode->proj);
|
||||
|
||||
/*
|
||||
* i_blocks is initialized from online and offline and is then
|
||||
@@ -734,6 +735,29 @@ void scoutfs_inode_set_flags(struct inode *inode, u32 and, u32 or)
|
||||
write_sequnlock(&si->seqlock);
|
||||
}
|
||||
|
||||
u64 scoutfs_inode_get_proj(struct inode *inode)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
unsigned seq;
|
||||
u64 proj;
|
||||
|
||||
do {
|
||||
seq = read_seqbegin(&si->seqlock);
|
||||
proj = si->proj;
|
||||
} while (read_seqretry(&si->seqlock, seq));
|
||||
|
||||
return proj;
|
||||
}
|
||||
|
||||
void scoutfs_inode_set_proj(struct inode *inode, u64 proj)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
|
||||
write_seqlock(&si->seqlock);
|
||||
si->proj = proj;
|
||||
write_sequnlock(&si->seqlock);
|
||||
}
|
||||
|
||||
static int scoutfs_iget_test(struct inode *inode, void *arg)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
@@ -879,6 +903,7 @@ static void store_inode(struct scoutfs_inode *cinode, struct inode *inode, int i
|
||||
cinode->crtime.sec = cpu_to_le64(si->crtime.tv_sec);
|
||||
cinode->crtime.nsec = cpu_to_le32(si->crtime.tv_nsec);
|
||||
memset(cinode->crtime.__pad, 0, sizeof(cinode->crtime.__pad));
|
||||
cinode->proj = cpu_to_le64(si->proj);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1527,6 +1552,7 @@ int scoutfs_new_inode(struct super_block *sb, struct inode *dir, umode_t mode, d
|
||||
si->offline_blocks = 0;
|
||||
si->next_readdir_pos = SCOUTFS_DIRENT_FIRST_POS;
|
||||
si->next_xattr_id = 0;
|
||||
si->proj = 0;
|
||||
si->have_item = false;
|
||||
atomic64_set(&si->last_refreshed, lock->refresh_gen);
|
||||
scoutfs_lock_add_coverage(sb, lock, &si->ino_lock_cov);
|
||||
|
||||
@@ -21,6 +21,7 @@ struct scoutfs_inode_info {
|
||||
u64 data_version;
|
||||
u64 online_blocks;
|
||||
u64 offline_blocks;
|
||||
u64 proj;
|
||||
u32 flags;
|
||||
struct kc_timespec crtime;
|
||||
|
||||
@@ -122,6 +123,9 @@ u64 scoutfs_inode_data_version(struct inode *inode);
|
||||
void scoutfs_inode_get_onoff(struct inode *inode, s64 *on, s64 *off);
|
||||
u32 scoutfs_inode_get_flags(struct inode *inode);
|
||||
void scoutfs_inode_set_flags(struct inode *inode, u32 and, u32 or);
|
||||
u64 scoutfs_inode_get_proj(struct inode *inode);
|
||||
void scoutfs_inode_set_proj(struct inode *inode, u64 proj);
|
||||
|
||||
int scoutfs_complete_truncate(struct inode *inode, struct scoutfs_lock *lock);
|
||||
|
||||
int scoutfs_inode_check_retention(struct inode *inode);
|
||||
|
||||
+3
-1
@@ -687,6 +687,7 @@ struct scoutfs_ioctl_inode_attr_x {
|
||||
__u64 crtime_sec;
|
||||
__u64 size;
|
||||
__u64 bits;
|
||||
__u64 project_id;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -736,11 +737,12 @@ struct scoutfs_ioctl_inode_attr_x {
|
||||
#define SCOUTFS_IOC_IAX_CRTIME (1ULL << 6)
|
||||
#define SCOUTFS_IOC_IAX_SIZE (1ULL << 7)
|
||||
#define SCOUTFS_IOC_IAX_RETENTION (1ULL << 8)
|
||||
#define SCOUTFS_IOC_IAX_PROJECT_ID (1ULL << 9)
|
||||
|
||||
/* single bit attributes that are packed in the bits field as _B_ */
|
||||
#define SCOUTFS_IOC_IAX__BITS (SCOUTFS_IOC_IAX_RETENTION)
|
||||
/* inverse of all the bits we understand */
|
||||
#define SCOUTFS_IOC_IAX__UNKNOWN (U64_MAX << 9)
|
||||
#define SCOUTFS_IOC_IAX__UNKNOWN (U64_MAX << 10)
|
||||
|
||||
#define SCOUTFS_IOC_GET_ATTR_X \
|
||||
_IOW(SCOUTFS_IOCTL_MAGIC, 18, struct scoutfs_ioctl_inode_attr_x)
|
||||
|
||||
+15
-1
@@ -312,6 +312,19 @@ with sufficient priveledges to remove the retention restrictions on
|
||||
other modifications.
|
||||
.RE
|
||||
|
||||
.SH PROJECT IDs
|
||||
All inodes have a project ID attribute that can be set via the
|
||||
SET_ATTR_X ioctl and displayed with the GET_ATTR_X ioctl. Project IDs
|
||||
are an unsigned 64bit value and the value of 0 is reserved to indicate
|
||||
that no project ID is assigned. If a project ID is set on a directory
|
||||
then all inodes created with it as the initial parent inheret that ID,
|
||||
for all file types. This includes files initially unlinked from the
|
||||
namespace when created with O_TMPFILE. Project IDs are only
|
||||
automatically inherited from the parent dir on initial creation.
|
||||
They're not changed as directory entry linkes to the inode are created
|
||||
or renamed.
|
||||
.RE
|
||||
|
||||
.SH FORMAT VERSION
|
||||
The format version defines the layout and use of structures stored on
|
||||
devices and passed over the network. The version is incremented for
|
||||
@@ -399,7 +412,8 @@ The defined format versions are:
|
||||
Initial format version.
|
||||
.TP
|
||||
.B 2
|
||||
Added retention mode by setting the retention attribute.
|
||||
Added retention mode by setting the retention attribute. Added the
|
||||
project ID inode attribute.
|
||||
.RE
|
||||
|
||||
.SH CORRUPTION DETECTION
|
||||
|
||||
@@ -82,6 +82,7 @@ static int do_attr_x(struct attr_x_args *args)
|
||||
pr(iax, CRTIME, "crtime", "%llu.%u", iax->crtime_sec, iax->crtime_nsec);
|
||||
pr(iax, SIZE, "size", "%llu", iax->size);
|
||||
prb(iax, RETENTION, "retention");
|
||||
pr(iax, PROJECT_ID, "project_id", "%llu", iax->project_id);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
@@ -191,6 +192,14 @@ static int parse_opt(int key, char *arg, struct argp_state *state)
|
||||
args->iax.bits |= SCOUTFS_IOC_IAX_B_RETENTION;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
args->iax.x_mask |= SCOUTFS_IOC_IAX_PROJECT_ID;
|
||||
if (arg) {
|
||||
ret = parse_u64(arg, &args->iax.project_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (!args->filename)
|
||||
args->filename = strdup_or_error(state, arg);
|
||||
@@ -222,6 +231,7 @@ static struct argp_option set_options[] = {
|
||||
{ "crtime", 'r', "SECS.NSECS", 0, "ScoutFS creation time"},
|
||||
{ "size", 's', "SIZE", 0, "Inode i_size field"},
|
||||
{ "retention", 't', "0|1", 0, "Retention flag"},
|
||||
{ "project_id", 'p', "PROJECT_ID", 0, "Project ID"},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
+2
-1
@@ -49,7 +49,7 @@ static void print_inode(struct scoutfs_key *key, void *val, int val_len)
|
||||
{
|
||||
struct scoutfs_inode *inode = val;
|
||||
|
||||
printf(" inode: ino %llu size %llu version %llu nlink %u\n"
|
||||
printf(" inode: ino %llu size %llu version %llu proj %llu nlink %u\n"
|
||||
" uid %u gid %u mode 0%o rdev 0x%x flags 0x%x\n"
|
||||
" next_readdir_pos %llu meta_seq %llu data_seq %llu data_version %llu\n"
|
||||
" atime %llu.%08u ctime %llu.%08u\n"
|
||||
@@ -57,6 +57,7 @@ static void print_inode(struct scoutfs_key *key, void *val, int val_len)
|
||||
le64_to_cpu(key->ski_ino),
|
||||
le64_to_cpu(inode->size),
|
||||
le64_to_cpu(inode->version),
|
||||
le64_to_cpu(inode->proj),
|
||||
le32_to_cpu(inode->nlink), le32_to_cpu(inode->uid),
|
||||
le32_to_cpu(inode->gid), le32_to_cpu(inode->mode),
|
||||
le32_to_cpu(inode->rdev),
|
||||
|
||||
Reference in New Issue
Block a user