3 * vboxsf -- VirtualBox Guest Additions for Linux:
4 * Directory inode and file operations
8 * Copyright (C) 2006-2017 Oracle Corporation
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
22 * Open a directory. Read the complete content into a buffer.
26 * @returns 0 on success, Linux error code otherwise
28 static int sf_dir_open(struct inode
*inode
, struct file
*file
)
32 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
33 struct sf_dir_info
*sf_d
;
34 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
35 SHFLCREATEPARMS params
;
41 if (file
->private_data
)
43 LogFunc(("sf_dir_open() called on already opened directory '%s'\n",
44 sf_i
->path
->String
.utf8
));
48 sf_d
= sf_dir_info_alloc();
51 LogRelFunc(("could not allocate directory info for '%s'\n",
52 sf_i
->path
->String
.utf8
));
57 params
.Handle
= SHFL_HANDLE_NIL
;
58 params
.CreateFlags
= 0
60 | SHFL_CF_ACT_OPEN_IF_EXISTS
61 | SHFL_CF_ACT_FAIL_IF_NEW
65 LogFunc(("sf_dir_open(): calling VbglR0SfCreate, folder %s, flags %#x\n",
66 sf_i
->path
->String
.utf8
, params
.CreateFlags
));
67 rc
= VbglR0SfCreate(&client_handle
, &sf_g
->map
, sf_i
->path
, ¶ms
);
70 if (params
.Result
== SHFL_FILE_EXISTS
)
72 err
= sf_dir_read_all(sf_g
, sf_i
, sf_d
, params
.Handle
);
74 file
->private_data
= sf_d
;
79 rc
= VbglR0SfClose(&client_handle
, &sf_g
->map
, params
.Handle
);
81 LogFunc(("sf_dir_open(): VbglR0SfClose(%s) after err=%d failed rc=%Rrc\n",
82 sf_i
->path
->String
.utf8
, err
, rc
));
88 sf_dir_info_free(sf_d
);
95 * This is called when reference count of [file] goes to zero. Notify
96 * the host that it can free whatever is associated with this directory
97 * and deallocate our own internal buffers
101 * returns 0 on success, Linux error code otherwise
103 static int sf_dir_release(struct inode
*inode
, struct file
*file
)
107 if (file
->private_data
)
108 sf_dir_info_free(file
->private_data
);
114 * Translate RTFMODE into DT_xxx (in conjunction to rtDirType())
115 * @param fMode file mode
118 static int sf_get_d_type(RTFMODE fMode
)
121 switch (fMode
& RTFS_TYPE_MASK
)
123 case RTFS_TYPE_FIFO
: d_type
= DT_FIFO
; break;
124 case RTFS_TYPE_DEV_CHAR
: d_type
= DT_CHR
; break;
125 case RTFS_TYPE_DIRECTORY
: d_type
= DT_DIR
; break;
126 case RTFS_TYPE_DEV_BLOCK
: d_type
= DT_BLK
; break;
127 case RTFS_TYPE_FILE
: d_type
= DT_REG
; break;
128 case RTFS_TYPE_SYMLINK
: d_type
= DT_LNK
; break;
129 case RTFS_TYPE_SOCKET
: d_type
= DT_SOCK
; break;
130 case RTFS_TYPE_WHITEOUT
: d_type
= DT_WHT
; break;
131 default: d_type
= DT_UNKNOWN
; break;
137 * Extract element ([dir]->f_pos) from the directory [dir] into [d_name].
139 * @returns 0 for success, 1 for end reached, Linux error code otherwise.
141 static int sf_getdent(struct file
*dir
, char d_name
[NAME_MAX
], int *d_type
)
144 struct sf_glob_info
*sf_g
;
145 struct sf_dir_info
*sf_d
;
146 struct sf_inode_info
*sf_i
;
148 struct list_head
*pos
, *list
;
152 inode
= GET_F_DENTRY(dir
)->d_inode
;
153 sf_i
= GET_INODE_INFO(inode
);
154 sf_g
= GET_GLOB_INFO(inode
->i_sb
);
155 sf_d
= dir
->private_data
;
161 if (sf_i
->force_reread
)
165 SHFLCREATEPARMS params
;
168 params
.Handle
= SHFL_HANDLE_NIL
;
169 params
.CreateFlags
= 0
171 | SHFL_CF_ACT_OPEN_IF_EXISTS
172 | SHFL_CF_ACT_FAIL_IF_NEW
173 | SHFL_CF_ACCESS_READ
176 LogFunc(("sf_getdent: calling VbglR0SfCreate, folder %s, flags %#x\n",
177 sf_i
->path
->String
.utf8
, params
.CreateFlags
));
178 rc
= VbglR0SfCreate(&client_handle
, &sf_g
->map
, sf_i
->path
, ¶ms
);
181 LogFunc(("VbglR0SfCreate(%s) failed rc=%Rrc\n",
182 sf_i
->path
->String
.utf8
, rc
));
186 if (params
.Result
!= SHFL_FILE_EXISTS
)
188 LogFunc(("directory %s does not exist\n", sf_i
->path
->String
.utf8
));
189 sf_dir_info_free(sf_d
);
193 sf_dir_info_empty(sf_d
);
194 err
= sf_dir_read_all(sf_g
, sf_i
, sf_d
, params
.Handle
);
195 rc
= VbglR0SfClose(&client_handle
, &sf_g
->map
, params
.Handle
);
197 LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i
->path
->String
.utf8
, rc
));
201 sf_i
->force_reread
= 0;
205 list
= &sf_d
->info_list
;
206 list_for_each(pos
, list
)
208 struct sf_dir_buf
*b
;
212 b
= list_entry(pos
, struct sf_dir_buf
, head
);
213 if (dir
->f_pos
>= cur
+ b
->cEntries
)
219 for (i
= 0, info
= b
->buf
; i
< dir
->f_pos
- cur
; ++i
)
223 size
= offsetof(SHFLDIRINFO
, name
.String
) + info
->name
.u16Size
;
224 info
= (SHFLDIRINFO
*) ((uintptr_t) info
+ size
);
227 *d_type
= sf_get_d_type(info
->Info
.Attr
.fMode
);
229 return sf_nlscpy(sf_g
, d_name
, NAME_MAX
,
230 info
->name
.String
.utf8
, info
->name
.u16Length
);
237 * This is called when vfs wants to populate internal buffers with
238 * directory [dir]s contents. [opaque] is an argument to the
239 * [filldir]. [filldir] magically modifies it's argument - [opaque]
240 * and takes following additional arguments (which i in turn get from
241 * the host via sf_getdent):
243 * name : name of the entry (i must also supply it's length huh?)
244 * type : type of the entry (FILE | DIR | etc) (i ellect to use DT_UNKNOWN)
245 * pos : position/index of the entry
246 * ino : inode number of the entry (i fake those)
249 * f_pos : cursor into the directory listing
250 * private_data : mean of communication with the host side
252 * Extract elements from the directory listing (incrementing f_pos
253 * along the way) and feed them to [filldir] until:
255 * a. there are no more entries (i.e. sf_getdent set done to 1)
256 * b. failure to compute fake inode number
257 * c. filldir returns an error (see comment on that)
259 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
260 static int sf_dir_iterate(struct file
*dir
, struct dir_context
*ctx
)
262 static int sf_dir_read(struct file
*dir
, void *opaque
, filldir_t filldir
)
271 char d_name
[NAME_MAX
];
272 int d_type
= DT_UNKNOWN
;
274 err
= sf_getdent(dir
, d_name
, &d_type
);
285 /* skip erroneous entry and proceed */
286 LogFunc(("sf_getdent error %d\n", err
));
288 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
294 /* d_name now contains a valid entry name */
296 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
297 sanity
= ctx
->pos
+ 0xbeef;
299 sanity
= dir
->f_pos
+ 0xbeef;
302 if (sanity
- fake_ino
)
304 LogRelFunc(("can not compute ino\n"));
308 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
309 if (!dir_emit(ctx
, d_name
, strlen(d_name
), fake_ino
, d_type
))
311 LogFunc(("dir_emit failed\n"));
315 err
= filldir(opaque
, d_name
, strlen(d_name
), dir
->f_pos
, fake_ino
, d_type
);
318 LogFunc(("filldir returned error %d\n", err
));
319 /* Rely on the fact that filldir returns error
320 only when it runs out of space in opaque */
326 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
334 struct file_operations sf_dir_fops
=
337 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
338 .iterate
= sf_dir_iterate
,
340 .readdir
= sf_dir_read
,
342 .release
= sf_dir_release
,
343 .read
= generic_read_dir
344 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
345 , .llseek
= generic_file_llseek
353 * This is called when vfs failed to locate dentry in the cache. The
354 * job of this function is to allocate inode and link it to dentry.
355 * [dentry] contains the name to be looked in the [parent] directory.
356 * Failure to locate the name is not a "hard" error, in this case NULL
357 * inode is added to [dentry] and vfs should proceed trying to create
358 * the entry via other means. NULL(or "positive" pointer) ought to be
359 * returned in case of success and "negative" pointer on error
361 static struct dentry
*sf_lookup(struct inode
*parent
, struct dentry
*dentry
362 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
364 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
365 , struct nameidata
*nd
370 struct sf_inode_info
*sf_i
, *sf_new_i
;
371 struct sf_glob_info
*sf_g
;
375 SHFLFSOBJINFO fsinfo
;
378 sf_g
= GET_GLOB_INFO(parent
->i_sb
);
379 sf_i
= GET_INODE_INFO(parent
);
384 err
= sf_path_from_dentry(__func__
, sf_g
, sf_i
, dentry
, &path
);
388 err
= sf_stat(__func__
, sf_g
, path
, &fsinfo
, 1);
393 /* -ENOENT: add NULL inode to dentry so it later can be
394 created via call to create/mkdir/open */
403 sf_new_i
= kmalloc(sizeof(*sf_new_i
), GFP_KERNEL
);
406 LogRelFunc(("could not allocate memory for new inode info\n"));
410 sf_new_i
->handle
= SHFL_HANDLE_NIL
;
411 sf_new_i
->force_reread
= 0;
413 ino
= iunique(parent
->i_sb
, 1);
414 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
415 inode
= iget_locked(parent
->i_sb
, ino
);
417 inode
= iget(parent
->i_sb
, ino
);
421 LogFunc(("iget failed\n"));
422 err
= -ENOMEM
; /* XXX: ??? */
426 SET_INODE_INFO(inode
, sf_new_i
);
427 sf_init_inode(sf_g
, inode
, &fsinfo
);
428 sf_new_i
->path
= path
;
430 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
431 unlock_new_inode(inode
);
435 sf_i
->force_restat
= 0;
436 dentry
->d_time
= jiffies
;
437 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
438 d_set_d_op(dentry
, &sf_dentry_ops
);
440 dentry
->d_op
= &sf_dentry_ops
;
442 d_add(dentry
, inode
);
456 * This should allocate memory for sf_inode_info, compute a unique inode
457 * number, get an inode from vfs, initialize inode info, instantiate
460 * @param parent inode entry of the directory
461 * @param dentry directory cache entry
462 * @param path path name
463 * @param info file information
464 * @param handle handle
465 * @returns 0 on success, Linux error code otherwise
467 static int sf_instantiate(struct inode
*parent
, struct dentry
*dentry
,
468 SHFLSTRING
*path
, PSHFLFSOBJINFO info
, SHFLHANDLE handle
)
473 struct sf_inode_info
*sf_new_i
;
474 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(parent
->i_sb
);
479 sf_new_i
= kmalloc(sizeof(*sf_new_i
), GFP_KERNEL
);
482 LogRelFunc(("could not allocate inode info.\n"));
487 ino
= iunique(parent
->i_sb
, 1);
488 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
489 inode
= iget_locked(parent
->i_sb
, ino
);
491 inode
= iget(parent
->i_sb
, ino
);
495 LogFunc(("iget failed\n"));
500 sf_init_inode(sf_g
, inode
, info
);
501 sf_new_i
->path
= path
;
502 SET_INODE_INFO(inode
, sf_new_i
);
503 sf_new_i
->force_restat
= 1;
504 sf_new_i
->force_reread
= 0;
506 d_instantiate(dentry
, inode
);
508 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
509 unlock_new_inode(inode
);
512 /* Store this handle if we leave the handle open. */
513 sf_new_i
->handle
= handle
;
525 * Create a new regular file / directory.
527 * @param parent inode of the directory
528 * @param dentry directory cache entry
529 * @param mode file mode
530 * @param fDirectory true if directory, false otherwise
531 * @returns 0 on success, Linux error code otherwise
533 static int sf_create_aux(struct inode
*parent
, struct dentry
*dentry
,
534 umode_t mode
, int fDirectory
)
537 SHFLCREATEPARMS params
;
539 struct sf_inode_info
*sf_i
= GET_INODE_INFO(parent
);
540 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(parent
->i_sb
);
546 err
= sf_path_from_dentry(__func__
, sf_g
, sf_i
, dentry
, &path
);
551 params
.Handle
= SHFL_HANDLE_NIL
;
552 params
.CreateFlags
= 0
553 | SHFL_CF_ACT_CREATE_IF_NEW
554 | SHFL_CF_ACT_FAIL_IF_EXISTS
555 | SHFL_CF_ACCESS_READWRITE
556 | (fDirectory
? SHFL_CF_DIRECTORY
: 0)
558 params
.Info
.Attr
.fMode
= 0
559 | (fDirectory
? RTFS_TYPE_DIRECTORY
: RTFS_TYPE_FILE
)
562 params
.Info
.Attr
.enmAdditional
= RTFSOBJATTRADD_NOTHING
;
564 LogFunc(("sf_create_aux: calling VbglR0SfCreate, folder %s, flags %#x\n",
565 path
->String
.utf8
, params
.CreateFlags
));
566 rc
= VbglR0SfCreate(&client_handle
, &sf_g
->map
, path
, ¶ms
);
569 if (rc
== VERR_WRITE_PROTECT
)
575 LogFunc(("(%d): VbglR0SfCreate(%s) failed rc=%Rrc\n",
576 fDirectory
, sf_i
->path
->String
.utf8
, rc
));
580 if (params
.Result
!= SHFL_FILE_CREATED
)
583 LogFunc(("(%d): could not create file %s result=%d\n",
584 fDirectory
, sf_i
->path
->String
.utf8
, params
.Result
));
588 err
= sf_instantiate(parent
, dentry
, path
, ¶ms
.Info
,
589 fDirectory
? SHFL_HANDLE_NIL
: params
.Handle
);
592 LogFunc(("(%d): could not instantiate dentry for %s err=%d\n",
593 fDirectory
, sf_i
->path
->String
.utf8
, err
));
598 * Don't close this handle right now. We assume that the same file is
599 * opened with sf_reg_open() and later closed with sf_reg_close(). Save
600 * the handle in between. Does not apply to directories. True?
604 rc
= VbglR0SfClose(&client_handle
, &sf_g
->map
, params
.Handle
);
606 LogFunc(("(%d): VbglR0SfClose failed rc=%Rrc\n", fDirectory
, rc
));
609 sf_i
->force_restat
= 1;
613 rc
= VbglR0SfClose(&client_handle
, &sf_g
->map
, params
.Handle
);
615 LogFunc(("(%d): VbglR0SfClose failed rc=%Rrc\n", fDirectory
, rc
));
625 * Create a new regular file.
627 * @param parent inode of the directory
628 * @param dentry directory cache entry
629 * @param mode file mode
630 * @param excl Possible O_EXCL...
631 * @returns 0 on success, Linux error code otherwise
633 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(DOXYGEN_RUNNING)
634 static int sf_create(struct inode
*parent
, struct dentry
*dentry
, umode_t mode
, bool excl
)
635 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
636 static int sf_create(struct inode
*parent
, struct dentry
*dentry
, umode_t mode
, struct nameidata
*nd
)
637 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
638 static int sf_create(struct inode
*parent
, struct dentry
*dentry
, int mode
, struct nameidata
*nd
)
640 static int sf_create(struct inode
*parent
, struct dentry
*dentry
, int mode
)
644 return sf_create_aux(parent
, dentry
, mode
, 0);
648 * Create a new directory.
650 * @param parent inode of the directory
651 * @param dentry directory cache entry
652 * @param mode file mode
653 * @returns 0 on success, Linux error code otherwise
655 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
656 static int sf_mkdir(struct inode
*parent
, struct dentry
*dentry
, umode_t mode
)
658 static int sf_mkdir(struct inode
*parent
, struct dentry
*dentry
, int mode
)
662 return sf_create_aux(parent
, dentry
, mode
, 1);
666 * Remove a regular file / directory.
668 * @param parent inode of the directory
669 * @param dentry directory cache entry
670 * @param fDirectory true if directory, false otherwise
671 * @returns 0 on success, Linux error code otherwise
673 static int sf_unlink_aux(struct inode
*parent
, struct dentry
*dentry
, int fDirectory
)
676 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(parent
->i_sb
);
677 struct sf_inode_info
*sf_i
= GET_INODE_INFO(parent
);
684 err
= sf_path_from_dentry(__func__
, sf_g
, sf_i
, dentry
, &path
);
688 fFlags
= fDirectory
? SHFL_REMOVE_DIR
: SHFL_REMOVE_FILE
;
690 && ((dentry
->d_inode
->i_mode
& S_IFLNK
) == S_IFLNK
))
691 fFlags
|= SHFL_REMOVE_SYMLINK
;
692 rc
= VbglR0SfRemove(&client_handle
, &sf_g
->map
, path
, fFlags
);
695 LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc\n", fDirectory
, path
->String
.utf8
, rc
));
696 err
= -RTErrConvertToErrno(rc
);
700 /* directory access/change time changed */
701 sf_i
->force_restat
= 1;
702 /* directory content changed */
703 sf_i
->force_reread
= 1;
715 * Remove a regular file.
717 * @param parent inode of the directory
718 * @param dentry directory cache entry
719 * @returns 0 on success, Linux error code otherwise
721 static int sf_unlink(struct inode
*parent
, struct dentry
*dentry
)
724 return sf_unlink_aux(parent
, dentry
, 0);
728 * Remove a directory.
730 * @param parent inode of the directory
731 * @param dentry directory cache entry
732 * @returns 0 on success, Linux error code otherwise
734 static int sf_rmdir(struct inode
*parent
, struct dentry
*dentry
)
737 return sf_unlink_aux(parent
, dentry
, 1);
741 * Rename a regular file / directory.
743 * @param old_parent inode of the old parent directory
744 * @param old_dentry old directory cache entry
745 * @param new_parent inode of the new parent directory
746 * @param new_dentry new directory cache entry
748 * @returns 0 on success, Linux error code otherwise
750 static int sf_rename(struct inode
*old_parent
, struct dentry
*old_dentry
,
751 struct inode
*new_parent
, struct dentry
*new_dentry
752 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
757 int err
= 0, rc
= VINF_SUCCESS
;
758 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(old_parent
->i_sb
);
762 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
765 LogFunc(("rename with flags=%x\n", flags
));
770 if (sf_g
!= GET_GLOB_INFO(new_parent
->i_sb
))
772 LogFunc(("rename with different roots\n"));
777 struct sf_inode_info
*sf_old_i
= GET_INODE_INFO(old_parent
);
778 struct sf_inode_info
*sf_new_i
= GET_INODE_INFO(new_parent
);
779 /* As we save the relative path inside the inode structure, we need to change
780 this if the rename is successful. */
781 struct sf_inode_info
*sf_file_i
= GET_INODE_INFO(old_dentry
->d_inode
);
782 SHFLSTRING
*old_path
;
783 SHFLSTRING
*new_path
;
789 old_path
= sf_file_i
->path
;
790 err
= sf_path_from_dentry(__func__
, sf_g
, sf_new_i
,
791 new_dentry
, &new_path
);
793 LogFunc(("failed to create new path\n"));
796 int fDir
= ((old_dentry
->d_inode
->i_mode
& S_IFDIR
) != 0);
798 rc
= VbglR0SfRename(&client_handle
, &sf_g
->map
, old_path
,
799 new_path
, fDir
? 0 : SHFL_RENAME_FILE
| SHFL_RENAME_REPLACE_IF_EXISTS
);
803 sf_new_i
->force_restat
= 1;
804 sf_old_i
->force_restat
= 1; /* XXX: needed? */
805 /* Set the new relative path in the inode. */
806 sf_file_i
->path
= new_path
;
810 LogFunc(("VbglR0SfRename failed rc=%Rrc\n", rc
));
811 err
= -RTErrConvertToErrno(rc
);
819 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
820 static int sf_symlink(struct inode
*parent
, struct dentry
*dentry
, const char *symname
)
824 struct sf_inode_info
*sf_i
;
825 struct sf_glob_info
*sf_g
;
826 SHFLSTRING
*path
, *ssymname
;
828 int symname_len
= strlen(symname
) + 1;
831 sf_g
= GET_GLOB_INFO(parent
->i_sb
);
832 sf_i
= GET_INODE_INFO(parent
);
837 err
= sf_path_from_dentry(__func__
, sf_g
, sf_i
, dentry
, &path
);
841 ssymname
= kmalloc(offsetof(SHFLSTRING
, String
.utf8
) + symname_len
, GFP_KERNEL
);
844 LogRelFunc(("kmalloc failed, caller=sf_symlink\n"));
849 ssymname
->u16Length
= symname_len
- 1;
850 ssymname
->u16Size
= symname_len
;
851 memcpy(ssymname
->String
.utf8
, symname
, symname_len
);
853 rc
= VbglR0SfSymlink(&client_handle
, &sf_g
->map
, path
, ssymname
, &info
);
858 if (rc
== VERR_WRITE_PROTECT
)
863 LogFunc(("VbglR0SfSymlink(%s) failed rc=%Rrc\n",
864 sf_i
->path
->String
.utf8
, rc
));
869 err
= sf_instantiate(parent
, dentry
, path
, &info
, SHFL_HANDLE_NIL
);
872 LogFunc(("could not instantiate dentry for %s err=%d\n",
873 sf_i
->path
->String
.utf8
, err
));
877 sf_i
->force_restat
= 1;
887 struct inode_operations sf_dir_iops
=
895 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
896 .revalidate
= sf_inode_revalidate
898 .getattr
= sf_getattr
,
899 .setattr
= sf_setattr
,
900 .symlink
= sf_symlink