Ejemplo n.º 1
0
/* called when a cache lookup succeeds */
static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
{
	struct inode *inode = de->d_inode;
	struct coda_inode_info *cii;

	if (!inode || coda_isroot(inode))
		goto out;
	if (is_bad_inode(inode))
		goto bad;

	cii = ITOC(de->d_inode);
	if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
		goto out;

	shrink_dcache_parent(de);

	/* propagate for a flush */
	if (cii->c_flags & C_FLUSH) 
		coda_flag_inode_children(inode, C_FLUSH);

	if (atomic_read(&de->d_count) > 1)
		/* pretend it's valid, but don't change the flags */
		goto out;

	/* clear the flags. */
	spin_lock(&cii->c_lock);
	cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
	spin_unlock(&cii->c_lock);
bad:
	return 0;
out:
	return 1;
}
/*
 * This is called when we want to check if the inode has
 * changed on the server.  Coda makes this easy since the
 * cache manager Venus issues a downcall to the kernel when this 
 * happens 
 */
int coda_revalidate_inode(struct dentry *dentry)
{
	struct coda_vattr attr;
	int error = 0;
	int old_mode;
	ino_t old_ino;
	struct inode *inode = dentry->d_inode;
	struct coda_inode_info *cii = ITOC(inode);

	CDEBUG(D_INODE, "revalidating: %*s/%*s\n", 
	       dentry->d_name.len, dentry->d_name.name,
	       dentry->d_parent->d_name.len, dentry->d_parent->d_name.name);

	lock_kernel();
	if ( !cii->c_flags )
		goto ok;

	if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
		error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
		if ( error )
			goto return_bad_inode;

		/* this inode may be lost if:
		   - it's ino changed 
		   - type changes must be permitted for repair and
		   missing mount points.
		*/
		old_mode = inode->i_mode;
		old_ino = inode->i_ino;
		coda_vattr_to_iattr(inode, &attr);

		if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
			printk("Coda: inode %ld, fid %s changed type!\n",
			       inode->i_ino, coda_f2s(&(cii->c_fid)));
		}

		/* the following can happen when a local fid is replaced 
		   with a global one, here we lose and declare the inode bad */
		if (inode->i_ino != old_ino)
			goto return_bad_inode;
		
		coda_flag_inode_children(inode, C_FLUSH);
		cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
	}

ok:
	unlock_kernel();
	return 0;

return_bad_inode:
	unlock_kernel();
	return -EIO;
}
Ejemplo n.º 3
0
/*
 * This is called when we want to check if the inode has
 * changed on the server.  Coda makes this easy since the
 * cache manager Venus issues a downcall to the kernel when this
 * happens
 */
int coda_revalidate_inode(struct inode *inode)
{
    struct coda_vattr attr;
    int error;
    int old_mode;
    ino_t old_ino;
    struct coda_inode_info *cii = ITOC(inode);

    if (!cii->c_flags)
        return 0;

    if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
        error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
        if (error)
            return -EIO;

        /* this inode may be lost if:
           - it's ino changed
           - type changes must be permitted for repair and
           missing mount points.
        */
        old_mode = inode->i_mode;
        old_ino = inode->i_ino;
        coda_vattr_to_iattr(inode, &attr);

        if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
            pr_warn("inode %ld, fid %s changed type!\n",
                    inode->i_ino, coda_f2s(&(cii->c_fid)));
        }

        /* the following can happen when a local fid is replaced
           with a global one, here we lose and declare the inode bad */
        if (inode->i_ino != old_ino)
            return -EIO;

        coda_flag_inode_children(inode, C_FLUSH);

        spin_lock(&cii->c_lock);
        cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
        spin_unlock(&cii->c_lock);
    }
    return 0;
}
/* called when a cache lookup succeeds */
static int coda_dentry_revalidate(struct dentry *de, int flags)
{
	struct inode *inode = de->d_inode;
	struct coda_inode_info *cii;

	if (!inode)
		return 1;
	lock_kernel();
	if (coda_isroot(inode))
		goto out;
	if (is_bad_inode(inode))
		goto bad;

	cii = ITOC(de->d_inode);
	if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
		goto out;

	shrink_dcache_parent(de);

	/* propagate for a flush */
	if (cii->c_flags & C_FLUSH) 
		coda_flag_inode_children(inode, C_FLUSH);

	if (atomic_read(&de->d_count) > 1) {
		/* pretend it's valid, but don't change the flags */
		CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n",
		       de->d_inode->i_ino, coda_f2s(&cii->c_fid));
		goto out;
	}

	/* clear the flags. */
	cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);

bad:
	unlock_kernel();
	return 0;
out:
	unlock_kernel();
	return 1;
}
Ejemplo n.º 5
0
/* called when a cache lookup succeeds */
static int coda_dentry_revalidate(struct dentry *de, unsigned int flags)
{
    struct inode *inode;
    struct coda_inode_info *cii;

    if (flags & LOOKUP_RCU)
        return -ECHILD;

    inode = de->d_inode;
    if (!inode || is_root_inode(inode))
        goto out;
    if (is_bad_inode(inode))
        goto bad;

    cii = ITOC(de->d_inode);
    if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
        goto out;

    shrink_dcache_parent(de);

    /* propagate for a flush */
    if (cii->c_flags & C_FLUSH)
        coda_flag_inode_children(inode, C_FLUSH);

    if (d_count(de) > 1)
        /* pretend it's valid, but don't change the flags */
        goto out;

    /* clear the flags. */
    spin_lock(&cii->c_lock);
    cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
    spin_unlock(&cii->c_lock);
bad:
    return 0;
out:
    return 1;
}
Ejemplo n.º 6
0
int coda_revalidate_inode(struct dentry *dentry)
{
	struct coda_vattr attr;
	int error;
	int old_mode;
	ino_t old_ino;
	struct inode *inode = dentry->d_inode;
	struct coda_inode_info *cii = ITOC(inode);

	if (!cii->c_flags)
		return 0;

	if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
		error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
		if (error)
			return -EIO;

		old_mode = inode->i_mode;
		old_ino = inode->i_ino;
		coda_vattr_to_iattr(inode, &attr);

		if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
			printk("Coda: inode %ld, fid %s changed type!\n",
			       inode->i_ino, coda_f2s(&(cii->c_fid)));
		}

		if (inode->i_ino != old_ino)
			return -EIO;
		
		coda_flag_inode_children(inode, C_FLUSH);

		spin_lock(&cii->c_lock);
		cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
		spin_unlock(&cii->c_lock);
	}
	return 0;
}
Ejemplo n.º 7
0
static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
{
	struct inode *inode;
	struct coda_inode_info *cii;

	if (nd->flags & LOOKUP_RCU)
		return -ECHILD;

	inode = de->d_inode;
	if (!inode || coda_isroot(inode))
		goto out;
	if (is_bad_inode(inode))
		goto bad;

	cii = ITOC(de->d_inode);
	if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
		goto out;

	shrink_dcache_parent(de);

	
	if (cii->c_flags & C_FLUSH) 
		coda_flag_inode_children(inode, C_FLUSH);

	if (de->d_count > 1)
		
		goto out;

	
	spin_lock(&cii->c_lock);
	cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
	spin_unlock(&cii->c_lock);
bad:
	return 0;
out:
	return 1;
}