aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r--fs/afs/inode.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 320ffef11574..0747339011c3 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -19,6 +19,8 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/pagemap.h> 20#include <linux/pagemap.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/mount.h>
23#include <linux/namei.h>
22#include "internal.h" 24#include "internal.h"
23 25
24struct afs_iget_data { 26struct afs_iget_data {
@@ -102,6 +104,16 @@ static int afs_iget5_test(struct inode *inode, void *opaque)
102} 104}
103 105
104/* 106/*
107 * iget5() comparator for inode created by autocell operations
108 *
109 * These pseudo inodes don't match anything.
110 */
111static int afs_iget5_autocell_test(struct inode *inode, void *opaque)
112{
113 return 0;
114}
115
116/*
105 * iget5() inode initialiser 117 * iget5() inode initialiser
106 */ 118 */
107static int afs_iget5_set(struct inode *inode, void *opaque) 119static int afs_iget5_set(struct inode *inode, void *opaque)
@@ -118,6 +130,67 @@ static int afs_iget5_set(struct inode *inode, void *opaque)
118} 130}
119 131
120/* 132/*
133 * inode retrieval for autocell
134 */
135struct inode *afs_iget_autocell(struct inode *dir, const char *dev_name,
136 int namesz, struct key *key)
137{
138 struct afs_iget_data data;
139 struct afs_super_info *as;
140 struct afs_vnode *vnode;
141 struct super_block *sb;
142 struct inode *inode;
143 static atomic_t afs_autocell_ino;
144
145 _enter("{%x:%u},%*.*s,",
146 AFS_FS_I(dir)->fid.vid, AFS_FS_I(dir)->fid.vnode,
147 namesz, namesz, dev_name ?: "");
148
149 sb = dir->i_sb;
150 as = sb->s_fs_info;
151 data.volume = as->volume;
152 data.fid.vid = as->volume->vid;
153 data.fid.unique = 0;
154 data.fid.vnode = 0;
155
156 inode = iget5_locked(sb, atomic_inc_return(&afs_autocell_ino),
157 afs_iget5_autocell_test, afs_iget5_set,
158 &data);
159 if (!inode) {
160 _leave(" = -ENOMEM");
161 return ERR_PTR(-ENOMEM);
162 }
163
164 _debug("GOT INODE %p { ino=%lu, vl=%x, vn=%x, u=%x }",
165 inode, inode->i_ino, data.fid.vid, data.fid.vnode,
166 data.fid.unique);
167
168 vnode = AFS_FS_I(inode);
169
170 /* there shouldn't be an existing inode */
171 BUG_ON(!(inode->i_state & I_NEW));
172
173 inode->i_size = 0;
174 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
175 inode->i_op = &afs_autocell_inode_operations;
176 inode->i_nlink = 2;
177 inode->i_uid = 0;
178 inode->i_gid = 0;
179 inode->i_ctime.tv_sec = get_seconds();
180 inode->i_ctime.tv_nsec = 0;
181 inode->i_atime = inode->i_mtime = inode->i_ctime;
182 inode->i_blocks = 0;
183 inode->i_version = 0;
184 inode->i_generation = 0;
185
186 set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
187 inode->i_flags |= S_NOATIME;
188 unlock_new_inode(inode);
189 _leave(" = %p", inode);
190 return inode;
191}
192
193/*
121 * inode retrieval 194 * inode retrieval
122 */ 195 */
123struct inode *afs_iget(struct super_block *sb, struct key *key, 196struct inode *afs_iget(struct super_block *sb, struct key *key,
@@ -314,6 +387,19 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry,
314} 387}
315 388
316/* 389/*
390 * discard an AFS inode
391 */
392int afs_drop_inode(struct inode *inode)
393{
394 _enter("");
395
396 if (test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(inode)->flags))
397 return generic_delete_inode(inode);
398 else
399 return generic_drop_inode(inode);
400}
401
402/*
317 * clear an AFS inode 403 * clear an AFS inode
318 */ 404 */
319void afs_evict_inode(struct inode *inode) 405void afs_evict_inode(struct inode *inode)