/* this is effectively coda_iget: - get attributes (might be cached) - get the inode for the fid using vfs iget - link the two up if this is needed - fill in the attributes */ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) { struct coda_vattr attr; int error; /* We get inode numbers from Venus -- see venus source */ error = venus_getattr(sb, fid, &attr); if ( error ) { CDEBUG(D_CNODE, "coda_cnode_make: coda_getvattr returned %d for %s.\n", error, coda_f2s(fid)); *inode = NULL; return error; } *inode = coda_iget(sb, fid, &attr); if ( IS_ERR(*inode) ) { printk("coda_cnode_make: coda_iget failed\n"); return PTR_ERR(*inode); } CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n", (*inode)->i_ino, atomic_read(&(*inode)->i_count), coda_f2s(&ITOC(*inode)->c_fid)); return 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 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; }
/* this is effectively coda_iget: - get attributes (might be cached) - get the inode for the fid using vfs iget - link the two up if this is needed - fill in the attributes */ struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb) { struct coda_vattr attr; struct inode *inode; int error; /* We get inode numbers from Venus -- see venus source */ error = venus_getattr(sb, fid, &attr); if (error) return ERR_PTR(error); inode = coda_iget(sb, fid, &attr); if (IS_ERR(inode)) pr_warn("%s: coda_iget failed\n", __func__); return inode; }
struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb) { struct coda_vattr attr; struct inode *inode; int error; error = venus_getattr(sb, fid, &attr); if (error) return ERR_PTR(error); inode = coda_iget(sb, fid, &attr); if (IS_ERR(inode)) printk("coda_cnode_make: coda_iget failed\n"); return inode; }
/* this is effectively coda_iget: - get attributes (might be cached) - get the inode for the fid using vfs iget - link the two up if this is needed - fill in the attributes */ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) { struct coda_inode_info *cnp; struct coda_sb_info *sbi= coda_sbp(sb); struct coda_vattr attr; int error; ino_t ino; ENTRY; /* * We get inode numbers from Venus -- see venus source */ error = venus_getattr(sb, fid, &attr); if ( error ) { CDEBUG(D_CNODE, "coda_cnode_make: coda_getvattr returned %d for %s.\n", error, coda_f2s(fid)); *inode = NULL; return error; } ino = attr.va_fileid; *inode = iget(sb, ino); if ( !*inode ) { printk("coda_cnode_make: iget failed\n"); return -ENOMEM; } cnp = ITOC(*inode); /* see if we've got it already */ if ( cnp->c_magic != 0 && coda_fideq(fid, &cnp->c_fid)) { /* replace the attributes, type might have changed */ coda_fill_inode(*inode, &attr); return 0; } /* not fresh: collision */ if ( cnp->c_magic != 0 ) { printk("coda_cnode_make on initialized inode %ld, old %s new %s!\n", (*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid)); iput(*inode); return -ENOENT; }
/* this is effectively coda_iget: - get attributes (might be cached) - get the inode for the fid using vfs iget - link the two up if this is needed - fill in the attributes */ int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb) { struct coda_vattr attr; int error; /* We get inode numbers from Venus -- see venus source */ error = venus_getattr(sb, fid, &attr); if ( error ) { *inode = NULL; return error; } *inode = coda_iget(sb, fid, &attr); if ( IS_ERR(*inode) ) { printk("coda_cnode_make: coda_iget failed\n"); return PTR_ERR(*inode); } return 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; }
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; }