diff options
Diffstat (limited to 'fs/9p')
-rw-r--r-- | fs/9p/fid.c | 3 | ||||
-rw-r--r-- | fs/9p/v9fs.c | 9 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 9 | ||||
-rw-r--r-- | fs/9p/v9fs_vfs.h | 2 | ||||
-rw-r--r-- | fs/9p/vfs_addr.c | 2 | ||||
-rw-r--r-- | fs/9p/vfs_dentry.c | 26 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 18 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 20 |
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 */ | ||
78 | enum { | ||
79 | CACHE_NONE, /* default */ | ||
80 | CACHE_LOOSE, /* no consistency */ | ||
81 | }; | ||
82 | |||
76 | extern struct dentry *v9fs_debugfs_root; | 83 | extern struct dentry *v9fs_debugfs_root; |
77 | 84 | ||
78 | int v9fs_session_init(struct v9fs_session_info *, const char *, char *); | 85 | int 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 @@ | |||
40 | extern struct file_system_type v9fs_fs_type; | 40 | extern struct file_system_type v9fs_fs_type; |
41 | extern const struct address_space_operations v9fs_addr_operations; | 41 | extern const struct address_space_operations v9fs_addr_operations; |
42 | extern const struct file_operations v9fs_file_operations; | 42 | extern const struct file_operations v9fs_file_operations; |
43 | extern const struct file_operations v9fs_cached_file_operations; | ||
43 | extern const struct file_operations v9fs_dir_operations; | 44 | extern const struct file_operations v9fs_dir_operations; |
44 | extern struct dentry_operations v9fs_dentry_operations; | 45 | extern struct dentry_operations v9fs_dentry_operations; |
46 | extern struct dentry_operations v9fs_cached_dentry_operations; | ||
45 | 47 | ||
46 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); | 48 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); |
47 | ino_t v9fs_qid2ino(struct v9fs_qid *qid); | 49 | ino_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 @@ | |||
53 | static int v9fs_dentry_delete(struct dentry *dentry) | 53 | static 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 | |||
69 | static 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 | ||
111 | struct dentry_operations v9fs_cached_dentry_operations = { | ||
112 | .d_delete = v9fs_cached_dentry_delete, | ||
113 | .d_release = v9fs_dentry_release, | ||
114 | }; | ||
115 | |||
90 | struct dentry_operations v9fs_dentry_operations = { | 116 | struct 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 | ||
84 | Clunk_Fid: | 91 | Clunk_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 | ||
248 | const 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 | |||
241 | const struct file_operations v9fs_file_operations = { | 259 | const 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 | ||