|
@@ -658,13 +658,10 @@ int ceph_fill_file_size(struct inode *inode, int issued,
|
|
|
}
|
|
|
|
|
|
void ceph_fill_file_time(struct inode *inode, int issued,
|
|
|
- u64 time_warp_seq, struct timespec *ctime,
|
|
|
- struct timespec *mtime, struct timespec *atime)
|
|
|
+ u64 time_warp_seq, struct timespec64 *ctime,
|
|
|
+ struct timespec64 *mtime, struct timespec64 *atime)
|
|
|
{
|
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
|
- struct timespec64 ctime64 = timespec_to_timespec64(*ctime);
|
|
|
- struct timespec64 mtime64 = timespec_to_timespec64(*mtime);
|
|
|
- struct timespec64 atime64 = timespec_to_timespec64(*atime);
|
|
|
int warn = 0;
|
|
|
|
|
|
if (issued & (CEPH_CAP_FILE_EXCL|
|
|
@@ -673,39 +670,39 @@ void ceph_fill_file_time(struct inode *inode, int issued,
|
|
|
CEPH_CAP_AUTH_EXCL|
|
|
|
CEPH_CAP_XATTR_EXCL)) {
|
|
|
if (ci->i_version == 0 ||
|
|
|
- timespec64_compare(&ctime64, &inode->i_ctime) > 0) {
|
|
|
+ timespec64_compare(ctime, &inode->i_ctime) > 0) {
|
|
|
dout("ctime %lld.%09ld -> %lld.%09ld inc w/ cap\n",
|
|
|
- (long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
|
|
|
- (long long)ctime->tv_sec, ctime->tv_nsec);
|
|
|
- inode->i_ctime = ctime64;
|
|
|
+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
|
|
|
+ ctime->tv_sec, ctime->tv_nsec);
|
|
|
+ inode->i_ctime = *ctime;
|
|
|
}
|
|
|
if (ci->i_version == 0 ||
|
|
|
ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
|
|
|
/* the MDS did a utimes() */
|
|
|
dout("mtime %lld.%09ld -> %lld.%09ld "
|
|
|
"tw %d -> %d\n",
|
|
|
- (long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
|
|
|
- (long long)mtime->tv_sec, mtime->tv_nsec,
|
|
|
+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
|
|
|
+ mtime->tv_sec, mtime->tv_nsec,
|
|
|
ci->i_time_warp_seq, (int)time_warp_seq);
|
|
|
|
|
|
- inode->i_mtime = mtime64;
|
|
|
- inode->i_atime = atime64;
|
|
|
+ inode->i_mtime = *mtime;
|
|
|
+ inode->i_atime = *atime;
|
|
|
ci->i_time_warp_seq = time_warp_seq;
|
|
|
} else if (time_warp_seq == ci->i_time_warp_seq) {
|
|
|
/* nobody did utimes(); take the max */
|
|
|
- if (timespec64_compare(&mtime64, &inode->i_mtime) > 0) {
|
|
|
+ if (timespec64_compare(mtime, &inode->i_mtime) > 0) {
|
|
|
dout("mtime %lld.%09ld -> %lld.%09ld inc\n",
|
|
|
- (long long)inode->i_mtime.tv_sec,
|
|
|
+ inode->i_mtime.tv_sec,
|
|
|
inode->i_mtime.tv_nsec,
|
|
|
- (long long)mtime->tv_sec, mtime->tv_nsec);
|
|
|
- inode->i_mtime = mtime64;
|
|
|
+ mtime->tv_sec, mtime->tv_nsec);
|
|
|
+ inode->i_mtime = *mtime;
|
|
|
}
|
|
|
- if (timespec64_compare(&atime64, &inode->i_atime) > 0) {
|
|
|
+ if (timespec64_compare(atime, &inode->i_atime) > 0) {
|
|
|
dout("atime %lld.%09ld -> %lld.%09ld inc\n",
|
|
|
- (long long)inode->i_atime.tv_sec,
|
|
|
+ inode->i_atime.tv_sec,
|
|
|
inode->i_atime.tv_nsec,
|
|
|
- (long long)atime->tv_sec, atime->tv_nsec);
|
|
|
- inode->i_atime = atime64;
|
|
|
+ atime->tv_sec, atime->tv_nsec);
|
|
|
+ inode->i_atime = *atime;
|
|
|
}
|
|
|
} else if (issued & CEPH_CAP_FILE_EXCL) {
|
|
|
/* we did a utimes(); ignore mds values */
|
|
@@ -715,9 +712,9 @@ void ceph_fill_file_time(struct inode *inode, int issued,
|
|
|
} else {
|
|
|
/* we have no write|excl caps; whatever the MDS says is true */
|
|
|
if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
|
|
|
- inode->i_ctime = ctime64;
|
|
|
- inode->i_mtime = mtime64;
|
|
|
- inode->i_atime = atime64;
|
|
|
+ inode->i_ctime = *ctime;
|
|
|
+ inode->i_mtime = *mtime;
|
|
|
+ inode->i_atime = *atime;
|
|
|
ci->i_time_warp_seq = time_warp_seq;
|
|
|
} else {
|
|
|
warn = 1;
|
|
@@ -743,7 +740,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
|
|
|
struct ceph_mds_reply_inode *info = iinfo->in;
|
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
|
int issued, new_issued, info_caps;
|
|
|
- struct timespec mtime, atime, ctime;
|
|
|
+ struct timespec64 mtime, atime, ctime;
|
|
|
struct ceph_buffer *xattr_blob = NULL;
|
|
|
struct ceph_string *pool_ns = NULL;
|
|
|
struct ceph_cap *new_cap = NULL;
|
|
@@ -823,9 +820,9 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
|
|
|
|
|
|
if (new_version || (new_issued & CEPH_CAP_ANY_RD)) {
|
|
|
/* be careful with mtime, atime, size */
|
|
|
- ceph_decode_timespec(&atime, &info->atime);
|
|
|
- ceph_decode_timespec(&mtime, &info->mtime);
|
|
|
- ceph_decode_timespec(&ctime, &info->ctime);
|
|
|
+ ceph_decode_timespec64(&atime, &info->atime);
|
|
|
+ ceph_decode_timespec64(&mtime, &info->mtime);
|
|
|
+ ceph_decode_timespec64(&ctime, &info->ctime);
|
|
|
ceph_fill_file_time(inode, issued,
|
|
|
le32_to_cpu(info->time_warp_seq),
|
|
|
&ctime, &mtime, &atime);
|
|
@@ -872,7 +869,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
|
|
|
ci->i_rbytes = le64_to_cpu(info->rbytes);
|
|
|
ci->i_rfiles = le64_to_cpu(info->rfiles);
|
|
|
ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
|
|
|
- ceph_decode_timespec(&ci->i_rctime, &info->rctime);
|
|
|
+ ceph_decode_timespec64(&ci->i_rctime, &info->rctime);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1954,7 +1951,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
int err = 0;
|
|
|
int inode_dirty_flags = 0;
|
|
|
bool lock_snap_rwsem = false;
|
|
|
- struct timespec ts;
|
|
|
|
|
|
prealloc_cf = ceph_alloc_cap_flush();
|
|
|
if (!prealloc_cf)
|
|
@@ -2030,8 +2026,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
|
|
|
if (ia_valid & ATTR_ATIME) {
|
|
|
dout("setattr %p atime %lld.%ld -> %lld.%ld\n", inode,
|
|
|
- (long long)inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
|
|
|
- (long long)attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
|
|
|
+ inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
|
|
|
+ attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
|
|
|
if (issued & CEPH_CAP_FILE_EXCL) {
|
|
|
ci->i_time_warp_seq++;
|
|
|
inode->i_atime = attr->ia_atime;
|
|
@@ -2043,8 +2039,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
dirtied |= CEPH_CAP_FILE_WR;
|
|
|
} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
|
|
|
!timespec64_equal(&inode->i_atime, &attr->ia_atime)) {
|
|
|
- ts = timespec64_to_timespec(attr->ia_atime);
|
|
|
- ceph_encode_timespec(&req->r_args.setattr.atime, &ts);
|
|
|
+ ceph_encode_timespec64(&req->r_args.setattr.atime,
|
|
|
+ &attr->ia_atime);
|
|
|
mask |= CEPH_SETATTR_ATIME;
|
|
|
release |= CEPH_CAP_FILE_SHARED |
|
|
|
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
|
|
@@ -2052,8 +2048,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
}
|
|
|
if (ia_valid & ATTR_MTIME) {
|
|
|
dout("setattr %p mtime %lld.%ld -> %lld.%ld\n", inode,
|
|
|
- (long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
|
|
|
- (long long)attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
|
|
|
+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
|
|
|
+ attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
|
|
|
if (issued & CEPH_CAP_FILE_EXCL) {
|
|
|
ci->i_time_warp_seq++;
|
|
|
inode->i_mtime = attr->ia_mtime;
|
|
@@ -2065,8 +2061,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
dirtied |= CEPH_CAP_FILE_WR;
|
|
|
} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
|
|
|
!timespec64_equal(&inode->i_mtime, &attr->ia_mtime)) {
|
|
|
- ts = timespec64_to_timespec(attr->ia_mtime);
|
|
|
- ceph_encode_timespec(&req->r_args.setattr.mtime, &ts);
|
|
|
+ ceph_encode_timespec64(&req->r_args.setattr.mtime,
|
|
|
+ &attr->ia_mtime);
|
|
|
mask |= CEPH_SETATTR_MTIME;
|
|
|
release |= CEPH_CAP_FILE_SHARED |
|
|
|
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
|
|
@@ -2097,8 +2093,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
|
|
|
ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
|
|
|
dout("setattr %p ctime %lld.%ld -> %lld.%ld (%s)\n", inode,
|
|
|
- (long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
|
|
|
- (long long)attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
|
|
|
+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
|
|
|
+ attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
|
|
|
only ? "ctime only" : "ignored");
|
|
|
if (only) {
|
|
|
/*
|
|
@@ -2140,7 +2136,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
req->r_inode_drop = release;
|
|
|
req->r_args.setattr.mask = cpu_to_le32(mask);
|
|
|
req->r_num_caps = 1;
|
|
|
- req->r_stamp = timespec64_to_timespec(attr->ia_ctime);
|
|
|
+ req->r_stamp = attr->ia_ctime;
|
|
|
err = ceph_mdsc_do_request(mdsc, NULL, req);
|
|
|
}
|
|
|
dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
|
|
@@ -2161,6 +2157,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|
|
int ceph_setattr(struct dentry *dentry, struct iattr *attr)
|
|
|
{
|
|
|
struct inode *inode = d_inode(dentry);
|
|
|
+ struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
|
|
|
int err;
|
|
|
|
|
|
if (ceph_snap(inode) != CEPH_NOSNAP)
|
|
@@ -2170,6 +2167,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
|
|
|
if (err != 0)
|
|
|
return err;
|
|
|
|
|
|
+ if ((attr->ia_valid & ATTR_SIZE) &&
|
|
|
+ attr->ia_size > max(inode->i_size, fsc->max_file_size))
|
|
|
+ return -EFBIG;
|
|
|
+
|
|
|
if ((attr->ia_valid & ATTR_SIZE) &&
|
|
|
ceph_quota_is_max_bytes_exceeded(inode, attr->ia_size))
|
|
|
return -EDQUOT;
|