diff options
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r-- | fs/afs/inode.c | 86 |
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 | ||
24 | struct afs_iget_data { | 26 | struct 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 | */ | ||
111 | static 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 | */ |
107 | static int afs_iget5_set(struct inode *inode, void *opaque) | 119 | static 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 | */ | ||
135 | struct 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 | */ |
123 | struct inode *afs_iget(struct super_block *sb, struct key *key, | 196 | struct 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 | */ | ||
392 | int 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 | */ |
319 | void afs_evict_inode(struct inode *inode) | 405 | void afs_evict_inode(struct inode *inode) |