diff options
author | Dipankar Sarma <dipankar@in.ibm.com> | 2005-09-09 16:04:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:55 -0400 |
commit | badf16621c1f9d1ac753be056fce11b43d6e0be5 (patch) | |
tree | 3fdf833fdf2e3d3a439090743539680449ec3428 /fs/open.c | |
parent | c0dfb2905126e9e94edebbce8d3e05001301f52d (diff) |
[PATCH] files: break up files struct
In order for the RCU to work, the file table array, sets and their sizes must
be updated atomically. Instead of ensuring this through too many memory
barriers, we put the arrays and their sizes in a separate structure. This
patch takes the first step of putting the file table elements in a separate
structure fdtable that is embedded withing files_struct. It also changes all
the users to refer to the file table using files_fdtable() macro. Subsequent
applciation of RCU becomes easier after this.
Signed-off-by: Dipankar Sarma <dipankar@in.ibm.com>
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 41 |
1 files changed, 24 insertions, 17 deletions
@@ -842,14 +842,16 @@ int get_unused_fd(void) | |||
842 | { | 842 | { |
843 | struct files_struct * files = current->files; | 843 | struct files_struct * files = current->files; |
844 | int fd, error; | 844 | int fd, error; |
845 | struct fdtable *fdt; | ||
845 | 846 | ||
846 | error = -EMFILE; | 847 | error = -EMFILE; |
847 | spin_lock(&files->file_lock); | 848 | spin_lock(&files->file_lock); |
848 | 849 | ||
849 | repeat: | 850 | repeat: |
850 | fd = find_next_zero_bit(files->open_fds->fds_bits, | 851 | fdt = files_fdtable(files); |
851 | files->max_fdset, | 852 | fd = find_next_zero_bit(fdt->open_fds->fds_bits, |
852 | files->next_fd); | 853 | fdt->max_fdset, |
854 | fdt->next_fd); | ||
853 | 855 | ||
854 | /* | 856 | /* |
855 | * N.B. For clone tasks sharing a files structure, this test | 857 | * N.B. For clone tasks sharing a files structure, this test |
@@ -872,14 +874,14 @@ repeat: | |||
872 | goto repeat; | 874 | goto repeat; |
873 | } | 875 | } |
874 | 876 | ||
875 | FD_SET(fd, files->open_fds); | 877 | FD_SET(fd, fdt->open_fds); |
876 | FD_CLR(fd, files->close_on_exec); | 878 | FD_CLR(fd, fdt->close_on_exec); |
877 | files->next_fd = fd + 1; | 879 | fdt->next_fd = fd + 1; |
878 | #if 1 | 880 | #if 1 |
879 | /* Sanity check */ | 881 | /* Sanity check */ |
880 | if (files->fd[fd] != NULL) { | 882 | if (fdt->fd[fd] != NULL) { |
881 | printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); | 883 | printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); |
882 | files->fd[fd] = NULL; | 884 | fdt->fd[fd] = NULL; |
883 | } | 885 | } |
884 | #endif | 886 | #endif |
885 | error = fd; | 887 | error = fd; |
@@ -893,9 +895,10 @@ EXPORT_SYMBOL(get_unused_fd); | |||
893 | 895 | ||
894 | static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) | 896 | static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) |
895 | { | 897 | { |
896 | __FD_CLR(fd, files->open_fds); | 898 | struct fdtable *fdt = files_fdtable(files); |
897 | if (fd < files->next_fd) | 899 | __FD_CLR(fd, fdt->open_fds); |
898 | files->next_fd = fd; | 900 | if (fd < fdt->next_fd) |
901 | fdt->next_fd = fd; | ||
899 | } | 902 | } |
900 | 903 | ||
901 | void fastcall put_unused_fd(unsigned int fd) | 904 | void fastcall put_unused_fd(unsigned int fd) |
@@ -924,10 +927,12 @@ EXPORT_SYMBOL(put_unused_fd); | |||
924 | void fastcall fd_install(unsigned int fd, struct file * file) | 927 | void fastcall fd_install(unsigned int fd, struct file * file) |
925 | { | 928 | { |
926 | struct files_struct *files = current->files; | 929 | struct files_struct *files = current->files; |
930 | struct fdtable *fdt; | ||
927 | spin_lock(&files->file_lock); | 931 | spin_lock(&files->file_lock); |
928 | if (unlikely(files->fd[fd] != NULL)) | 932 | fdt = files_fdtable(files); |
933 | if (unlikely(fdt->fd[fd] != NULL)) | ||
929 | BUG(); | 934 | BUG(); |
930 | files->fd[fd] = file; | 935 | fdt->fd[fd] = file; |
931 | spin_unlock(&files->file_lock); | 936 | spin_unlock(&files->file_lock); |
932 | } | 937 | } |
933 | 938 | ||
@@ -1010,15 +1015,17 @@ asmlinkage long sys_close(unsigned int fd) | |||
1010 | { | 1015 | { |
1011 | struct file * filp; | 1016 | struct file * filp; |
1012 | struct files_struct *files = current->files; | 1017 | struct files_struct *files = current->files; |
1018 | struct fdtable *fdt; | ||
1013 | 1019 | ||
1014 | spin_lock(&files->file_lock); | 1020 | spin_lock(&files->file_lock); |
1015 | if (fd >= files->max_fds) | 1021 | fdt = files_fdtable(files); |
1022 | if (fd >= fdt->max_fds) | ||
1016 | goto out_unlock; | 1023 | goto out_unlock; |
1017 | filp = files->fd[fd]; | 1024 | filp = fdt->fd[fd]; |
1018 | if (!filp) | 1025 | if (!filp) |
1019 | goto out_unlock; | 1026 | goto out_unlock; |
1020 | files->fd[fd] = NULL; | 1027 | fdt->fd[fd] = NULL; |
1021 | FD_CLR(fd, files->close_on_exec); | 1028 | FD_CLR(fd, fdt->close_on_exec); |
1022 | __put_unused_fd(files, fd); | 1029 | __put_unused_fd(files, fd); |
1023 | spin_unlock(&files->file_lock); | 1030 | spin_unlock(&files->file_lock); |
1024 | return filp_close(filp, files); | 1031 | return filp_close(filp, files); |