From: Trond Myklebust <trond.myklebust@fys.uio.no>
To: Xeno <xeno@overture.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: 2.4: NFS client race causes data loss when appending
Date: 06 Dec 2001 22:24:24 +0100 [thread overview]
Message-ID: <shsg06odotz.fsf@charged.uio.no> (raw)
In-Reply-To: <3C0ED156.2F327B0F@overture.com> <shsher4776s.fsf@charged.uio.no>
In-Reply-To: <shsher4776s.fsf@charged.uio.no>
>>>>> " " == Trond Myklebust <trond.myklebust@fys.uio.no> writes:
> What we really want is to prevent nfs_refresh_inode() from
> overwriting newer attribute information with older
> information. How therefore about something like the appended
> patch, that uses the ctime field to determine which attribute
> information is obsolete? I'm afraid it's not going to work too
> well for Linux servers because of the shitty 1 second
> resolution we have on (a|m|c)time, but it will help against
> most non-Linux servers.
Hah... I of course managed to get the sign wrong on the last
patch. The following should work better, including with Linux servers.
Cheers,
Trond
--- linux-2.4.17-pre4/fs/nfs/inode.c.orig Thu Dec 6 02:27:46 2001
+++ linux-2.4.17-pre4/fs/nfs/inode.c Thu Dec 6 21:45:29 2001
@@ -655,20 +655,8 @@
inode->i_op = &nfs_symlink_inode_operations;
else
init_special_inode(inode, inode->i_mode, fattr->rdev);
- /*
- * Preset the size and mtime, as there's no need
- * to invalidate the caches.
- */
- inode->i_size = nfs_size_to_loff_t(fattr->size);
- inode->i_mtime = nfs_time_to_secs(fattr->mtime);
- inode->i_atime = nfs_time_to_secs(fattr->atime);
- inode->i_ctime = nfs_time_to_secs(fattr->ctime);
- NFS_CACHE_CTIME(inode) = fattr->ctime;
- NFS_CACHE_MTIME(inode) = fattr->mtime;
- NFS_CACHE_ISIZE(inode) = fattr->size;
- NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
- NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
memcpy(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh));
+ NFS_CACHEINV(inode);
}
nfs_refresh_inode(inode, fattr);
}
@@ -966,6 +954,37 @@
}
/*
+ * nfs_fattr_obsolete - Test if attribute data is newer than cached data
+ * @inode: inode
+ * @fattr: attributes to test
+ *
+ * Avoid stuffing the attribute cache with obsolete information.
+ * We always accept updates if the attribute cache timed out, or if
+ * fattr->ctime is newer than our cached value.
+ * If fattr->ctime matches the cached value, we still accept the update
+ * if there also is a reasonable match for the Weak Cache Consistency
+ * data. This is in order to cope with NFS servers with crap time
+ * resolution...
+ */
+static inline
+int nfs_fattr_obsolete(struct inode *inode, struct nfs_fattr *fattr)
+{
+ s64 cdif;
+
+ if (time_after(jiffies, NFS_READTIME(inode)+NFS_ATTRTIMEO(inode)))
+ goto out_valid;
+ if ((cdif = (s64)fattr->ctime - (s64)NFS_CACHE_CTIME(inode)) > 0)
+ goto out_valid;
+ /* Ugh... */
+ if (cdif == 0 && (fattr->valid & NFS_ATTR_WCC)
+ && (s64)fattr->pre_ctime - (s64)NFS_CACHE_CTIME(inode) >= 0)
+ goto out_valid;
+ return -1;
+ out_valid:
+ return 0;
+}
+
+/*
* Many nfs protocol calls return the new file attributes after
* an operation. Here we update the inode to reflect the state
* of the server's inode.
@@ -1003,6 +1022,10 @@
if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
goto out_changed;
+ /* Avoid races */
+ if (nfs_fattr_obsolete(inode, fattr))
+ return 0;
+
new_mtime = fattr->mtime;
new_size = fattr->size;
new_isize = nfs_size_to_loff_t(fattr->size);
prev parent reply other threads:[~2001-12-06 21:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-06 2:00 2.4: NFS client race causes data loss when appending Xeno
2001-12-06 14:29 ` Trond Myklebust
2001-12-06 21:24 ` Trond Myklebust [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=shsg06odotz.fsf@charged.uio.no \
--to=trond.myklebust@fys.uio.no \
--cc=linux-kernel@vger.kernel.org \
--cc=xeno@overture.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.