|
@@ -71,6 +71,8 @@
|
|
|
|
|
|
#define NFSDBG_FACILITY NFSDBG_PROC
|
|
|
|
|
|
+#define NFS4_BITMASK_SZ 3
|
|
|
+
|
|
|
#define NFS4_POLL_RETRY_MIN (HZ/10)
|
|
|
#define NFS4_POLL_RETRY_MAX (15*HZ)
|
|
|
|
|
@@ -274,6 +276,33 @@ const u32 nfs4_fs_locations_bitmap[3] = {
|
|
|
| FATTR4_WORD1_MOUNTED_ON_FILEID,
|
|
|
};
|
|
|
|
|
|
+static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src,
|
|
|
+ struct inode *inode)
|
|
|
+{
|
|
|
+ unsigned long cache_validity;
|
|
|
+
|
|
|
+ memcpy(dst, src, NFS4_BITMASK_SZ*sizeof(*dst));
|
|
|
+ if (!inode || !nfs4_have_delegation(inode, FMODE_READ))
|
|
|
+ return;
|
|
|
+
|
|
|
+ cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
|
|
|
+ if (!(cache_validity & NFS_INO_REVAL_FORCED))
|
|
|
+ cache_validity &= ~(NFS_INO_INVALID_CHANGE
|
|
|
+ | NFS_INO_INVALID_SIZE);
|
|
|
+
|
|
|
+ if (!(cache_validity & NFS_INO_INVALID_SIZE))
|
|
|
+ dst[0] &= ~FATTR4_WORD0_SIZE;
|
|
|
+
|
|
|
+ if (!(cache_validity & NFS_INO_INVALID_CHANGE))
|
|
|
+ dst[0] &= ~FATTR4_WORD0_CHANGE;
|
|
|
+}
|
|
|
+
|
|
|
+static void nfs4_bitmap_copy_adjust_setattr(__u32 *dst,
|
|
|
+ const __u32 *src, struct inode *inode)
|
|
|
+{
|
|
|
+ nfs4_bitmap_copy_adjust(dst, src, inode);
|
|
|
+}
|
|
|
+
|
|
|
static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
|
|
|
struct nfs4_readdir_arg *readdir)
|
|
|
{
|
|
@@ -3074,12 +3103,13 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
|
|
struct nfs4_label *olabel)
|
|
|
{
|
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
|
+ __u32 bitmask[NFS4_BITMASK_SZ];
|
|
|
struct nfs4_state *state = ctx ? ctx->state : NULL;
|
|
|
struct nfs_setattrargs arg = {
|
|
|
.fh = NFS_FH(inode),
|
|
|
.iap = sattr,
|
|
|
.server = server,
|
|
|
- .bitmask = server->attr_bitmask,
|
|
|
+ .bitmask = bitmask,
|
|
|
.label = ilabel,
|
|
|
};
|
|
|
struct nfs_setattrres res = {
|
|
@@ -3094,11 +3124,11 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
|
|
};
|
|
|
int err;
|
|
|
|
|
|
- arg.bitmask = nfs4_bitmask(server, ilabel);
|
|
|
- if (ilabel)
|
|
|
- arg.bitmask = nfs4_bitmask(server, olabel);
|
|
|
-
|
|
|
do {
|
|
|
+ nfs4_bitmap_copy_adjust_setattr(bitmask,
|
|
|
+ nfs4_bitmask(server, olabel),
|
|
|
+ inode);
|
|
|
+
|
|
|
err = _nfs4_do_setattr(inode, &arg, &res, cred, ctx);
|
|
|
switch (err) {
|
|
|
case -NFS4ERR_OPENMODE:
|