[OpenAFS-devel] AFS and Solaris UFS
Nickolai Zeldovich
kolya@MIT.EDU
Fri, 13 Apr 2001 19:50:19 -0400
> This code is broken in 4 areas with respect to the way
> it makes use of Solaris UFS internal functions.
I think the patch below should fix the inconsistencies in AFS-Solaris
interactions that you've mentioned.
-- kolya
--- afs/SOLARIS/osi_file.c 2000/11/04 10:03:25 1.2
+++ afs/SOLARIS/osi_file.c 2001/04/13 23:34:17
@@ -263,7 +263,11 @@
{
if (afs_CacheFSType == AFS_SUN_UFS_CACHE) {
struct inode *ip = VTOI(avp);
+ rw_enter(&ip->i_contents, RW_READER);
+ mutex_enter(&ip->i_tlock);
ip->i_flag &= ~IACC;
+ mutex_exit(&ip->i_tlock);
+ rw_exit(&ip->i_contents);
}
}
--- afs/SOLARIS/osi_inode.c 2001/01/19 10:22:50 1.4
+++ afs/SOLARIS/osi_inode.c 2001/04/13 23:34:17
@@ -19,8 +19,15 @@
#include "../afs/osi_inode.h"
#include "../afs/afs_stats.h" /* statistics stuff */
-extern int (*ufs_iputp)(), (*ufs_iallocp)(), (*ufs_iupdatp)(), (*ufs_igetp)();
+extern int (*ufs_iallocp)(), (*ufs_iupdatp)(), (*ufs_igetp)(),
+ (*ufs_itimes_nolockp)();
+#define AFS_ITIMES(ip) { \
+ mutex_enter(&(ip)->i_tlock); \
+ (*ufs_itimes_nolockp)(ip); \
+ mutex_exit(&(ip)->i_tlock); \
+}
+
getinode(vfsp, dev, inode, ipp, credp,perror)
struct vfs *vfsp;
struct AFS_UCRED *credp;
@@ -34,6 +41,7 @@
struct vnode *vp;
struct fs *fs;
struct inode *pip;
+ struct ufsvfs *ufsvfsp;
AFS_STATCNT(getinode);
@@ -48,7 +56,13 @@
) {
return (ENODEV);
}
- if (code = (*ufs_igetp)(vfsp, inode, &ip, credp)) {
+ ufsvfsp = (struct ufsvfs *)vfsp->vfs_data;
+
+ rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
+ code = (*ufs_igetp)(vfsp, inode, &ip, credp);
+ rw_exit(&ufsvfsp->vfs_dqrwlock);
+
+ if (code) {
*perror = BAD_IGET;
return code;
}
@@ -81,14 +95,16 @@
if (ip->i_mode == 0) {
/* Not an allocated inode */
+ AFS_ITIMES(ip);
rw_exit(&ip->i_contents);
- (*ufs_iputp)(ip);
+ VN_RELE(ITOV(ip));
return (ENOENT);
}
if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) {
+ AFS_ITIMES(ip);
rw_exit(&ip->i_contents);
- (*ufs_iputp)(ip);
+ VN_RELE(ITOV(ip));
return (ENOENT);
}
@@ -122,6 +138,7 @@
struct inode *ip, *newip;
register int code;
dev_t newdev;
+ struct ufsvfs *ufsvfsp;
AFS_STATCNT(afs_syscall_icreate);
@@ -142,11 +159,22 @@
if (code) {
return (code);
}
- if (code = (*ufs_iallocp)(ip, near_inode, 0, &newip, credp)) {
- (*ufs_iputp)(ip);
+
+ ufsvfsp = ip->i_ufsvfs;
+ rw_enter(&ip->i_rwlock, RW_WRITER);
+ rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
+ rw_enter(&ip->i_contents, RW_WRITER);
+ code = (*ufs_iallocp)(ip, near_inode, 0, &newip, credp);
+ rw_exit(&ufsvfsp->vfs_dqrwlock);
+ rw_exit(&ip->i_rwlock);
+
+ AFS_ITIMES(ip);
+ rw_exit(&ip->i_contents);
+ VN_RELE(ITOV(ip));
+
+ if (code) {
return (code);
}
- (*ufs_iputp)(ip);
rw_enter(&newip->i_contents, RW_WRITER);
mutex_enter(&newip->i_tlock);
newip->i_flag |= IACC|IUPD|ICHG;
@@ -184,8 +212,9 @@
*/
if (CrSync)
(*ufs_iupdatp)(newip, 1);
+ AFS_ITIMES(newip);
rw_exit(&newip->i_contents);
- (*ufs_iputp)(newip);
+ VN_RELE(ITOV(newip));
return (code);
}
@@ -224,7 +253,10 @@
}
code = falloc((struct vnode *)NULL, FWRITE|FREAD, &fp, &fd);
if (code) {
- (*ufs_iputp)(ip);
+ rw_enter(&ip->i_contents, RW_READER);
+ AFS_ITIMES(ip);
+ rw_exit(&ip->i_contents);
+ VN_RELE(ITOV(ip));
return (code);
}
@@ -284,9 +316,13 @@
if (code) {
return (code);
}
- if (!IS_VICEMAGIC(ip))
+ if (!IS_VICEMAGIC(ip)) {
code = EPERM;
- else {
+ rw_enter(&ip->i_contents, RW_READER);
+ AFS_ITIMES(ip);
+ rw_exit(&ip->i_contents);
+ VN_RELE(ITOV(ip));
+ } else {
rw_enter(&ip->i_contents, RW_WRITER);
ip->i_nlink += amount;
if (ip->i_nlink == 0) {
@@ -300,9 +336,10 @@
/* We may want to force the inode to the disk in case of crashes, other references, etc. */
if (IncSync)
(*ufs_iupdatp)(ip, 1);
+ AFS_ITIMES(ip);
rw_exit(&ip->i_contents);
+ VN_RELE(ITOV(ip));
}
- (*ufs_iputp)(ip);
return (code);
}
--- afs/SOLARIS/osi_vfsops.c 2000/11/15 00:38:24 1.4
+++ afs/SOLARIS/osi_vfsops.c 2001/04/13 23:34:17
@@ -231,10 +231,10 @@
/*
* afsinit - intialize VFS
*/
-void (*ufs_iputp)();
int (*ufs_iallocp)();
void (*ufs_iupdatp)();
int (*ufs_igetp)();
+void (*ufs_itimes_nolockp)();
struct streamtab *udp_infop = 0;
struct ill_s *ill_g_headp = 0;
@@ -302,14 +302,14 @@
nfs_checkauth = (int (*)()) modlookup("nfssrv", "checkauth");
if ( !nfs_checkauth ) afs_warn("nfs_checkauth not initialised");
#endif
- ufs_iputp = (int (*)()) modlookup("ufs", "ufs_iput");
ufs_iallocp = (int (*)()) modlookup("ufs", "ufs_ialloc");
ufs_iupdatp = (int (*)()) modlookup("ufs", "ufs_iupdat");
ufs_igetp = (int (*)()) modlookup("ufs", "ufs_iget");
+ ufs_itimes_nolockp = (void (*)()) modlookup("ufs", "ufs_itimes_nolock");
udp_infop = (struct streamtab *) modlookup("udp", "udpinfo");
ill_g_headp = (struct ill_s *) modlookup("ip", "ill_g_head");
- if ( !ufs_iputp || !ufs_iallocp || !ufs_iupdatp ||
+ if ( !ufs_iallocp || !ufs_iupdatp || !ufs_itimes_nolockp ||
!ufs_igetp || !udp_infop || !ill_g_headp )
afs_warn("AFS to UFS mapping cannot be fully initialised\n");