| From foo@baz Mon Dec 18 15:03:25 CET 2017 |
| From: Marc Dionne <marc.dionne@auristor.com> |
| Date: Thu, 16 Mar 2017 16:27:47 +0000 |
| Subject: afs: Populate and use client modification time |
| |
| From: Marc Dionne <marc.dionne@auristor.com> |
| |
| |
| [ Upstream commit ab94f5d0dd6fd82e7eeca5e7c8096eaea0a0261f ] |
| |
| The inode timestamps should be set from the client time |
| in the status received from the server, rather than the |
| server time which is meant for internal server use. |
| |
| Set AFS_SET_MTIME and populate the mtime for operations |
| that take an input status, such as file/dir creation |
| and StoreData. If an input time is not provided the |
| server will set the vnode times based on the current server |
| time. |
| |
| In a situation where the server has some skew with the |
| client, this could lead to the client seeing a timestamp |
| in the future for a file that it just created or wrote. |
| |
| Signed-off-by: Marc Dionne <marc.dionne@auristor.com> |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/afs/fsclient.c | 18 +++++++++--------- |
| fs/afs/inode.c | 2 +- |
| 2 files changed, 10 insertions(+), 10 deletions(-) |
| |
| --- a/fs/afs/fsclient.c |
| +++ b/fs/afs/fsclient.c |
| @@ -105,7 +105,7 @@ static void xdr_decode_AFSFetchStatus(co |
| vnode->vfs_inode.i_mode = mode; |
| } |
| |
| - vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server; |
| + vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client; |
| vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; |
| vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; |
| vnode->vfs_inode.i_version = data_version; |
| @@ -703,8 +703,8 @@ int afs_fs_create(struct afs_server *ser |
| memset(bp, 0, padsz); |
| bp = (void *) bp + padsz; |
| } |
| - *bp++ = htonl(AFS_SET_MODE); |
| - *bp++ = 0; /* mtime */ |
| + *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); |
| + *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
| *bp++ = 0; /* owner */ |
| *bp++ = 0; /* group */ |
| *bp++ = htonl(mode & S_IALLUGO); /* unix mode */ |
| @@ -981,8 +981,8 @@ int afs_fs_symlink(struct afs_server *se |
| memset(bp, 0, c_padsz); |
| bp = (void *) bp + c_padsz; |
| } |
| - *bp++ = htonl(AFS_SET_MODE); |
| - *bp++ = 0; /* mtime */ |
| + *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); |
| + *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
| *bp++ = 0; /* owner */ |
| *bp++ = 0; /* group */ |
| *bp++ = htonl(S_IRWXUGO); /* unix mode */ |
| @@ -1192,8 +1192,8 @@ static int afs_fs_store_data64(struct af |
| *bp++ = htonl(vnode->fid.vnode); |
| *bp++ = htonl(vnode->fid.unique); |
| |
| - *bp++ = 0; /* mask */ |
| - *bp++ = 0; /* mtime */ |
| + *bp++ = htonl(AFS_SET_MTIME); /* mask */ |
| + *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
| *bp++ = 0; /* owner */ |
| *bp++ = 0; /* group */ |
| *bp++ = 0; /* unix mode */ |
| @@ -1269,8 +1269,8 @@ int afs_fs_store_data(struct afs_server |
| *bp++ = htonl(vnode->fid.vnode); |
| *bp++ = htonl(vnode->fid.unique); |
| |
| - *bp++ = 0; /* mask */ |
| - *bp++ = 0; /* mtime */ |
| + *bp++ = htonl(AFS_SET_MTIME); /* mask */ |
| + *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
| *bp++ = 0; /* owner */ |
| *bp++ = 0; /* group */ |
| *bp++ = 0; /* unix mode */ |
| --- a/fs/afs/inode.c |
| +++ b/fs/afs/inode.c |
| @@ -71,7 +71,7 @@ static int afs_inode_map_status(struct a |
| inode->i_uid = vnode->status.owner; |
| inode->i_gid = vnode->status.group; |
| inode->i_size = vnode->status.size; |
| - inode->i_ctime.tv_sec = vnode->status.mtime_server; |
| + inode->i_ctime.tv_sec = vnode->status.mtime_client; |
| inode->i_ctime.tv_nsec = 0; |
| inode->i_atime = inode->i_mtime = inode->i_ctime; |
| inode->i_blocks = 0; |