.B lfs find \fR<\fIdirectory\fR|\fIfilename \fR...>
[[\fB!\fR] \fB--atime\fR|\fB-A\fR [\fB-+\fR]\fIn[smhdwy]\fR]
[[\fB!\fR] \fB--blocks\fR|\fB-b\fR [\fB+-\fR]\fIn\fR]
+ [[\fB!\fR] \fB--btime\fR|\fB--Btime\fR|\fB-B\fR [\fB+-\fR]\fIn[smhdwy]\fR]
[[\fB!\fR] \fB--ctime\fR|\fB-C\fR [\fB+-\fR]\fIn[smhdwy]\fR]
[[\fB!\fR] \fB--component-count|\fB--comp-count\fR [\fB+-\fR]\fIn\fR]
[[\fB!\fR] \fB--component-end|\fB--comp-end\fR|\fB-E\fR [\fB+-\fR]\fIn\fR[\fBKMGTPE\fR]]
\fIn\fR 512-byte \fBb\fRlocks, or \fBK\fRibi-, \fBM\fRebi-, \fBG\fRibi-,
\fBT\fRebi-, \fBP\fRebi-, or \fBE\fRbi-bytes if that suffix is given.
.TP
+.BR --btime | --Btime | -B
+File was created \fIn\fR*24 hours ago, see
+--atime
+for full details and options.
+.TP
.BR --ctime | -C
File's status was last changed \fIn\fR*24 hours ago, see
--atime
ll
llw(2i).
a The access time of the file \fIreference\fR
+b|B The birth time of the file \fIreference\fR
c The inode status change time of \fIreference\fR
m The modification time of the file \fIreference\fR
t \fIreference\fR is interpreted directly as a time
being "today", and "@%s" or "%s" the seconds since the Unix epoch (see
.BR strftime (3)
for details of the time formats). Otherwise, it will report an error.
-
+If you try to use the birth time of a reference file, and the birth
+time cannot be determined, a fatal error message results. If you
+specify a test which refers to the birth time of files being examined,
+this test will fail for any files where the birth time is unknown.
.TP
.BR --ost | -O
File has an object on the specified OST(s). The OST names can be specified
*
* \see enum la_valid
*/
- __u64 la_valid;
+ __u64 la_valid;
/** size in bytes */
- __u64 la_size;
+ __u64 la_size;
/** modification time in seconds since Epoch */
s64 la_mtime;
/** access time in seconds since Epoch */
s64 la_atime;
/** change time in seconds since Epoch */
s64 la_ctime;
+ /** create time in seconds since Epoch */
+ s64 la_btime;
/** 512-byte blocks allocated to object */
- __u64 la_blocks;
+ __u64 la_blocks;
/** permission bits and file type */
- __u32 la_mode;
+ __u32 la_mode;
/** owner id */
- __u32 la_uid;
+ __u32 la_uid;
/** group id */
- __u32 la_gid;
+ __u32 la_gid;
/** object flags */
- __u32 la_flags;
+ __u32 la_flags;
/** number of persistent references to this object */
- __u32 la_nlink;
+ __u32 la_nlink;
/** blk bits of the object*/
- __u32 la_blkbits;
+ __u32 la_blkbits;
/** blk size of the object*/
- __u32 la_blksize;
+ __u32 la_blksize;
/** real device */
- __u32 la_rdev;
+ __u32 la_rdev;
/** project id */
- __u32 la_projid;
+ __u32 la_projid;
/** set layout version to OST objects. */
__u32 la_layout_version;
};
NEWERXY_ATIME = 0, /* neweraY */
NEWERXY_MTIME = 1, /* newermY */
NEWERXY_CTIME = 2, /* newercY */
+ NEWERXY_BTIME = 3, /* newerbY | newerBY */
NEWERXY_MAX,
};
time_t fp_atime;
time_t fp_mtime;
time_t fp_ctime;
- /* {a,m,c}sign cannot be bitfields due to using pointers to
+ /* {a,m,c,b}sign cannot be bitfields due to using pointers to
* access them during argument parsing. */
int fp_asign;
int fp_msign;
fp_exclude_ext_size:1,
fp_lazy:1,
fp_newerxy:1,
- fp_unused_bit2:1, /* All of these unused bit */
- fp_unused_bit3:1, /* fields available to use.*/
- fp_unused_bit4:1, /* Once all unused fields */
- fp_unused_bit5:1, /* are used we need to add */
- fp_unused_bit6:1, /* a separate flag field at*/
- fp_unused_bit7:1; /* the end of the struct. */
+ fp_exclude_btime:1,
+ fp_unused_bit3:1, /* All of these unused bit */
+ fp_unused_bit4:1, /* fields available to use.*/
+ fp_unused_bit5:1, /* Once all unused fields */
+ fp_unused_bit6:1, /* are used we need to add */
+ fp_unused_bit7:1; /* a separate flag field at*/
+ /* the end of the struct. */
enum llapi_layout_verbose fp_verbose;
int fp_quiet;
* fp_newery[NEWERXY_MAX][1]: ! -- newerXY reference
*/
time_t fp_newery[NEWERXY_MAX][2];
+
+ time_t fp_btime;
+ int fp_bsign;
};
int llapi_ostlist(char *path, struct find_param *param);
#define OBD_MD_FLLAZYSIZE (0x0400000000000000ULL) /* Lazy size */
#define OBD_MD_FLLAZYBLOCKS (0x0800000000000000ULL) /* Lazy blocks */
+#define OBD_MD_FLBTIME (0x1000000000000000ULL) /* birth time */
+
#define OBD_MD_FLALLQUOTA (OBD_MD_FLUSRQUOTA | \
OBD_MD_FLGRPQUOTA | \
OBD_MD_FLPRJQUOTA)
OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \
OBD_MD_FLGID | OBD_MD_FLFLAGS | OBD_MD_FLNLINK | \
OBD_MD_FLPARENT | OBD_MD_FLRDEV | OBD_MD_FLGROUP | \
- OBD_MD_FLPROJID)
+ OBD_MD_FLPROJID | OBD_MD_FLBTIME)
#define OBD_MD_FLXATTRALL (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS)
__u32 mbo_projid;
__u64 mbo_dom_size; /* size of DOM component */
__u64 mbo_dom_blocks; /* blocks consumed by DOM component */
- __u64 mbo_padding_8; /* also fix lustre_swab_mdt_body */
- __u64 mbo_padding_9;
+ __u64 mbo_btime;
+ __u64 mbo_padding_9; /* also fix lustre_swab_mdt_body */
__u64 mbo_padding_10;
}; /* 216 */
LA_LAYOUT_VERSION = 1 << 16, /* 0x10000 */
LA_LSIZE = 1 << 17, /* 0x20000 */
LA_LBLOCKS = 1 << 18, /* 0x40000 */
+ LA_BTIME = 1 << 19, /* 0x80000 */
/**
* Attributes must be transmitted to OST objects
*/
stx.stx_atime.tv_sec = body->mbo_atime;
stx.stx_ctime.tv_sec = body->mbo_ctime;
stx.stx_mtime.tv_sec = body->mbo_mtime;
+ stx.stx_btime.tv_sec = body->mbo_btime;
stx.stx_rdev_major = MAJOR(body->mbo_rdev);
stx.stx_rdev_minor = MINOR(body->mbo_rdev);
stx.stx_dev_major = MAJOR(inode->i_sb->s_dev);
stx.stx_dev_minor = MINOR(inode->i_sb->s_dev);
- stx.stx_mask |= STATX_BASIC_STATS;
+ stx.stx_mask |= STATX_BASIC_STATS | STATX_BTIME;
/*
* For a striped directory, the size and blocks returned
b->mbo_ctime = attr->la_ctime;
b->mbo_valid |= OBD_MD_FLCTIME;
}
+ if (attr->la_valid & LA_BTIME) {
+ b->mbo_btime = attr->la_btime;
+ b->mbo_valid |= OBD_MD_FLBTIME;
+ }
if (attr->la_valid & LA_FLAGS) {
b->mbo_flags = attr->la_flags;
b->mbo_valid |= OBD_MD_FLFLAGS;
attr->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE |
LA_SIZE | LA_BLOCKS | LA_UID | LA_GID |
LA_PROJID | LA_FLAGS | LA_NLINK | LA_RDEV |
- LA_BLKSIZE | LA_TYPE;
+ LA_BLKSIZE | LA_TYPE | LA_BTIME;
attr->la_atime = inode->i_atime.tv_sec;
attr->la_mtime = inode->i_mtime.tv_sec;
attr->la_ctime = inode->i_ctime.tv_sec;
+ attr->la_btime = LDISKFS_I(inode)->i_crtime.tv_sec;
attr->la_mode = inode->i_mode;
attr->la_size = i_size_read(inode);
attr->la_blocks = inode->i_blocks;
uint64_t atime[2];
uint64_t mtime[2];
uint64_t ctime[2];
+ uint64_t btime[2];
};
LASSERT(obj->oo_dn != NULL);
- la->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE | LA_TYPE |
- LA_SIZE | LA_UID | LA_GID | LA_FLAGS | LA_NLINK;
+ la->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_BTIME | LA_MODE |
+ LA_TYPE | LA_SIZE | LA_UID | LA_GID | LA_FLAGS |
+ LA_NLINK;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(o), NULL, osa->atime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(o), NULL, osa->mtime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(o), NULL, osa->ctime, 16);
+ SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CRTIME(o), NULL, osa->btime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MODE(o), NULL, &osa->mode, 8);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_SIZE(o), NULL, &osa->size, 8);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(o), NULL, &osa->nlink, 8);
la->la_atime = osa->atime[0];
la->la_mtime = osa->mtime[0];
la->la_ctime = osa->ctime[0];
+ la->la_btime = osa->btime[0];
la->la_mode = osa->mode;
la->la_uid = osa->uid;
la->la_gid = osa->gid;
sa_bulk_attr_t *bulk = osd_oti_get(env)->oti_attr_bulk;
struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
uint64_t gen;
- uint64_t crtime[2];
inode_timespec_t now;
int cnt;
int rc;
gen = dmu_tx_get_txg(tx);
gethrestime(&now);
- ZFS_TIME_ENCODE(&now, crtime);
+ ZFS_TIME_ENCODE(&now, osa->btime);
osa->atime[0] = la->la_atime;
osa->ctime[0] = la->la_ctime;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(osd), NULL, osa->atime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(osd), NULL, osa->mtime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(osd), NULL, osa->ctime, 16);
- SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CRTIME(osd), NULL, crtime, 16);
+ SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CRTIME(osd), NULL, osa->btime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(osd), NULL, &osa->nlink, 8);
#ifdef ZFS_PROJINHERIT
if (osd->od_projectused_dn)
struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
struct lu_buf *lb = &osd_oti_get(env)->oti_xattr_lbuf;
struct osd_device *osd = osd_obj2dev(obj);
- uint64_t crtime[2], gen;
+ uint64_t gen;
inode_timespec_t now;
size_t size;
int rc, cnt;
gen = dmu_tx_get_txg(oh->ot_tx);
gethrestime(&now);
- ZFS_TIME_ENCODE(&now, crtime);
+ ZFS_TIME_ENCODE(&now, osa->btime);
+ obj->oo_attr.la_valid |= LA_BTIME;
+ obj->oo_attr.la_btime = osa->btime[0];
osa->atime[0] = obj->oo_attr.la_atime;
osa->ctime[0] = obj->oo_attr.la_ctime;
osa->mtime[0] = obj->oo_attr.la_mtime;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(osd), NULL, osa->atime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(osd), NULL, osa->mtime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(osd), NULL, osa->ctime, 16);
- SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CRTIME(osd), NULL, crtime, 16);
+ SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CRTIME(osd), NULL, osa->btime, 16);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(osd), NULL, &osa->nlink, 8);
#ifdef ZFS_PROJINHERIT
if (osd->od_projectused_dn)
__swab32s(&b->mbo_projid);
__swab64s(&b->mbo_dom_size);
__swab64s(&b->mbo_dom_blocks);
- BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_8) == 0);
+ __swab64s(&b->mbo_btime);
BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_9) == 0);
BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_10) == 0);
}
(long long)(int)offsetof(struct mdt_body, mbo_dom_blocks));
LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_dom_blocks) == 8, "found %lld\n",
(long long)(int)sizeof(((struct mdt_body *)0)->mbo_dom_blocks));
- LASSERTF((int)offsetof(struct mdt_body, mbo_padding_8) == 192, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, mbo_padding_8));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_8) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_8));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_btime) == 192, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_btime));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_btime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_btime));
LASSERTF((int)offsetof(struct mdt_body, mbo_padding_9) == 200, "found %lld\n",
(long long)(int)offsetof(struct mdt_body, mbo_padding_9));
LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_9) == 8, "found %lld\n",
local negref
if [ $y == "t" ]; then
- ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
+ if [ $x == "b" ]; then
+ ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
+ else
+ ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
+ fi
else
- ref=$DIR/$tfile.newer
+ ref=$DIR/$tfile.newer.$x$y
touch $ref || error "touch $ref failed"
fi
sleep 2
setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
sleep 2
if [ $y == "t" ]; then
- negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
+ if [ $x == "b" ]; then
+ negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
+ else
+ negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
+ fi
else
- negref=$DIR/$tfile.newerneg
+ negref=$DIR/$tfile.negnewer.$x$y
touch $negref || error "touch $negref failed"
fi
}
test_56oc() {
+ test_newerXY_base "b" "t"
test_newerXY_base "a" "a"
test_newerXY_base "a" "m"
test_newerXY_base "a" "c"
test_newerXY_base "c" "a"
test_newerXY_base "c" "m"
test_newerXY_base "c" "c"
+ test_newerXY_base "b" "b"
test_newerXY_base "a" "t"
test_newerXY_base "m" "t"
test_newerXY_base "c" "t"
+ test_newerXY_base "b" "t"
}
run_test 56oc "check lfs find -newerXY work"
+btime_supported() {
+ local dir=$DIR/$tdir
+ local rc
+
+ mkdir -p $dir
+ touch $dir/$tfile
+ $LFS find $dir -btime -1d -type f
+ rc=$?
+ rm -rf $dir
+ return $rc
+}
+
+test_56od() {
+ [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
+ ! btime_supported && skip "btime unsupported on MDS"
+
+ [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
+ ! btime_supported && skip "btime unsupported on clients"
+
+ local dir=$DIR/$tdir
+ local ref=$DIR/$tfile.ref
+ local negref=$DIR/$tfile.negref
+
+ mkdir $dir || error "mkdir $dir failed"
+ touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
+ touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
+ mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
+ mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
+ touch $ref || error "touch $ref failed"
+ # sleep 3 seconds at least
+ sleep 3
+
+ local before=$(do_facet mds1 date +%s)
+ local skew=$(($(date +%s) - before + 1))
+
+ if (( skew < 0 && skew > -5 )); then
+ sleep $((0 - skew + 1))
+ skew=0
+ fi
+
+ # Set the dir stripe params to limit files all on MDT0,
+ # otherwise we need to calc the max clock skew between
+ # the client and MDTs.
+ setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
+ sleep 2
+ touch $negref || error "touch $negref failed"
+
+ local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
+ local nums=$($cmd | wc -l)
+ local expected=$(((NUMFILES + 1) * NUMDIRS))
+
+ [ $nums -eq $expected ] ||
+ error "'$cmd' wrong: found $nums, expected $expected"
+
+ cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
+ nums=$($cmd | wc -l)
+ expected=$((NUMFILES + 1))
+ [ $nums -eq $expected ] ||
+ error "'$cmd' wrong: found $nums, expected $expected"
+
+ [ $skew -lt 0 ] && return
+
+ local after=$(do_facet mds1 date +%s)
+ local age=$((after - before + 1 + skew))
+
+ cmd="$LFS find $dir -btime -${age}s -type f"
+ nums=$($cmd | wc -l)
+ expected=$(((NUMFILES + 1) * NUMDIRS))
+
+ echo "Clock skew between client and server: $skew, age:$age"
+ [ $nums -eq $expected ] ||
+ error "'$cmd' wrong: found $nums, expected $expected"
+
+ expected=$(($NUMDIRS + 1))
+ cmd="$LFS find $dir -btime -${age}s -type d"
+ nums=$($cmd | wc -l)
+ [ $nums -eq $expected ] ||
+ error "'$cmd' wrong: found $nums, expected $expected"
+ rm -f $ref $negref || error "Failed to remove $ref $negref"
+}
+run_test 56od "check lfs find -btime with units"
+
test_56p() {
[ $RUNAS_ID -eq $UID ] &&
skip_env "RUNAS_ID = UID = $UID -- skipping"
"find files matching given attributes recursively in directory tree.\n"
"usage: find <directory|filename> ...\n"
" [[!] --atime|-A [+-]N[smhdwy]] [[!] --ctime|-C [+-]N[smhdwy]]\n"
- " [[!] --mtime|-M [+-]N[smhdwy]] [[!] --blocks|-b N]\n"
- " [[!] --newer[XY] <reference>]\n"
+ " [[!] --mtime|-M [+-]N[smhdwy]]\n"
+ " [[!] --btime|--Btime|-B [+-]N[smhdwy]]\n"
+ " [[!] --newer[XY] <reference>] [[!] --blocks|-b N]\n"
" [--maxdepth|-D N] [[!] --mdt-index|--mdt|-m <uuid|index,...>]\n"
" [[!] --name|-n <pattern>] [[!] --ost|-O <uuid|index,...>]\n"
" [--print|-P] [--print0|-0] [[!] --size|-s [+-]N[bkMGTPE]]\n"
/* find { .val = 'A', .name = "atime", .has_arg = required_argument }*/
/* --block is only valid in migrate mode */
{ .val = 'b', .name = "block", .has_arg = no_argument },
+/* find { .val = 'B', .name = "btime", .has_arg = required_argument }*/
{ .val = LFS_COMP_ADD_OPT,
.name = "comp-add", .has_arg = no_argument },
{ .val = LFS_COMP_ADD_OPT,
struct option long_opts[] = {
{ .val = 'A', .name = "atime", .has_arg = required_argument },
{ .val = 'b', .name = "blocks", .has_arg = required_argument },
+ { .val = 'B', .name = "btime", .has_arg = required_argument },
+ { .val = 'B', .name = "Btime", .has_arg = required_argument },
{ .val = LFS_COMP_COUNT_OPT,
.name = "comp-count", .has_arg = required_argument },
{ .val = LFS_COMP_COUNT_OPT,
{ .val = LFS_NEWERXY_OPT,
.name = "newerac", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
+ .name = "newerab", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
.name = "newerma", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
.name = "newermm", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
.name = "newermc", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
+ .name = "newermb", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
.name = "newerca", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
.name = "newercm", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
.name = "newercc", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
+ .name = "newercb", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerba", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerbm", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerbc", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerbb", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerBa", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerBm", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerBc", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerBB", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
.name = "newerat", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
.name = "newermt", .has_arg = required_argument},
{ .val = LFS_NEWERXY_OPT,
.name = "newerct", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerbt", .has_arg = required_argument},
+ { .val = LFS_NEWERXY_OPT,
+ .name = "newerBt", .has_arg = required_argument},
{ .val = 'c', .name = "stripe-count", .has_arg = required_argument },
{ .val = 'c', .name = "stripe_count", .has_arg = required_argument },
{ .val = 'C', .name = "ctime", .has_arg = required_argument },
/* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */
while ((c = getopt_long_only(argc, argv,
- "-0A:b:c:C:D:E:g:G:H:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:vz:",
- long_opts, &optidx)) >= 0) {
+ "-0A:b:B:c:C:D:E:g:G:H:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:vz:",
+ long_opts, &optidx)) >= 0) {
xtime = NULL;
xsign = NULL;
if (neg_opt)
xtime = ¶m.fp_atime;
xsign = ¶m.fp_asign;
param.fp_exclude_atime = !!neg_opt;
+ /* no break, this falls through to 'B' for btime */
+ case 'B':
+ if (c == 'B') {
+ xtime = ¶m.fp_btime;
+ xsign = ¶m.fp_bsign;
+ param.fp_exclude_btime = !!neg_opt;
+ }
/* no break, this falls through to 'C' for ctime */
case 'C':
if (c == 'C') {
}
ref = mktime(&tm);
+ } else if (y == 'b' || y == 'B') {
+ lstatx_t stx;
+
+ rc = llapi_get_lum_file(optarg, NULL, &stx,
+ NULL, 0);
+ if (rc || !(stx.stx_mask & STATX_BTIME)) {
+ if (!(stx.stx_mask & STATX_BTIME))
+ ret = -EOPNOTSUPP;
+ else
+ ret = -errno;
+ fprintf(stderr,
+ "%s: get btime failed '%s': %s\n",
+ progname, optarg,
+ strerror(-ret));
+ goto err;
+ }
+
+ ref = stx.stx_btime.tv_sec;
} else {
struct stat statbuf;
case 'c':
xidx = NEWERXY_CTIME;
break;
+ case 'b':
+ case 'B':
+ xidx = NEWERXY_BTIME;
+ break;
default:
fprintf(stderr,
"%s: invalid X argument: '%c'\n",
struct option long_opts[] = {
/* find { .val = 'A', .name = "atime", .has_arg = required_argument }*/
/* find { .val = 'b', .name = "blocks", .has_arg = required_argument }*/
+/* find { .val = 'B', .name = "btime", .has_arg = required_argument }*/
+/* find { .val = 'B', .name = "Btime", .has_arg = required_argument }*/
{ .val = LFS_COMP_COUNT_OPT,
.name = "comp-count", .has_arg = no_argument },
{ .val = LFS_COMP_COUNT_OPT,
return rc;
}
-static int find_newerxy_check(struct find_param *param, int mds)
+static int find_newerxy_check(struct find_param *param, int mds, bool from_mdt)
{
struct lov_user_mds_data *lmd = param->fp_lmd;
int i;
if (rc == 1)
rc = rc2;
}
+
+ /*
+ * File birth time (btime) can get from MDT directly.
+ * if @from_mdt is true, it means the input file attributs are
+ * obtained directly from MDT.
+ * Thus, if @from_mdt is false, we should skip the following
+ * btime check.
+ */
+ if (!from_mdt)
+ continue;
+
+ if (param->fp_newery[NEWERXY_BTIME][i]) {
+ if (!(lmd->lmd_stx.stx_mask & STATX_BTIME))
+ return -EOPNOTSUPP;
+
+ rc2 = find_value_cmp(lmd->lmd_stx.stx_btime.tv_sec,
+ param->fp_newery[NEWERXY_BTIME][i],
+ -1, i, 0, 0);
+ if (rc2 < 0)
+ return rc2;
+ }
}
return rc;
/* Request MDS for the stat info if some of these parameters need
* to be compared. */
if (param->fp_obd_uuid || param->fp_mdt_uuid ||
- param->fp_check_uid || param->fp_check_gid || param->fp_newerxy ||
+ param->fp_check_uid || param->fp_check_gid ||
+ param->fp_newerxy || param->fp_btime ||
param->fp_atime || param->fp_mtime || param->fp_ctime ||
param->fp_check_size || param->fp_check_blocks ||
find_check_lmm_info(param) ||
goto decided;
}
+ if (param->fp_btime) {
+ if (!(lmd->lmd_stx.stx_mask & STATX_BTIME)) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ decision = find_value_cmp(lmd->lmd_stx.stx_btime.tv_sec,
+ param->fp_btime, param->fp_bsign,
+ param->fp_exclude_btime,
+ param->fp_time_margin, 0);
+ if (decision == -1)
+ goto decided;
+ }
+
if (param->fp_newerxy) {
int for_mds;
for_mds = lustre_fs ?
(S_ISREG(lmd->lmd_stx.stx_mode) && stripe_count) : 0;
- decision = find_newerxy_check(param, for_mds);
+ decision = find_newerxy_check(param, for_mds, true);
if (decision == -1)
goto decided;
+ if (decision < 0) {
+ ret = decision;
+ goto out;
+ }
}
flags = param->fp_lmd->lmd_flags;
goto decided;
if (param->fp_newerxy) {
- decision = find_newerxy_check(param, 0);
+ decision = find_newerxy_check(param, 0, false);
if (decision == -1)
goto decided;
-
+ if (decision < 0) {
+ ret = decision;
+ goto out;
+ }
}
}
if (rc)
return rc;
- *valid = lmd->lmd_flags;
+ if (valid)
+ *valid = lmd->lmd_flags;
+
if (statx)
memcpy(statx, &lmd->lmd_stx, sizeof(*statx));
(long long)(int)offsetof(struct mdt_body, mbo_dom_blocks));
LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_dom_blocks) == 8, "found %lld\n",
(long long)(int)sizeof(((struct mdt_body *)0)->mbo_dom_blocks));
- LASSERTF((int)offsetof(struct mdt_body, mbo_padding_8) == 192, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, mbo_padding_8));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_8) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_8));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_btime) == 192, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_btime));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_btime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_btime));
LASSERTF((int)offsetof(struct mdt_body, mbo_padding_9) == 200, "found %lld\n",
(long long)(int)offsetof(struct mdt_body, mbo_padding_9));
LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_9) == 8, "found %lld\n",