#include <afsconfig.h>
#include "afs/param.h"
-RCSID("$Header$");
+RCSID
+ ("$Header$");
#include "afs/sysincludes.h"
#include "afsincludes.h"
#if defined(AFS_LINUX24_ENV)
#include "h/smp_lock.h"
#endif
+#if defined(AFS_LINUX26_ENV)
+#include "h/namei.h"
+#endif
-char *crash_addr = 0; /* Induce an oops by writing here. */
-
+#if defined(AFS_LINUX24_ENV)
/* Lookup name and return vnode for same. */
-int osi_lookupname(char *aname, uio_seg_t seg, int followlink,
- vnode_t **dirvpp, struct dentry **dpp)
+int
+osi_lookupname(char *aname, uio_seg_t seg, int followlink,
+ vnode_t ** dirvpp, struct dentry **dpp)
{
-#if defined(AFS_LINUX24_ENV)
- struct nameidata nd;
-#else
- struct dentry *dp = NULL;
-#endif
int code;
+ extern struct nameidata afs_cacheNd;
+ struct nameidata *nd = &afs_cacheNd;
code = ENOENT;
-#if defined(AFS_LINUX24_ENV)
if (seg == AFS_UIOUSER) {
- code = followlink ?
- user_path_walk(aname, &nd) : user_path_walk_link(aname, &nd);
- }
- else {
- if (path_init(aname, followlink ? LOOKUP_FOLLOW : 0, &nd))
- code = path_walk(aname, &nd);
+ code =
+ followlink ? user_path_walk(aname,
+ nd) : user_path_walk_link(aname, nd);
+ } else {
+#if defined(AFS_LINUX26_ENV)
+ code = path_lookup(aname, followlink ? LOOKUP_FOLLOW : 0, nd);
+#else
+ if (path_init(aname, followlink ? LOOKUP_FOLLOW : 0, nd))
+ code = path_walk(aname, nd);
+#endif
}
if (!code) {
- if (nd.dentry->d_inode) {
- *dpp = dget(nd.dentry);
+ if (nd->dentry->d_inode) {
+ *dpp = dget(nd->dentry);
code = 0;
- } else
+ } else {
code = ENOENT;
- path_release(&nd);
+ path_release(nd);
+ }
}
+ return code;
+}
#else
+int
+osi_lookupname(char *aname, uio_seg_t seg, int followlink, vnode_t ** dirvpp,
+ struct dentry **dpp)
+{
+ struct dentry *dp = NULL;
+ int code;
+
+ code = ENOENT;
if (seg == AFS_UIOUSER) {
dp = followlink ? namei(aname) : lnamei(aname);
- }
- else {
+ } else {
dp = lookup_dentry(aname, NULL, followlink ? 1 : 0);
}
if (dp->d_inode) {
*dpp = dp;
code = 0;
- }
- else
+ } else
dput(dp);
}
-#endif
-
+
return code;
}
+#endif
/* Intialize cache device info and fragment size for disk cache partition. */
-int osi_InitCacheInfo(char *aname)
+int
+osi_InitCacheInfo(char *aname)
{
int code;
struct dentry *dp;
extern struct osi_dev cacheDev;
extern afs_int32 afs_fsfragsize;
extern struct super_block *afs_cacheSBp;
-
code = osi_lookupname(aname, AFS_UIOSYS, 1, NULL, &dp);
- if (code) return ENOENT;
+ if (code)
+ return ENOENT;
cacheInode = dp->d_inode->i_ino;
- cacheDev.dev = dp->d_inode->i_dev;
+ cacheDev.dev = dp->d_inode->i_sb->s_dev;
afs_fsfragsize = dp->d_inode->i_sb->s_blocksize - 1;
afs_cacheSBp = dp->d_inode->i_sb;
* Seek, then read or write to an open inode. addrp points to data in
* kernel space.
*/
-int osi_rdwr(int rw, struct osi_file *file, caddr_t addrp, size_t asize,
- size_t *resid)
+int
+osi_rdwr(int rw, struct osi_file *file, caddr_t addrp, size_t asize,
+ size_t * resid)
{
int code = 0;
KERNEL_SPACE_DECL;
/* Seek to the desired position. Return -1 on error. */
if (filp->f_op->llseek) {
- if (filp->f_op->llseek(filp, (loff_t)offset, 0) != offset)
+ if (filp->f_op->llseek(filp, (loff_t) offset, 0) != offset)
return -1;
- }
- else
+ } else
filp->f_pos = offset;
savelim = current->rlim[RLIMIT_FSIZE].rlim_cur;
code = FOP_READ(filp, addrp, asize);
else if (rw == UIO_WRITE)
code = FOP_WRITE(filp, addrp, asize);
- else /* all is well? */
+ else /* all is well? */
code = asize;
TO_KERNEL_SPACE();
current->rlim[RLIMIT_FSIZE].rlim_cur = savelim;
- if (code >=0) {
+ if (code >= 0) {
*resid = asize - code;
return 0;
- }
- else
+ } else
return -1;
}
/* This variant is called from AFS read/write routines and takes a uio
* struct and, if successful, returns 0.
*/
-int osi_file_uio_rdwr(struct osi_file *osifile, uio_t *uiop, int rw)
+int
+osi_file_uio_rdwr(struct osi_file *osifile, uio_t * uiop, int rw)
{
struct file *filp = &osifile->file;
struct inode *ip = FILE_INODE(&osifile->file);
if (code < 0) {
code = -code;
break;
+ } else if (code == 0) {
+ /*
+ * This is bad -- we can't read any more data from the
+ * file, but we have no good way of signaling a partial
+ * read either.
+ code = EIO;
+ break;
}
-
+
iov->iov_base += code;
iov->iov_len -= code;
uiop->uio_resid -= code;
/* setup_uio
* Setup a uio struct.
*/
-void setup_uio(uio_t *uiop, struct iovec *iovecp, char *buf,
- afs_offs_t pos, int count, uio_flag_t flag,
- uio_seg_t seg)
+void
+setup_uio(uio_t * uiop, struct iovec *iovecp, char *buf, afs_offs_t pos,
+ int count, uio_flag_t flag, uio_seg_t seg)
{
iovecp->iov_base = buf;
iovecp->iov_len = count;
* UIO_READ : dp -> uio
* UIO_WRITE : uio -> dp
*/
-int uiomove(char *dp, int length, uio_flag_t rw, uio_t *uiop)
+int
+uiomove(char *dp, int length, uio_flag_t rw, uio_t * uiop)
{
int count, n;
struct iovec *iov;
if (count > length)
count = length;
-
- switch(uiop->uio_seg) {
+
+ switch (uiop->uio_seg) {
case AFS_UIOSYS:
- switch(rw) {
+ switch (rw) {
case UIO_READ:
- memcpy(iov->iov_base, dp, count); break;
+ memcpy(iov->iov_base, dp, count);
+ break;
case UIO_WRITE:
- memcpy(dp, iov->iov_base, count); break;
+ memcpy(dp, iov->iov_base, count);
+ break;
default:
printf("uiomove: Bad rw = %d\n", rw);
return -EINVAL;
}
break;
case AFS_UIOUSER:
- switch(rw) {
+ switch (rw) {
case UIO_READ:
- AFS_COPYOUT(dp, iov->iov_base, count, code); break;
+ AFS_COPYOUT(dp, iov->iov_base, count, code);
+ break;
case UIO_WRITE:
- AFS_COPYIN(iov->iov_base, dp, count, code); break;
+ AFS_COPYIN(iov->iov_base, dp, count, code);
+ break;
default:
printf("uiomove: Bad rw = %d\n", rw);
return -EINVAL;
return 0;
}
-void afs_osi_SetTime(osi_timeval_t *tvp)
+void
+afs_osi_SetTime(osi_timeval_t * tvp)
{
- extern int (*sys_settimeofdayp)(struct timeval *tv, struct timezone *tz);
+ extern int (*sys_settimeofdayp) (struct timeval * tv,
+ struct timezone * tz);
#ifdef AFS_LINUX_64BIT_KERNEL
struct timeval tv;
AFS_STATCNT(osi_SetTime);
tv.tv_sec = tvp->tv_sec;
tv.tv_usec = tvp->tv_usec;
- (void) (*sys_settimeofdayp)(&tv, NULL);
+ (void)(*sys_settimeofdayp) (&tv, NULL);
#else
KERNEL_SPACE_DECL;
AFS_STATCNT(osi_SetTime);
TO_USER_SPACE();
- (void) (*sys_settimeofdayp)(tvp, NULL);
+ (void)(*sys_settimeofdayp) (tvp, NULL);
TO_KERNEL_SPACE();
#endif
}
/* Free all the pages on any of the vnodes in the vlru. Must be done before
* freeing all memory.
*/
-void osi_linux_free_inode_pages(void)
+void
+osi_linux_free_inode_pages(void)
{
int i;
struct vcache *tvc;
struct inode *ip;
extern struct vcache *afs_vhashT[VCSIZE];
- for (i=0; i<VCSIZE; i++) {
- for(tvc = afs_vhashT[i]; tvc; tvc=tvc->hnext) {
+ for (i = 0; i < VCSIZE; i++) {
+ for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
ip = AFSTOI(tvc);
#if defined(AFS_LINUX24_ENV)
if (ip->i_data.nrpages) {
if (ip->i_nrpages) {
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
- truncate_inode_pages(&ip->i_data, 0);
+ truncate_inode_pages(&ip->i_data, 0);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15)
- truncate_inode_pages(ip, 0);
+ truncate_inode_pages(ip, 0);
#else
invalidate_inode_pages(ip);
#endif
}
}
-void osi_clear_inode(struct inode *ip)
+void
+osi_clear_inode(struct inode *ip)
{
cred_t *credp = crref();
struct vcache *vcp = ITOAFS(ip);
#else
if (ip->i_count > 1)
#endif
- printf("afs_put_inode: ino %d (0x%x) has count %d\n", ip->i_ino, ip, ip->i_count);
+ printf("afs_put_inode: ino %d (0x%x) has count %d\n", ip->i_ino, ip,
+ ip->i_count);
afs_InactiveVCache(vcp, credp);
ObtainWriteLock(&vcp->lock, 504);
-#if defined(AFS_LINUX24_ENV)
- atomic_set(&ip->i_count, 0);
-#else
- ip->i_count = 0;
-#endif
- ip->i_nlink = 0; /* iput checks this after calling this routine. */
+ ip->i_nlink = 0; /* iput checks this after calling this routine. */
+ ip->i_state = I_CLEAR;
ReleaseWriteLock(&vcp->lock);
crfree(credp);
}
+#if !defined(AFS_LINUX26_ENV)
/* iput an inode. Since we still have a separate inode pool, we don't want
* to call iput on AFS inodes, since they would then end up on Linux's
* inode_unsed list.
*/
-void osi_iput(struct inode *ip)
+void
+osi_iput(struct inode *ip)
{
extern struct vfs *afs_globalVFS;
AFS_GLOCK();
+
+ if (afs_globalVFS && ip->i_sb != afs_globalVFS)
+ osi_Panic("IPUT Not an afs inode\n");
+
#if defined(AFS_LINUX24_ENV)
- if (atomic_read(&ip->i_count) == 0 || atomic_read(&ip->i_count) & 0xffff0000) {
+ if (atomic_read(&ip->i_count) == 0)
#else
- if (ip->i_count == 0 || ip->i_count & 0xffff0000) {
+ if (ip->i_count == 0)
#endif
osi_Panic("IPUT Bad refCount %d on inode 0x%x\n",
#if defined(AFS_LINUX24_ENV)
- atomic_read(&ip->i_count), ip);
+ atomic_read(&ip->i_count),
#else
- ip->i_count, ip);
+ ip->i_count,
#endif
- }
- if (afs_globalVFS && afs_globalVFS == ip->i_sb ) {
+ ip);
+
#if defined(AFS_LINUX24_ENV)
- atomic_dec(&ip->i_count);
- if (!atomic_read(&ip->i_count))
+ if (atomic_dec_and_test(&ip->i_count))
#else
- ip->i_count --;
- if (!ip->i_count)
+ if (!--ip->i_count)
#endif
- osi_clear_inode(ip);
+ {
+ osi_clear_inode(ip);
+ ip->i_state = 0;
}
- else
- iput(ip);
AFS_GUNLOCK();
}
+#endif
/* check_bad_parent() : Checks if this dentry's vcache is a root vcache
* that has its mvid (parent dir's fid) pointer set to the wrong directory
* to the correct parent and mountpoint fids.
*/
-void check_bad_parent(struct dentry *dp)
+void
+check_bad_parent(struct dentry *dp)
{
- cred_t *credp;
- struct vcache *vcp = ITOAFS(dp->d_inode), *avc = NULL;
- struct vcache *pvc = ITOAFS(dp->d_parent->d_inode);
-
- if (vcp->mvid->Fid.Volume != pvc->fid.Fid.Volume) { /* bad parent */
- credp = crref();
-
-
- /* force a lookup, so vcp->mvid is fixed up */
- afs_lookup(pvc, dp->d_name.name, &avc, credp);
- if (!avc || vcp != avc) { /* bad, very bad.. */
- afs_Trace4(afs_iclSetp, CM_TRACE_TMP_1S3L, ICL_TYPE_STRING,
- "afs_linux_revalidate : bad pointer returned from afs_lookup origvc newvc dentry",
- ICL_TYPE_POINTER, vcp,
- ICL_TYPE_POINTER, avc,
- ICL_TYPE_POINTER, dp);
+ cred_t *credp;
+ struct vcache *vcp = ITOAFS(dp->d_inode), *avc = NULL;
+ struct vcache *pvc = ITOAFS(dp->d_parent->d_inode);
+
+ if (vcp->mvid->Fid.Volume != pvc->fid.Fid.Volume) { /* bad parent */
+ credp = crref();
+
+
+ /* force a lookup, so vcp->mvid is fixed up */
+ afs_lookup(pvc, dp->d_name.name, &avc, credp);
+ if (!avc || vcp != avc) { /* bad, very bad.. */
+ afs_Trace4(afs_iclSetp, CM_TRACE_TMP_1S3L, ICL_TYPE_STRING,
+ "check_bad_parent: bad pointer returned from afs_lookup origvc newvc dentry",
+ ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, avc,
+ ICL_TYPE_POINTER, dp);
+ }
+ if (avc)
+ AFS_RELE(avc);
+ crfree(credp);
}
- if (avc)
- AFS_RELE(avc);
- crfree(credp);
- } /* if bad parent */
-
- return;
+ /* if bad parent */
+ return;
}
struct task_struct *rxk_ListenerTask;
-void osi_linux_mask(void)
+void
+osi_linux_mask(void)
{
- spin_lock_irq(¤t->sigmask_lock);
+ SIG_LOCK(current);
sigfillset(¤t->blocked);
- recalc_sigpending(current);
- spin_unlock_irq(¤t->sigmask_lock);
-}
-
-void osi_linux_unmask(void)
-{
- spin_lock_irq(&rxk_ListenerTask->sigmask_lock);
- sigemptyset(&rxk_ListenerTask->blocked);
- flush_signals(rxk_ListenerTask);
- recalc_sigpending(rxk_ListenerTask);
- spin_unlock_irq(&rxk_ListenerTask->sigmask_lock);
+ RECALC_SIGPENDING(current);
+ SIG_UNLOCK(current);
}
-void osi_linux_rxkreg(void)
+void
+osi_linux_rxkreg(void)
{
rxk_ListenerTask = current;
}