aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/fid.c3
-rw-r--r--fs/9p/v9fs.c9
-rw-r--r--fs/9p/v9fs.h9
-rw-r--r--fs/9p/v9fs_vfs.h2
-rw-r--r--fs/9p/vfs_addr.c2
-rw-r--r--fs/9p/vfs_dentry.c26
-rw-r--r--fs/9p/vfs_file.c18
-rw-r--r--fs/9p/vfs_inode.c20
8 files changed, 82 insertions, 7 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index a9b6301a04fc..90419715c7e9 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -136,7 +136,8 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
136} 136}
137 137
138/** 138/**
139 * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it 139 * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
140 * release it
140 * @dentry: dentry to look for fid in 141 * @dentry: dentry to look for fid in
141 * 142 *
142 * find a fid in the dentry and then clone to a new private fid 143 * find a fid in the dentry and then clone to a new private fid
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index d9b561ba5e58..6ad6f192b6e4 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -53,6 +53,8 @@ enum {
53 Opt_uname, Opt_remotename, 53 Opt_uname, Opt_remotename,
54 /* Options that take no arguments */ 54 /* Options that take no arguments */
55 Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, 55 Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
56 /* Cache options */
57 Opt_cache_loose,
56 /* Error token */ 58 /* Error token */
57 Opt_err 59 Opt_err
58}; 60};
@@ -76,6 +78,8 @@ static match_table_t tokens = {
76 {Opt_fd, "fd"}, 78 {Opt_fd, "fd"},
77 {Opt_legacy, "noextend"}, 79 {Opt_legacy, "noextend"},
78 {Opt_nodevmap, "nodevmap"}, 80 {Opt_nodevmap, "nodevmap"},
81 {Opt_cache_loose, "cache=loose"},
82 {Opt_cache_loose, "loose"},
79 {Opt_err, NULL} 83 {Opt_err, NULL}
80}; 84};
81 85
@@ -106,6 +110,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
106 v9ses->debug = 0; 110 v9ses->debug = 0;
107 v9ses->rfdno = ~0; 111 v9ses->rfdno = ~0;
108 v9ses->wfdno = ~0; 112 v9ses->wfdno = ~0;
113 v9ses->cache = 0;
109 114
110 if (!options) 115 if (!options)
111 return; 116 return;
@@ -121,7 +126,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
121 "integer field, but no integer?\n"); 126 "integer field, but no integer?\n");
122 continue; 127 continue;
123 } 128 }
124
125 } 129 }
126 switch (token) { 130 switch (token) {
127 case Opt_port: 131 case Opt_port:
@@ -169,6 +173,9 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
169 case Opt_nodevmap: 173 case Opt_nodevmap:
170 v9ses->nodev = 1; 174 v9ses->nodev = 1;
171 break; 175 break;
176 case Opt_cache_loose:
177 v9ses->cache = CACHE_LOOSE;
178 break;
172 default: 179 default:
173 continue; 180 continue;
174 } 181 }
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index c134d104cb28..820bf5ca35d8 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -47,7 +47,7 @@ struct v9fs_session_info {
47 unsigned int afid; /* authentication fid */ 47 unsigned int afid; /* authentication fid */
48 unsigned int rfdno; /* read file descriptor number */ 48 unsigned int rfdno; /* read file descriptor number */
49 unsigned int wfdno; /* write file descriptor number */ 49 unsigned int wfdno; /* write file descriptor number */
50 50 unsigned int cache; /* cache mode */
51 51
52 char *name; /* user name to mount as */ 52 char *name; /* user name to mount as */
53 char *remotename; /* name of remote hierarchy being mounted */ 53 char *remotename; /* name of remote hierarchy being mounted */
@@ -73,6 +73,13 @@ enum {
73 PROTO_FD, 73 PROTO_FD,
74}; 74};
75 75
76/* possible values of ->cache */
77/* eventually support loose, tight, time, session, default always none */
78enum {
79 CACHE_NONE, /* default */
80 CACHE_LOOSE, /* no consistency */
81};
82
76extern struct dentry *v9fs_debugfs_root; 83extern struct dentry *v9fs_debugfs_root;
77 84
78int v9fs_session_init(struct v9fs_session_info *, const char *, char *); 85int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 450b0c1b385e..8ada4c5c5d70 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -40,8 +40,10 @@
40extern struct file_system_type v9fs_fs_type; 40extern struct file_system_type v9fs_fs_type;
41extern const struct address_space_operations v9fs_addr_operations; 41extern const struct address_space_operations v9fs_addr_operations;
42extern const struct file_operations v9fs_file_operations; 42extern const struct file_operations v9fs_file_operations;
43extern const struct file_operations v9fs_cached_file_operations;
43extern const struct file_operations v9fs_dir_operations; 44extern const struct file_operations v9fs_dir_operations;
44extern struct dentry_operations v9fs_dentry_operations; 45extern struct dentry_operations v9fs_dentry_operations;
46extern struct dentry_operations v9fs_cached_dentry_operations;
45 47
46struct inode *v9fs_get_inode(struct super_block *sb, int mode); 48struct inode *v9fs_get_inode(struct super_block *sb, int mode);
47ino_t v9fs_qid2ino(struct v9fs_qid *qid); 49ino_t v9fs_qid2ino(struct v9fs_qid *qid);
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index cc24abf232d5..bed48fa96521 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -63,6 +63,8 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page)
63 int total = 0; 63 int total = 0;
64 int result = 0; 64 int result = 0;
65 65
66 dprintk(DEBUG_VFS, "\n");
67
66 buffer = kmap(page); 68 buffer = kmap(page);
67 do { 69 do {
68 if (count < rsize) 70 if (count < rsize)
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index 062daa6000ab..ddffd8aa902d 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -53,10 +53,31 @@
53static int v9fs_dentry_delete(struct dentry *dentry) 53static int v9fs_dentry_delete(struct dentry *dentry)
54{ 54{
55 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 55 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
56
56 return 1; 57 return 1;
57} 58}
58 59
59/** 60/**
61 * v9fs_cached_dentry_delete - called when dentry refcount equals 0
62 * @dentry: dentry in question
63 *
64 * Only return 1 if our inode is invalid. Only non-synthetic files
65 * (ones without mtime == 0) should be calling this function.
66 *
67 */
68
69static int v9fs_cached_dentry_delete(struct dentry *dentry)
70{
71 struct inode *inode = dentry->d_inode;
72 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
73
74 if(!inode)
75 return 1;
76
77 return 0;
78}
79
80/**
60 * v9fs_dentry_release - called when dentry is going to be freed 81 * v9fs_dentry_release - called when dentry is going to be freed
61 * @dentry: dentry that is being release 82 * @dentry: dentry that is being release
62 * 83 *
@@ -87,6 +108,11 @@ void v9fs_dentry_release(struct dentry *dentry)
87 } 108 }
88} 109}
89 110
111struct dentry_operations v9fs_cached_dentry_operations = {
112 .d_delete = v9fs_cached_dentry_delete,
113 .d_release = v9fs_dentry_release,
114};
115
90struct dentry_operations v9fs_dentry_operations = { 116struct dentry_operations v9fs_dentry_operations = {
91 .d_delete = v9fs_dentry_delete, 117 .d_delete = v9fs_dentry_delete,
92 .d_release = v9fs_dentry_release, 118 .d_release = v9fs_dentry_release,
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 6c78343cf690..653dfa5b2531 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -79,6 +79,13 @@ int v9fs_file_open(struct inode *inode, struct file *file)
79 vfid->filp = file; 79 vfid->filp = file;
80 kfree(fcall); 80 kfree(fcall);
81 81
82 if((vfid->qid.version) && (v9ses->cache)) {
83 dprintk(DEBUG_VFS, "cached");
84 /* enable cached file options */
85 if(file->f_op == &v9fs_file_operations)
86 file->f_op = &v9fs_cached_file_operations;
87 }
88
82 return 0; 89 return 0;
83 90
84Clunk_Fid: 91Clunk_Fid:
@@ -238,6 +245,17 @@ v9fs_file_write(struct file *filp, const char __user * data,
238 return total; 245 return total;
239} 246}
240 247
248const struct file_operations v9fs_cached_file_operations = {
249 .llseek = generic_file_llseek,
250 .read = do_sync_read,
251 .aio_read = generic_file_aio_read,
252 .write = v9fs_file_write,
253 .open = v9fs_file_open,
254 .release = v9fs_dir_release,
255 .lock = v9fs_file_lock,
256 .mmap = generic_file_mmap,
257};
258
241const struct file_operations v9fs_file_operations = { 259const struct file_operations v9fs_file_operations = {
242 .llseek = generic_file_llseek, 260 .llseek = generic_file_llseek,
243 .read = v9fs_file_read, 261 .read = v9fs_file_read,
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 5cf22134826b..124a085d1f2e 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -504,7 +504,10 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
504 goto error; 504 goto error;
505 } 505 }
506 506
507 dentry->d_op = &v9fs_dentry_operations; 507 if(v9ses->cache)
508 dentry->d_op = &v9fs_cached_dentry_operations;
509 else
510 dentry->d_op = &v9fs_dentry_operations;
508 d_instantiate(dentry, inode); 511 d_instantiate(dentry, inode);
509 512
510 if (nd && nd->flags & LOOKUP_OPEN) { 513 if (nd && nd->flags & LOOKUP_OPEN) {
@@ -589,7 +592,10 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
589 goto error; 592 goto error;
590 } 593 }
591 594
592 dentry->d_op = &v9fs_dentry_operations; 595 if(v9ses->cache)
596 dentry->d_op = &v9fs_cached_dentry_operations;
597 else
598 dentry->d_op = &v9fs_dentry_operations;
593 d_instantiate(dentry, inode); 599 d_instantiate(dentry, inode);
594 return 0; 600 return 0;
595 601
@@ -626,7 +632,6 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
626 632
627 sb = dir->i_sb; 633 sb = dir->i_sb;
628 v9ses = v9fs_inode2v9ses(dir); 634 v9ses = v9fs_inode2v9ses(dir);
629 dentry->d_op = &v9fs_dentry_operations;
630 dirfid = v9fs_fid_lookup(dentry->d_parent); 635 dirfid = v9fs_fid_lookup(dentry->d_parent);
631 636
632 if(IS_ERR(dirfid)) 637 if(IS_ERR(dirfid))
@@ -697,6 +702,10 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
697 702
698 fid->qid = fcall->params.rstat.stat.qid; 703 fid->qid = fcall->params.rstat.stat.qid;
699 v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); 704 v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
705 if((fid->qid.version)&&(v9ses->cache))
706 dentry->d_op = &v9fs_cached_dentry_operations;
707 else
708 dentry->d_op = &v9fs_dentry_operations;
700 709
701 d_add(dentry, inode); 710 d_add(dentry, inode);
702 kfree(fcall); 711 kfree(fcall);
@@ -1184,7 +1193,10 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1184 goto free_vfid; 1193 goto free_vfid;
1185 } 1194 }
1186 1195
1187 dentry->d_op = &v9fs_dentry_operations; 1196 if(v9ses->cache)
1197 dentry->d_op = &v9fs_cached_dentry_operations;
1198 else
1199 dentry->d_op = &v9fs_dentry_operations;
1188 d_instantiate(dentry, inode); 1200 d_instantiate(dentry, inode);
1189 return 0; 1201 return 0;
1190 1202