Add inode retention bit

Add a bit to the private scoutfs inode flags which indicates that the
inode is in retention mode.  The bit is visible through the _attr_x
interface.  It can only be set on regular files and when set it prevents
modification to all but non-user xattrs.  It can be cleared by root.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2024-06-28 15:09:05 -07:00
parent 5a53e7144d
commit fb5331a1d9
11 changed files with 142 additions and 2 deletions
+18
View File
@@ -295,6 +295,23 @@ with the
ioctl.
.RE
.SH FILE RETENTION MODE
A file can be set to retention mode by setting the
.IB RETENTION
attribute with the
.IB SET_ATTR_X
ioctl. This flag can only be set on regular files and requires root
permission (the
.IB CAP_SYS_ADMIN
capability).
.sp
Once in retention mode all modifications of the file will fail. The
only exceptions are that system extended attributes (all those without
the "user." prefix) may be modified. The retention bit may be cleared
with sufficient priveledges to remove the retention restrictions on
other modifications.
.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
@@ -382,6 +399,7 @@ The defined format versions are:
Initial format version.
.TP
.B 2
Added retention mode by setting the retention attribute.
.RE
.SH CORRUPTION DETECTION
+13
View File
@@ -81,6 +81,7 @@ static int do_attr_x(struct attr_x_args *args)
pr(iax, CTIME, "ctime", "%llu.%u", iax->ctime_sec, iax->ctime_nsec);
pr(iax, CRTIME, "crtime", "%llu.%u", iax->crtime_sec, iax->crtime_nsec);
pr(iax, SIZE, "size", "%llu", iax->size);
prb(iax, RETENTION, "retention");
}
ret = 0;
@@ -107,6 +108,7 @@ static int parse_opt(int key, char *arg, struct argp_state *state)
struct attr_x_args *args = state->input;
struct timespec ts;
int ret;
u64 x;
switch (key) {
case 'm':
@@ -179,6 +181,16 @@ static int parse_opt(int key, char *arg, struct argp_state *state)
return ret;
}
break;
case 't':
args->iax.x_mask |= SCOUTFS_IOC_IAX_RETENTION;
if (arg) {
ret = parse_u64(arg, &x);
if (ret)
return ret;
if (x)
args->iax.bits |= SCOUTFS_IOC_IAX_B_RETENTION;
}
break;
case ARGP_KEY_ARG:
if (!args->filename)
args->filename = strdup_or_error(state, arg);
@@ -209,6 +221,7 @@ static struct argp_option set_options[] = {
{ "ctime", 'c', "SECS.NSECS", 0, "Inode change time (posix ctime)"},
{ "crtime", 'r', "SECS.NSECS", 0, "ScoutFS creation time"},
{ "size", 's', "SIZE", 0, "Inode i_size field"},
{ "retention", 't', "0|1", 0, "Retention flag"},
{ NULL }
};