- explanation of how to make filesystems exportable.
Locking
- info on locking rules as they pertain to Linux VFS.
+9p.txt
+ - 9p (v9fs) is an implementation of the Plan 9 remote fs protocol.
adfs.txt
- info and mount options for the Acorn Advanced Disc Filing System.
afs.txt
- info and mount options for the UDF filesystem.
ufs.txt
- info on the ufs filesystem.
-v9fs.txt
- - v9fs is a Unix implementation of the Plan 9 9p remote fs protocol.
vfat.txt
- info on using the VFAT filesystem used in Windows NT and Windows 95
vfs.txt
aname=name aname specifies the file tree to access when the server is
offering several exported file systems.
+ cache=mode specifies a cacheing policy. By default, no caches are used.
+ loose = no attempts are made at consistency,
+ intended for exclusive, read-only mounts
+
debug=n specifies debug level. The debug level is a bitmask.
0x01 = display verbose error messages
0x02 = developer debug (DEBUG_CURRENT)
}
/**
- * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it
+ * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
+ * release it
* @dentry: dentry to look for fid in
*
* find a fid in the dentry and then clone to a new private fid
Opt_uname, Opt_remotename,
/* Options that take no arguments */
Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
+ /* Cache options */
+ Opt_cache_loose,
/* Error token */
Opt_err
};
{Opt_fd, "fd"},
{Opt_legacy, "noextend"},
{Opt_nodevmap, "nodevmap"},
+ {Opt_cache_loose, "cache=loose"},
+ {Opt_cache_loose, "loose"},
{Opt_err, NULL}
};
v9ses->debug = 0;
v9ses->rfdno = ~0;
v9ses->wfdno = ~0;
+ v9ses->cache = 0;
if (!options)
return;
"integer field, but no integer?\n");
continue;
}
-
}
switch (token) {
case Opt_port:
case Opt_nodevmap:
v9ses->nodev = 1;
break;
+ case Opt_cache_loose:
+ v9ses->cache = CACHE_LOOSE;
+ break;
default:
continue;
}
unsigned int afid; /* authentication fid */
unsigned int rfdno; /* read file descriptor number */
unsigned int wfdno; /* write file descriptor number */
-
+ unsigned int cache; /* cache mode */
char *name; /* user name to mount as */
char *remotename; /* name of remote hierarchy being mounted */
PROTO_FD,
};
+/* possible values of ->cache */
+/* eventually support loose, tight, time, session, default always none */
+enum {
+ CACHE_NONE, /* default */
+ CACHE_LOOSE, /* no consistency */
+};
+
extern struct dentry *v9fs_debugfs_root;
int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
extern struct file_system_type v9fs_fs_type;
extern const struct address_space_operations v9fs_addr_operations;
extern const struct file_operations v9fs_file_operations;
+extern const struct file_operations v9fs_cached_file_operations;
extern const struct file_operations v9fs_dir_operations;
extern struct dentry_operations v9fs_dentry_operations;
+extern struct dentry_operations v9fs_cached_dentry_operations;
struct inode *v9fs_get_inode(struct super_block *sb, int mode);
ino_t v9fs_qid2ino(struct v9fs_qid *qid);
int total = 0;
int result = 0;
+ dprintk(DEBUG_VFS, "\n");
+
buffer = kmap(page);
do {
if (count < rsize)
static int v9fs_dentry_delete(struct dentry *dentry)
{
dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
return 1;
}
+/**
+ * v9fs_cached_dentry_delete - called when dentry refcount equals 0
+ * @dentry: dentry in question
+ *
+ * Only return 1 if our inode is invalid. Only non-synthetic files
+ * (ones without mtime == 0) should be calling this function.
+ *
+ */
+
+static int v9fs_cached_dentry_delete(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
+ if(!inode)
+ return 1;
+
+ return 0;
+}
+
/**
* v9fs_dentry_release - called when dentry is going to be freed
* @dentry: dentry that is being release
}
}
+struct dentry_operations v9fs_cached_dentry_operations = {
+ .d_delete = v9fs_cached_dentry_delete,
+ .d_release = v9fs_dentry_release,
+};
+
struct dentry_operations v9fs_dentry_operations = {
.d_delete = v9fs_dentry_delete,
.d_release = v9fs_dentry_release,
vfid->filp = file;
kfree(fcall);
+ if((vfid->qid.version) && (v9ses->cache)) {
+ dprintk(DEBUG_VFS, "cached");
+ /* enable cached file options */
+ if(file->f_op == &v9fs_file_operations)
+ file->f_op = &v9fs_cached_file_operations;
+ }
+
return 0;
Clunk_Fid:
return total;
}
+const struct file_operations v9fs_cached_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = v9fs_file_write,
+ .open = v9fs_file_open,
+ .release = v9fs_dir_release,
+ .lock = v9fs_file_lock,
+ .mmap = generic_file_mmap,
+};
+
const struct file_operations v9fs_file_operations = {
.llseek = generic_file_llseek,
.read = v9fs_file_read,
goto error;
}
- dentry->d_op = &v9fs_dentry_operations;
+ if(v9ses->cache)
+ dentry->d_op = &v9fs_cached_dentry_operations;
+ else
+ dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode);
if (nd && nd->flags & LOOKUP_OPEN) {
goto error;
}
- dentry->d_op = &v9fs_dentry_operations;
+ if(v9ses->cache)
+ dentry->d_op = &v9fs_cached_dentry_operations;
+ else
+ dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode);
return 0;
sb = dir->i_sb;
v9ses = v9fs_inode2v9ses(dir);
- dentry->d_op = &v9fs_dentry_operations;
dirfid = v9fs_fid_lookup(dentry->d_parent);
if(IS_ERR(dirfid))
fid->qid = fcall->params.rstat.stat.qid;
v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
+ if((fid->qid.version)&&(v9ses->cache))
+ dentry->d_op = &v9fs_cached_dentry_operations;
+ else
+ dentry->d_op = &v9fs_dentry_operations;
d_add(dentry, inode);
kfree(fcall);
goto free_vfid;
}
- dentry->d_op = &v9fs_dentry_operations;
+ if(v9ses->cache)
+ dentry->d_op = &v9fs_cached_dentry_operations;
+ else
+ dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode);
return 0;