aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/cache.c20
-rw-r--r--fs/9p/cache.h9
-rw-r--r--fs/9p/v9fs.c2
-rw-r--r--fs/9p/v9fs.h2
-rw-r--r--fs/9p/vfs_inode.c36
-rw-r--r--fs/9p/vfs_inode_dotl.c41
6 files changed, 81 insertions, 29 deletions
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 5b335c5086a1..945aa5f02f9b 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -108,11 +108,10 @@ static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
108 void *buffer, uint16_t bufmax) 108 void *buffer, uint16_t bufmax)
109{ 109{
110 const struct v9fs_inode *v9inode = cookie_netfs_data; 110 const struct v9fs_inode *v9inode = cookie_netfs_data;
111 memcpy(buffer, &v9inode->fscache_key->path, 111 memcpy(buffer, &v9inode->qid.path, sizeof(v9inode->qid.path));
112 sizeof(v9inode->fscache_key->path));
113 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &v9inode->vfs_inode, 112 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &v9inode->vfs_inode,
114 v9inode->fscache_key->path); 113 v9inode->qid.path);
115 return sizeof(v9inode->fscache_key->path); 114 return sizeof(v9inode->qid.path);
116} 115}
117 116
118static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data, 117static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
@@ -129,11 +128,10 @@ static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
129 void *buffer, uint16_t buflen) 128 void *buffer, uint16_t buflen)
130{ 129{
131 const struct v9fs_inode *v9inode = cookie_netfs_data; 130 const struct v9fs_inode *v9inode = cookie_netfs_data;
132 memcpy(buffer, &v9inode->fscache_key->version, 131 memcpy(buffer, &v9inode->qid.version, sizeof(v9inode->qid.version));
133 sizeof(v9inode->fscache_key->version));
134 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &v9inode->vfs_inode, 132 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &v9inode->vfs_inode,
135 v9inode->fscache_key->version); 133 v9inode->qid.version);
136 return sizeof(v9inode->fscache_key->version); 134 return sizeof(v9inode->qid.version);
137} 135}
138 136
139static enum 137static enum
@@ -143,11 +141,11 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
143{ 141{
144 const struct v9fs_inode *v9inode = cookie_netfs_data; 142 const struct v9fs_inode *v9inode = cookie_netfs_data;
145 143
146 if (buflen != sizeof(v9inode->fscache_key->version)) 144 if (buflen != sizeof(v9inode->qid.version))
147 return FSCACHE_CHECKAUX_OBSOLETE; 145 return FSCACHE_CHECKAUX_OBSOLETE;
148 146
149 if (memcmp(buffer, &v9inode->fscache_key->version, 147 if (memcmp(buffer, &v9inode->qid.version,
150 sizeof(v9inode->fscache_key->version))) 148 sizeof(v9inode->qid.version)))
151 return FSCACHE_CHECKAUX_OBSOLETE; 149 return FSCACHE_CHECKAUX_OBSOLETE;
152 150
153 return FSCACHE_CHECKAUX_OKAY; 151 return FSCACHE_CHECKAUX_OKAY;
diff --git a/fs/9p/cache.h b/fs/9p/cache.h
index 049507a5b01c..40cc54ced5d9 100644
--- a/fs/9p/cache.h
+++ b/fs/9p/cache.h
@@ -93,15 +93,6 @@ static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
93 BUG_ON(PageFsCache(page)); 93 BUG_ON(PageFsCache(page));
94} 94}
95 95
96static inline void v9fs_fscache_set_key(struct inode *inode,
97 struct p9_qid *qid)
98{
99 struct v9fs_inode *v9inode = V9FS_I(inode);
100 spin_lock(&v9inode->fscache_lock);
101 v9inode->fscache_key = qid;
102 spin_unlock(&v9inode->fscache_lock);
103}
104
105static inline void v9fs_fscache_wait_on_page_write(struct inode *inode, 96static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
106 struct page *page) 97 struct page *page)
107{ 98{
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index c82b017f51f3..8b7c6be2450b 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -487,8 +487,8 @@ static void v9fs_inode_init_once(void *foo)
487 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo; 487 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
488#ifdef CONFIG_9P_FSCACHE 488#ifdef CONFIG_9P_FSCACHE
489 v9inode->fscache = NULL; 489 v9inode->fscache = NULL;
490 v9inode->fscache_key = NULL;
491#endif 490#endif
491 memset(&v9inode->qid, 0, sizeof(v9inode->qid));
492 inode_init_once(&v9inode->vfs_inode); 492 inode_init_once(&v9inode->vfs_inode);
493} 493}
494 494
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index e5ebedfc5ed8..5d7392ead24b 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -125,8 +125,8 @@ struct v9fs_inode {
125#ifdef CONFIG_9P_FSCACHE 125#ifdef CONFIG_9P_FSCACHE
126 spinlock_t fscache_lock; 126 spinlock_t fscache_lock;
127 struct fscache_cookie *fscache; 127 struct fscache_cookie *fscache;
128 struct p9_qid *fscache_key;
129#endif 128#endif
129 struct p9_qid qid;
130 unsigned int cache_validity; 130 unsigned int cache_validity;
131 struct p9_fid *writeback_fid; 131 struct p9_fid *writeback_fid;
132 struct mutex v_mutex; 132 struct mutex v_mutex;
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a5a95372cd68..3d8a18ee78e6 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -216,7 +216,6 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
216 return NULL; 216 return NULL;
217#ifdef CONFIG_9P_FSCACHE 217#ifdef CONFIG_9P_FSCACHE
218 v9inode->fscache = NULL; 218 v9inode->fscache = NULL;
219 v9inode->fscache_key = NULL;
220 spin_lock_init(&v9inode->fscache_lock); 219 spin_lock_init(&v9inode->fscache_lock);
221#endif 220#endif
222 v9inode->writeback_fid = NULL; 221 v9inode->writeback_fid = NULL;
@@ -433,6 +432,37 @@ void v9fs_evict_inode(struct inode *inode)
433 } 432 }
434} 433}
435 434
435static int v9fs_test_inode(struct inode *inode, void *data)
436{
437 int umode;
438 struct v9fs_inode *v9inode = V9FS_I(inode);
439 struct p9_wstat *st = (struct p9_wstat *)data;
440 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
441
442 umode = p9mode2unixmode(v9ses, st->mode);
443 /* don't match inode of different type */
444 if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
445 return 0;
446
447 /* compare qid details */
448 if (memcmp(&v9inode->qid.version,
449 &st->qid.version, sizeof(v9inode->qid.version)))
450 return 0;
451
452 if (v9inode->qid.type != st->qid.type)
453 return 0;
454 return 1;
455}
456
457static int v9fs_set_inode(struct inode *inode, void *data)
458{
459 struct v9fs_inode *v9inode = V9FS_I(inode);
460 struct p9_wstat *st = (struct p9_wstat *)data;
461
462 memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
463 return 0;
464}
465
436static struct inode *v9fs_qid_iget(struct super_block *sb, 466static struct inode *v9fs_qid_iget(struct super_block *sb,
437 struct p9_qid *qid, 467 struct p9_qid *qid,
438 struct p9_wstat *st) 468 struct p9_wstat *st)
@@ -443,7 +473,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
443 struct v9fs_session_info *v9ses = sb->s_fs_info; 473 struct v9fs_session_info *v9ses = sb->s_fs_info;
444 474
445 i_ino = v9fs_qid2ino(qid); 475 i_ino = v9fs_qid2ino(qid);
446 inode = iget_locked(sb, i_ino); 476 inode = iget5_locked(sb, i_ino, v9fs_test_inode, v9fs_set_inode, st);
447 if (!inode) 477 if (!inode)
448 return ERR_PTR(-ENOMEM); 478 return ERR_PTR(-ENOMEM);
449 if (!(inode->i_state & I_NEW)) 479 if (!(inode->i_state & I_NEW))
@@ -453,6 +483,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
453 * FIXME!! we may need support for stale inodes 483 * FIXME!! we may need support for stale inodes
454 * later. 484 * later.
455 */ 485 */
486 inode->i_ino = i_ino;
456 umode = p9mode2unixmode(v9ses, st->mode); 487 umode = p9mode2unixmode(v9ses, st->mode);
457 retval = v9fs_init_inode(v9ses, inode, umode); 488 retval = v9fs_init_inode(v9ses, inode, umode);
458 if (retval) 489 if (retval)
@@ -460,7 +491,6 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
460 491
461 v9fs_stat2inode(st, inode, sb); 492 v9fs_stat2inode(st, inode, sb);
462#ifdef CONFIG_9P_FSCACHE 493#ifdef CONFIG_9P_FSCACHE
463 v9fs_fscache_set_key(inode, &st->qid);
464 v9fs_cache_inode_get_cookie(inode); 494 v9fs_cache_inode_get_cookie(inode);
465#endif 495#endif
466 unlock_new_inode(inode); 496 unlock_new_inode(inode);
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 32bbbe5aa689..dc9e7de38202 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -86,6 +86,38 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
86 return dentry; 86 return dentry;
87} 87}
88 88
89static int v9fs_test_inode_dotl(struct inode *inode, void *data)
90{
91 struct v9fs_inode *v9inode = V9FS_I(inode);
92 struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
93
94 /* don't match inode of different type */
95 if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
96 return 0;
97
98 if (inode->i_generation != st->st_gen)
99 return 0;
100
101 /* compare qid details */
102 if (memcmp(&v9inode->qid.version,
103 &st->qid.version, sizeof(v9inode->qid.version)))
104 return 0;
105
106 if (v9inode->qid.type != st->qid.type)
107 return 0;
108 return 1;
109}
110
111static int v9fs_set_inode_dotl(struct inode *inode, void *data)
112{
113 struct v9fs_inode *v9inode = V9FS_I(inode);
114 struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
115
116 memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
117 inode->i_generation = st->st_gen;
118 return 0;
119}
120
89static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, 121static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
90 struct p9_qid *qid, 122 struct p9_qid *qid,
91 struct p9_fid *fid, 123 struct p9_fid *fid,
@@ -97,7 +129,8 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
97 struct v9fs_session_info *v9ses = sb->s_fs_info; 129 struct v9fs_session_info *v9ses = sb->s_fs_info;
98 130
99 i_ino = v9fs_qid2ino(qid); 131 i_ino = v9fs_qid2ino(qid);
100 inode = iget_locked(sb, i_ino); 132 inode = iget5_locked(sb, i_ino, v9fs_test_inode_dotl,
133 v9fs_set_inode_dotl, st);
101 if (!inode) 134 if (!inode)
102 return ERR_PTR(-ENOMEM); 135 return ERR_PTR(-ENOMEM);
103 if (!(inode->i_state & I_NEW)) 136 if (!(inode->i_state & I_NEW))
@@ -107,13 +140,13 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
107 * FIXME!! we may need support for stale inodes 140 * FIXME!! we may need support for stale inodes
108 * later. 141 * later.
109 */ 142 */
143 inode->i_ino = i_ino;
110 retval = v9fs_init_inode(v9ses, inode, st->st_mode); 144 retval = v9fs_init_inode(v9ses, inode, st->st_mode);
111 if (retval) 145 if (retval)
112 goto error; 146 goto error;
113 147
114 v9fs_stat2inode_dotl(st, inode); 148 v9fs_stat2inode_dotl(st, inode);
115#ifdef CONFIG_9P_FSCACHE 149#ifdef CONFIG_9P_FSCACHE
116 v9fs_fscache_set_key(inode, &st->qid);
117 v9fs_cache_inode_get_cookie(inode); 150 v9fs_cache_inode_get_cookie(inode);
118#endif 151#endif
119 retval = v9fs_get_acl(inode, fid); 152 retval = v9fs_get_acl(inode, fid);
@@ -136,7 +169,7 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
136 struct p9_stat_dotl *st; 169 struct p9_stat_dotl *st;
137 struct inode *inode = NULL; 170 struct inode *inode = NULL;
138 171
139 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 172 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
140 if (IS_ERR(st)) 173 if (IS_ERR(st))
141 return ERR_CAST(st); 174 return ERR_CAST(st);
142 175
@@ -547,7 +580,7 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
547 inode->i_blocks = stat->st_blocks; 580 inode->i_blocks = stat->st_blocks;
548 } 581 }
549 if (stat->st_result_mask & P9_STATS_GEN) 582 if (stat->st_result_mask & P9_STATS_GEN)
550 inode->i_generation = stat->st_gen; 583 inode->i_generation = stat->st_gen;
551 584
552 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 585 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
553 * because the inode structure does not have fields for them. 586 * because the inode structure does not have fields for them.