patch-2.1.90 linux/fs/coda/dir.c
Next file: linux/fs/coda/file.c
Previous file: linux/fs/coda/coda_linux.c
Back to the patch index
Back to the overall index
- Lines: 181
- Date:
Tue Mar 17 21:19:05 1998
- Orig file:
v2.1.89/linux/fs/coda/dir.c
- Orig date:
Tue Mar 10 10:03:33 1998
diff -u --recursive --new-file v2.1.89/linux/fs/coda/dir.c linux/fs/coda/dir.c
@@ -40,17 +40,21 @@
/* dir file-ops */
static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
+/* dentry ops */
+int coda_dentry_revalidate(struct dentry *de);
+
/* support routines */
static int coda_venus_readdir(struct file *filp, void *dirent,
filldir_t filldir);
int coda_fsync(struct file *, struct dentry *dentry);
+static int coda_refresh_inode(struct dentry *dentry);
struct dentry_operations coda_dentry_operations =
{
- NULL, /* revalidate */
+ coda_dentry_revalidate, /* revalidate */
NULL, /* hash */
NULL,
- coda_dentry_delete
+ NULL,
};
struct inode_operations coda_dir_inode_operations =
@@ -74,7 +78,7 @@
coda_permission, /* permission */
NULL, /* smap */
NULL, /* update page */
- NULL /* revalidate */
+ coda_revalidate_inode /* revalidate */
};
struct file_operations coda_dir_operations = {
@@ -117,7 +121,6 @@
}
dircnp = ITOC(dir);
- CHECK_CNODE(dircnp);
if ( length > CFS_MAXNAMLEN ) {
printk("name too long: lookup, %s (%*s)\n",
@@ -141,9 +144,13 @@
(const char *)name, length, &type, &resfid);
res_inode = NULL;
- if (!error || (error == -CFS_NOCACHE) ) {
- if (error == -CFS_NOCACHE)
+ if (!error) {
+ if (type & CFS_NOCACHE) {
+ type &= (~CFS_NOCACHE);
+ CDEBUG(D_INODE, "dropme set for %s\n",
+ coda_f2s(&resfid));
dropme = 1;
+ }
error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
if (error)
return -error;
@@ -152,7 +159,7 @@
coda_f2s(&dircnp->c_fid), length, name, error);
return error;
}
- CDEBUG(D_INODE, "lookup: %s is (%s) type %d result %d, dropme %d\n",
+ CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
name, coda_f2s(&resfid), type, error, dropme);
exit:
@@ -228,7 +235,6 @@
CHECK_CNODE(dircnp);
if ( length > CFS_MAXNAMLEN ) {
- char str[50];
printk("name too long: create, %s(%s)\n",
coda_f2s(&dircnp->c_fid), name);
return -ENAMETOOLONG;
@@ -238,7 +244,6 @@
0, mode, &newfid, &attrs);
if ( error ) {
- char str[50];
CDEBUG(D_INODE, "create: %s, result %d\n",
coda_f2s(&newfid), error);
d_drop(de);
@@ -321,7 +326,6 @@
const char * name = de->d_name.name;
int len = de->d_name.len;
struct coda_inode_info *dir_cnp, *cnp;
- char str[50];
int error;
ENTRY;
@@ -408,7 +412,6 @@
int error;
const char *name = de->d_name.name;
int len = de->d_name.len;
- char fidstr[50];
ENTRY;
@@ -781,3 +784,82 @@
CODA_FREE(buff, size);
return error;
}
+
+int coda_dentry_revalidate(struct dentry *de)
+{
+ int valid = 1;
+ struct inode *inode = de->d_inode;
+ struct coda_inode_info *cii;
+ ENTRY;
+
+ if (inode) {
+ if (is_bad_inode(inode))
+ return 0;
+ cii = ITOC(de->d_inode);
+ if (cii->c_flags & C_PURGE)
+ valid = 0;
+ }
+ return valid || coda_isroot(de->d_inode);
+}
+
+
+static int coda_refresh_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);
+
+ ENTRY;
+ error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
+ if ( error ) {
+ make_bad_inode(inode);
+ return -EIO;
+ }
+
+ /* this baby may be lost if:
+ - it's type changed
+ - it's ino changed
+ */
+ old_mode = inode->i_mode;
+ old_ino = inode->i_ino;
+ coda_vattr_to_iattr(inode, &attr);
+
+ if ((inode->i_ino != old_ino) ||
+ ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT))) {
+ make_bad_inode(inode);
+ inode->i_mode = old_mode;
+ return -EIO;
+ }
+
+ cii->c_flags &= ~C_VATTR;
+ 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)
+{
+ int error = 0;
+ struct coda_inode_info *cii = ITOC(dentry->d_inode);
+
+ ENTRY;
+ 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);
+
+ if ( cii->c_flags & (C_VATTR | C_PURGE )) {
+ error = coda_refresh_inode(dentry);
+ }
+
+ return error;
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov