aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c32
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c128
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c7
3 files changed, 6 insertions, 161 deletions
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 24fd598af846..7f7abec25e14 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -148,7 +148,6 @@ xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
148{ 148{
149 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid; 149 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
150 struct inode *inode = NULL; 150 struct inode *inode = NULL;
151 struct dentry *result;
152 151
153 if (fh_len < xfs_fileid_length(fileid_type)) 152 if (fh_len < xfs_fileid_length(fileid_type))
154 return NULL; 153 return NULL;
@@ -164,16 +163,7 @@ xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
164 break; 163 break;
165 } 164 }
166 165
167 if (!inode) 166 return d_obtain_alias(inode);
168 return NULL;
169 if (IS_ERR(inode))
170 return ERR_CAST(inode);
171 result = d_alloc_anon(inode);
172 if (!result) {
173 iput(inode);
174 return ERR_PTR(-ENOMEM);
175 }
176 return result;
177} 167}
178 168
179STATIC struct dentry * 169STATIC struct dentry *
@@ -182,7 +172,6 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
182{ 172{
183 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid; 173 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
184 struct inode *inode = NULL; 174 struct inode *inode = NULL;
185 struct dentry *result;
186 175
187 switch (fileid_type) { 176 switch (fileid_type) {
188 case FILEID_INO32_GEN_PARENT: 177 case FILEID_INO32_GEN_PARENT:
@@ -195,16 +184,7 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
195 break; 184 break;
196 } 185 }
197 186
198 if (!inode) 187 return d_obtain_alias(inode);
199 return NULL;
200 if (IS_ERR(inode))
201 return ERR_CAST(inode);
202 result = d_alloc_anon(inode);
203 if (!result) {
204 iput(inode);
205 return ERR_PTR(-ENOMEM);
206 }
207 return result;
208} 188}
209 189
210STATIC struct dentry * 190STATIC struct dentry *
@@ -213,18 +193,12 @@ xfs_fs_get_parent(
213{ 193{
214 int error; 194 int error;
215 struct xfs_inode *cip; 195 struct xfs_inode *cip;
216 struct dentry *parent;
217 196
218 error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL); 197 error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL);
219 if (unlikely(error)) 198 if (unlikely(error))
220 return ERR_PTR(-error); 199 return ERR_PTR(-error);
221 200
222 parent = d_alloc_anon(VFS_I(cip)); 201 return d_obtain_alias(VFS_I(cip));
223 if (unlikely(!parent)) {
224 iput(VFS_I(cip));
225 return ERR_PTR(-ENOMEM);
226 }
227 return parent;
228} 202}
229 203
230const struct export_operations xfs_export_operations = { 204const struct export_operations xfs_export_operations = {
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 5311c1acdd40..3fee790f138b 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -204,15 +204,6 @@ xfs_file_fsync(
204 return -xfs_fsync(XFS_I(dentry->d_inode)); 204 return -xfs_fsync(XFS_I(dentry->d_inode));
205} 205}
206 206
207/*
208 * Unfortunately we can't just use the clean and simple readdir implementation
209 * below, because nfs might call back into ->lookup from the filldir callback
210 * and that will deadlock the low-level btree code.
211 *
212 * Hopefully we'll find a better workaround that allows to use the optimal
213 * version at least for local readdirs for 2.6.25.
214 */
215#if 0
216STATIC int 207STATIC int
217xfs_file_readdir( 208xfs_file_readdir(
218 struct file *filp, 209 struct file *filp,
@@ -244,125 +235,6 @@ xfs_file_readdir(
244 return -error; 235 return -error;
245 return 0; 236 return 0;
246} 237}
247#else
248
249struct hack_dirent {
250 u64 ino;
251 loff_t offset;
252 int namlen;
253 unsigned int d_type;
254 char name[];
255};
256
257struct hack_callback {
258 char *dirent;
259 size_t len;
260 size_t used;
261};
262
263STATIC int
264xfs_hack_filldir(
265 void *__buf,
266 const char *name,
267 int namlen,
268 loff_t offset,
269 u64 ino,
270 unsigned int d_type)
271{
272 struct hack_callback *buf = __buf;
273 struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used);
274 unsigned int reclen;
275
276 reclen = ALIGN(sizeof(struct hack_dirent) + namlen, sizeof(u64));
277 if (buf->used + reclen > buf->len)
278 return -EINVAL;
279
280 de->namlen = namlen;
281 de->offset = offset;
282 de->ino = ino;
283 de->d_type = d_type;
284 memcpy(de->name, name, namlen);
285 buf->used += reclen;
286 return 0;
287}
288
289STATIC int
290xfs_file_readdir(
291 struct file *filp,
292 void *dirent,
293 filldir_t filldir)
294{
295 struct inode *inode = filp->f_path.dentry->d_inode;
296 xfs_inode_t *ip = XFS_I(inode);
297 struct hack_callback buf;
298 struct hack_dirent *de;
299 int error;
300 loff_t size;
301 int eof = 0;
302 xfs_off_t start_offset, curr_offset, offset;
303
304 /*
305 * Try fairly hard to get memory
306 */
307 buf.len = PAGE_CACHE_SIZE;
308 do {
309 buf.dirent = kmalloc(buf.len, GFP_KERNEL);
310 if (buf.dirent)
311 break;
312 buf.len >>= 1;
313 } while (buf.len >= 1024);
314
315 if (!buf.dirent)
316 return -ENOMEM;
317
318 curr_offset = filp->f_pos;
319 if (curr_offset == 0x7fffffff)
320 offset = 0xffffffff;
321 else
322 offset = filp->f_pos;
323
324 while (!eof) {
325 unsigned int reclen;
326
327 start_offset = offset;
328
329 buf.used = 0;
330 error = -xfs_readdir(ip, &buf, buf.len, &offset,
331 xfs_hack_filldir);
332 if (error || offset == start_offset) {
333 size = 0;
334 break;
335 }
336
337 size = buf.used;
338 de = (struct hack_dirent *)buf.dirent;
339 while (size > 0) {
340 curr_offset = de->offset /* & 0x7fffffff */;
341 if (filldir(dirent, de->name, de->namlen,
342 curr_offset & 0x7fffffff,
343 de->ino, de->d_type)) {
344 goto done;
345 }
346
347 reclen = ALIGN(sizeof(struct hack_dirent) + de->namlen,
348 sizeof(u64));
349 size -= reclen;
350 de = (struct hack_dirent *)((char *)de + reclen);
351 }
352 }
353
354 done:
355 if (!error) {
356 if (size == 0)
357 filp->f_pos = offset & 0x7fffffff;
358 else if (de)
359 filp->f_pos = curr_offset;
360 }
361
362 kfree(buf.dirent);
363 return error;
364}
365#endif
366 238
367STATIC int 239STATIC int
368xfs_file_mmap( 240xfs_file_mmap(
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 48799ba7e3e6..d3438c72dcaf 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -311,11 +311,10 @@ xfs_open_by_handle(
311 return new_fd; 311 return new_fd;
312 } 312 }
313 313
314 dentry = d_alloc_anon(inode); 314 dentry = d_obtain_alias(inode);
315 if (dentry == NULL) { 315 if (IS_ERR(dentry)) {
316 iput(inode);
317 put_unused_fd(new_fd); 316 put_unused_fd(new_fd);
318 return -XFS_ERROR(ENOMEM); 317 return PTR_ERR(dentry);
319 } 318 }
320 319
321 /* Ensure umount returns EBUSY on umounts while this file is open. */ 320 /* Ensure umount returns EBUSY on umounts while this file is open. */