#define pageoff(pp) pp->offset
#endif
+#if defined(AFS_LINUX26_ENV)
+#define UnlockPage(pp) unlock_page(pp)
+#endif
+
extern struct vcache *afs_globalVp;
extern afs_rwlock_t afs_xvcache;
-extern struct dentry_operations *afs_dops;
#if defined(AFS_LINUX24_ENV)
extern struct inode_operations afs_file_iops;
extern struct address_space_operations afs_file_aops;
*offp += count;
}
done:
+ ;
} else {
#endif /* AFS_64BIT_CLIENT */
osi_FlushPages(vcp, credp); /* ensure stale pages are gone */
ReleaseWriteLock(&vcp->lock);
}
done:
+ ;
} else {
#endif /* AFS_64BIT_CLIENT */
AFS_GUNLOCK();
struct afs_fakestat_state fakestat;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
AFS_STATCNT(afs_readdir);
code = afs_InitReq(&treq, credp);
crfree(credp);
- if (code) {
- AFS_GUNLOCK();
- return -code;
- }
+ if (code)
+ goto out1;
afs_InitFakeStat(&fakestat);
code = afs_EvalFakeStat(&avc, &fakestat, &treq);
- if (code) {
- afs_PutFakeStat(&fakestat);
- AFS_GUNLOCK();
- return -code;
- }
+ if (code)
+ goto out;
/* update the cache entry */
tagain:
code = afs_VerifyVCache(avc, &treq);
- if (code) {
- afs_PutFakeStat(&fakestat);
- AFS_GUNLOCK();
- return -code;
- }
+ if (code)
+ goto out;
/* get a reference to the entire directory */
tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &tlen, 1);
len = tlen;
if (!tdc) {
- afs_PutFakeStat(&fakestat);
- AFS_GUNLOCK();
- return -ENOENT;
+ code = -ENOENT;
+ goto out;
}
ObtainReadLock(&avc->lock);
ObtainReadLock(&tdc->lock);
* takes an offset in units of blobs, rather than bytes.
*/
code = 0;
- offset = (int)fp->f_pos;
+ offset = (int) fp->f_pos;
while (1) {
dirpos = BlobScan(&tdc->f.inode, offset);
if (!dirpos)
else {
printf("afs_linux_readdir: afs_dir_GetBlob failed, null name (inode %x, dirpos %d)\n",
&tdc->f.inode, dirpos);
- DRelease(de, 0);
+ DRelease((struct buffer *) de, 0);
afs_PutDCache(tdc);
ReleaseReadLock(&avc->lock);
- afs_PutFakeStat(&fakestat);
- return -ENOENT;
+ code = -ENOENT;
+ goto out;
}
/* filldir returns -EINVAL when the buffer is full. */
-#if (defined(AFS_LINUX24_ENV) || defined(pgoff2loff)) && defined(DECLARE_FSTYPE)
+#if defined(AFS_LINUX26_ENV) || ((defined(AFS_LINUX24_ENV) || defined(pgoff2loff)) && defined(DECLARE_FSTYPE))
{
unsigned int type = DT_UNKNOWN;
struct VenusFid afid;
#else
code = (*filldir) (dirbuf, de->name, len, offset, ino);
#endif
- DRelease(de, 0);
+ DRelease((struct buffer *)de, 0);
if (code)
break;
offset = dirpos + 1 + ((len + 16) >> 5);
ReleaseReadLock(&tdc->lock);
afs_PutDCache(tdc);
ReleaseReadLock(&avc->lock);
+ code = 0;
+
+out:
afs_PutFakeStat(&fakestat);
+out1:
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
- return 0;
+ return code;
}
(void)afs_close(vcp, vmap->vm_file->f_flags, credp);
/* only decrement the execsOrWriters flag if this is not a
* writable file. */
- if (!(vmap->vm_file->f_flags & (FWRITE | FTRUNC)))
- vcp->execsOrWriters--;
+ if (!(vcp->states & CRO) )
+ if (! (vmap->vm_file->f_flags & (FWRITE | FTRUNC)))
+ vcp->execsOrWriters--;
vcp->states &= ~CMAPPED;
crfree(credp);
} else if ((vmap->vm_file->f_flags & (FWRITE | FTRUNC)))
/* Add an open reference on the first mapping. */
if (vcp->mapcnt == 0) {
- vcp->execsOrWriters++;
+ if (!(vcp->states & CRO))
+ vcp->execsOrWriters++;
vcp->opens++;
vcp->states |= CMAPPED;
}
return -code;
}
+#if defined(AFS_LINUX26_ENV)
+static int
+afs_linux_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+ int err = afs_linux_revalidate(dentry);
+ if (!err)
+ generic_fillattr(dentry->d_inode, stat);
+ return err;
+}
+#endif
/* Validate a dentry. Return 1 if unchanged, 0 if VFS layer should re-evaluate.
* In kernels 2.2.10 and above, we are passed an additional flags var which
struct vcache *lookupvcp = NULL;
int code, bad_dentry = 1;
struct sysname_info sysState;
- struct vcache *vcp = ITOAFS(dp->d_inode);
- struct vcache *parentvcp = ITOAFS(dp->d_parent->d_inode);
+ struct vcache *vcp, *parentvcp;
+
+ sysState.allocked = 0;
AFS_GLOCK();
lock_kernel();
- sysState.allocked = 0;
+ vcp = ITOAFS(dp->d_inode);
+ parentvcp = ITOAFS(dp->d_parent->d_inode);
/* If it's a negative dentry, then there's nothing to do. */
if (!vcp || !parentvcp)
if (sysState.allocked)
osi_FreeLargeSpace(name);
- AFS_GUNLOCK();
- crfree(credp);
-
if (bad_dentry) {
shrink_dcache_parent(dp);
d_drop(dp);
}
+
unlock_kernel();
+ AFS_GUNLOCK();
+ crfree(credp);
return !bad_dentry;
}
+#if !defined(AFS_LINUX26_ENV)
/* afs_dentry_iput */
static void
afs_dentry_iput(struct dentry *dp, struct inode *ip)
osi_iput(ip);
}
+#endif
static int
afs_dentry_delete(struct dentry *dp)
struct dentry_operations afs_dentry_operations = {
.d_revalidate = afs_linux_dentry_revalidate,
- .d_iput = afs_dentry_iput,
.d_delete = afs_dentry_delete,
+#if !defined(AFS_LINUX26_ENV)
+ .d_iput = afs_dentry_iput,
+#endif
};
-struct dentry_operations *afs_dops = &afs_dentry_operations;
/**********************************************************************
* AFS Linux inode operations
vattr.va_mode = mode;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code =
afs_create(ITOAFS(dip), name, &vattr, NONEXCL, mode,
(struct vcache **)&ip, credp);
ip->i_op = &afs_symlink_iops;
#endif
- dp->d_op = afs_dops;
+ dp->d_op = &afs_dentry_operations;
dp->d_time = jiffies;
d_instantiate(dp, ip);
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
cred_t *credp = crref();
struct vcache *vcp = NULL;
const char *comp = dp->d_name.name;
+
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code = afs_lookup(ITOAFS(dip), comp, &vcp, credp);
if (vcp) {
#endif
}
dp->d_time = jiffies;
- dp->d_op = afs_dops;
+ dp->d_op = &afs_dentry_operations;
d_add(dp, AFSTOI(vcp));
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
const char *name = dp->d_name.name;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code = afs_remove(ITOAFS(dip), name, credp);
- AFS_GUNLOCK();
if (!code)
d_drop(dp);
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
+ AFS_GUNLOCK();
crfree(credp);
return -code;
}
const char *name = dp->d_name.name;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
VATTR_NULL(&vattr);
vattr.va_mask = ATTR_MODE;
vattr.va_mode = mode;
#if defined(AFS_LINUX24_ENV)
tvcp->v.v_fop = &afs_dir_fops;
#endif
- dp->d_op = afs_dops;
+ dp->d_op = &afs_dentry_operations;
dp->d_time = jiffies;
d_instantiate(dp, AFSTOI(tvcp));
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
const char *name = dp->d_name.name;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code = afs_rmdir(ITOAFS(dip), name, credp);
/* Linux likes to see ENOTEMPTY returned from an rmdir() syscall
d_drop(dp);
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
const char *oldname = olddp->d_name.name;
const char *newname = newdp->d_name.name;
+ AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
/* Remove old and new entries from name hash. New one will change below.
* While it's optimal to catch failures and re-insert newdp into hash,
* it's also error prone and in that case we're already dealing with error
* cases. Let another lookup put things right, if need be.
*/
- if (!list_empty(&olddp->d_hash)) {
+#if defined(AFS_LINUX26_ENV)
+ if (!d_unhashed(olddp))
d_drop(olddp);
- }
- if (!list_empty(&newdp->d_hash)) {
+ if (!d_unhashed(newdp))
d_drop(newdp);
- }
- AFS_GLOCK();
+#else
+ if (!list_empty(&olddp->d_hash))
+ d_drop(olddp);
+ if (!list_empty(&newdp->d_hash))
+ d_drop(newdp);
+#endif
code = afs_rename(ITOAFS(oldip), oldname, ITOAFS(newip), newname, credp);
- AFS_GUNLOCK();
if (!code) {
/* update time so it doesn't expire immediately */
d_move(olddp, newdp);
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
+ AFS_GUNLOCK();
+
crfree(credp);
return -code;
}
uio_t tuio;
struct iovec iovec;
struct inode *ip = FILE_INODE(fp);
- int cnt = atomic_read(&pp->count);
+ int cnt = page_count(pp);
struct vcache *avc = ITOAFS(ip);
AFS_GLOCK();
credp = crref();
afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
- ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count),
+ ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
ICL_TYPE_INT32, 99999);
setup_uio(&tuio, &iovec, buffer, base, count, UIO_WRITE, AFS_UIOSYS);
code = code ? -code : count - tuio.uio_resid;
afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
- ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count),
+ ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
ICL_TYPE_INT32, code);
crfree(credp);
credp = crref();
AFS_GLOCK();
afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
- ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count),
+ ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
ICL_TYPE_INT32, 99999);
setup_uio(&tuio, &iovec, page_addr + offset,
(afs_offs_t) (pageoff(pp) + offset), count, UIO_WRITE,
code = code ? -code : count - tuio.uio_resid;
afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
- ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count),
+ ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
ICL_TYPE_INT32, code);
AFS_GUNLOCK();
#endif
struct inode_operations afs_file_iops = {
-#if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX26_ENV)
+ .permission = afs_linux_permission,
+ .getattr = afs_linux_getattr,
+ .setattr = afs_notify_change,
+#elif defined(AFS_LINUX24_ENV)
.permission = afs_linux_permission,
.revalidate = afs_linux_revalidate,
.setattr = afs_notify_change,
.mkdir = afs_linux_mkdir,
.rmdir = afs_linux_rmdir,
.rename = afs_linux_rename,
+#if defined(AFS_LINUX26_ENV)
+ .getattr = afs_linux_getattr,
+#else
.revalidate = afs_linux_revalidate,
+#endif
.permission = afs_linux_permission,
};